diff --git a/res/drawable/ic_qrcode_24dp.xml b/res/drawable/ic_qrcode_24dp.xml
new file mode 100644
index 00000000000..ff7806f8107
--- /dev/null
+++ b/res/drawable/ic_qrcode_24dp.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_scan_24dp.xml b/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 00000000000..bcef8e32db0
--- /dev/null
+++ b/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cbb5e3be3ad..0116ed40663 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -653,6 +653,8 @@
Done
Apply
+
+ Share
Settings
@@ -3765,6 +3767,8 @@
To use face authentication, set pattern
To use face authentication, set PIN
+
+ Your Wi\u2011Fi name and password for \"%1$s\" will be shared.
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index daa1e7b1b08..b35077894f2 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -26,4 +26,5 @@ public class FeatureFlags {
public static final String MOBILE_NETWORK_V2 = "settings_mobile_network_v2";
public static final String WIFI_MAC_RANDOMIZATION = "settings_wifi_mac_randomization";
public static final String NETWORK_INTERNET_V2 = "settings_network_and_internet_v2";
+ public static final String WIFI_SHARING = "settings_wifi_sharing";
}
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index a676bfa6a9e..e1179f820fa 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import android.app.Activity;
+import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -40,6 +41,7 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;
@@ -54,8 +56,11 @@ import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.Utils;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.EntityHeaderController;
+import com.android.settings.wifi.dpp.WifiDppConfiguratorActivity;
+import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settings.wifi.WifiDialog;
import com.android.settings.wifi.WifiDialog.WifiDialogListener;
import com.android.settings.wifi.WifiUtils;
@@ -280,7 +285,10 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
.setButton1Icon(R.drawable.ic_settings_delete)
.setButton1OnClickListener(view -> forgetNetwork())
.setButton2Text(R.string.wifi_sign_in_button_text)
- .setButton2OnClickListener(view -> signIntoNetwork());
+ .setButton2OnClickListener(view -> signIntoNetwork())
+ .setButton3Text(R.string.share)
+ .setButton3Icon(R.drawable.ic_qrcode_24dp)
+ .setButton3OnClickListener(view -> shareNetwork());
mSignalStrengthPref = screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
mLinkSpeedPref = screen.findPreference(KEY_LINK_SPEED);
@@ -296,7 +304,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
mIpv6Category = (PreferenceCategory) screen.findPreference(KEY_IPV6_CATEGORY);
mIpv6AddressPref = screen.findPreference(KEY_IPV6_ADDRESSES_PREF);
- mSecurityPref.setSummary(mAccessPoint.getSecurityString(false /* concise */));
+ mSecurityPref.setSummary(mAccessPoint.getSecurityString(/* concise */ false));
}
private void setupEntityHeader(PreferenceScreen screen) {
@@ -425,7 +433,9 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
private void updateIpLayerInfo() {
mButtonsPref.setButton2Visible(canSignIntoNetwork());
- mButtonsPref.setVisible(canSignIntoNetwork() || canForgetNetwork());
+ mButtonsPref.setButton3Visible(isSharingNetworkEnabled());
+ mButtonsPref.setVisible(
+ canSignIntoNetwork() || canForgetNetwork() || isSharingNetworkEnabled());
if (mNetwork == null || mLinkProperties == null) {
mIpAddressPref.setVisible(false);
@@ -510,6 +520,13 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
return WifiUtils.canSignIntoNetwork(mNetworkCapabilities);
}
+ /**
+ * Returns whether the user can share the network represented by this preference with QR code.
+ */
+ private boolean isSharingNetworkEnabled() {
+ return FeatureFlagUtils.isEnabled(mContext, FeatureFlags.WIFI_SHARING);
+ }
+
/**
* Forgets the wifi network associated with this preference.
*/
@@ -528,6 +545,42 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
mFragment.getActivity().finish();
}
+ /**
+ * Show QR code to share the network represented by this preference.
+ */
+ public void launchQRCodeGenerator() {
+ final Intent intent = new Intent(
+ WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY,
+ mAccessPoint.getSecurityString(/* concise */ false));
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, mAccessPoint.getSsidStr());
+ mContext.startActivity(intent);
+ }
+
+ /**
+ * Share the wifi network with QR code.
+ */
+ private void shareNetwork() {
+ final KeyguardManager keyguardManager = (KeyguardManager) mContext.getSystemService(
+ Context.KEYGUARD_SERVICE);
+ if (keyguardManager.isKeyguardSecure()) {
+ // Show authentication screen to confirm credentials (pin, pattern or password) for
+ // the current user of the device.
+ final String description = String.format(
+ mContext.getString(R.string.wifi_sharing_message),
+ mAccessPoint.getSsidStr());
+ final Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(
+ mContext.getString(R.string.lockpassword_confirm_your_pattern_header),
+ description);
+ if (intent != null) {
+ mFragment.startActivityForResult(intent,
+ WifiNetworkDetailsFragment.REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
+ }
+ } else {
+ launchQRCodeGenerator();
+ }
+ }
+
/**
* Sign in to the captive portal found on this wifi network associated with this preference.
*/
diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
index 7f0e8ee5677..98144864620 100644
--- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
+++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
@@ -17,8 +17,10 @@ package com.android.settings.wifi.details;
import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID;
+import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
+import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
@@ -52,6 +54,8 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
private static final String TAG = "WifiNetworkDetailsFrg";
+ public static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 1;
+
private AccessPoint mAccessPoint;
private WifiDetailPreferenceController mWifiDetailPreferenceController;
@@ -142,4 +146,14 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
return controllers;
}
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS
+ && resultCode == Activity.RESULT_OK) {
+ mWifiDetailPreferenceController.launchQRCodeGenerator();
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 39215c16d3b..eab9e51a094 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -865,6 +865,12 @@ public class WifiDetailPreferenceControllerTest {
when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
+ when(pref.setButton3Text(anyInt())).thenReturn(pref);
+ when(pref.setButton3Icon(anyInt())).thenReturn(pref);
+ when(pref.setButton3Enabled(anyBoolean())).thenReturn(pref);
+ when(pref.setButton3Visible(anyBoolean())).thenReturn(pref);
+ when(pref.setButton3OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
+
return pref;
}
}