Merge "Handle navigation back problem from About Phone"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 831846e..ce17a70 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1632,8 +1632,9 @@
android:icon="@drawable/ic_suggestion_security">
<intent-filter android:priority="1">
<action android:name="android.intent.action.MAIN" />
- <category android:name="com.android.settings.suggested.category.DEFAULT" />
+ <category android:name="com.android.settings.suggested.category.FIRST_IMPRESSION" />
</intent-filter>
+ <meta-data android:name="com.android.settings.dismiss" android:value="14" />
<meta-data android:name="com.android.settings.title"
android:resource="@string/suggested_lock_settings_title" />
<meta-data android:name="com.android.settings.summary"
@@ -2552,7 +2553,7 @@
<receiver android:name=".sim.SimSelectNotification">
<intent-filter>
- <action android:name="android.intent.action.SIM_STATE_CHANGED"/>
+ <action android:name="android.intent.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED"/>
</intent-filter>
</receiver>
diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
index 3a0e659..c408a97 100644
--- a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
@@ -60,10 +60,10 @@
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
android:textAlignment="center"
- android:layout_marginTop="8dp"
- android:visibility="invisible"
- android:textColor="?android:attr/colorError"/>
+ android:textColor="?android:attr/colorError"
+ android:visibility="invisible"/>
</LinearLayout>
diff --git a/res/layout/manage_applications_apps.xml b/res/layout/manage_applications_apps.xml
index 87db820..9c90f02 100644
--- a/res/layout/manage_applications_apps.xml
+++ b/res/layout/manage_applications_apps.xml
@@ -26,41 +26,34 @@
android:layout_height="match_parent"
settings:layout_behavior="com.android.settings.widget.FloatingAppBarScrollingViewBehavior">
- <LinearLayout
+ <FrameLayout
android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
android:visibility="gone">
- <FrameLayout
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/apps_list"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ settings:fastScrollEnabled="true"
+ settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
+ settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
+ settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
+ settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/apps_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipToPadding="false"
- settings:fastScrollEnabled="true"
- settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
- settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
- settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
- settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:layout_gravity="center"
+ android:text="@string/no_applications"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:visibility="invisible"/>
- <TextView
- android:id="@android:id/empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:layout_gravity="center"
- android:text="@string/no_applications"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:visibility="invisible"/>
-
- </FrameLayout>
-
- </LinearLayout>
+ </FrameLayout>
<include layout="@layout/loading_container"/>
diff --git a/res/layout/preference.xml b/res/layout/preference.xml
index db96139..195671b 100644
--- a/res/layout/preference.xml
+++ b/res/layout/preference.xml
@@ -54,10 +54,6 @@
</RelativeLayout>
- <include
- layout="@layout/preference_two_target_divider"
- android:visibility="gone"/>
-
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
diff --git a/res/layout/wifi_dpp_qrcode_generator_fragment.xml b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
index 2617aea..31bf7cc 100644
--- a/res/layout/wifi_dpp_qrcode_generator_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
@@ -40,6 +40,14 @@
android:layout_height="@dimen/qrcode_size"
android:src="@android:color/transparent"/>
+ <TextView
+ android:id="@+id/password"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:textAlignment="center"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</ScrollView>
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index 4fa8e8b..9bd742a 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -60,10 +60,10 @@
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
android:textAlignment="center"
- android:layout_marginTop="8dp"
- android:visibility="invisible"
- android:textColor="?android:attr/colorError"/>
+ android:textColor="?android:attr/colorError"
+ android:visibility="invisible"/>
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 194b6c5..0986634 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2129,7 +2129,9 @@
<!-- Title for the fragment to share Wi-Fi [CHAR LIMIT=50] -->
<string name="wifi_dpp_share_wifi">Share Wi\u2011Fi</string>
<!-- Hint for the user to use another device to scan QR code on screen to join Wi-Fi [CHAR LIMIT=NONE] -->
- <string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code with another device to join \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+ <string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code to connect to \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d and share the password</string>
+ <!-- Hint for the user to use another device to scan QR code on screen to join a open Wi-Fi [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_scan_open_network_qr_code_with_another_device">Scan this QR code to connect to \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
<!-- Hint for QR code detection [CHAR LIMIT=NONE] -->
<string name="wifi_dpp_could_not_detect_valid_qr_code">Couldn\u2019t read QR code. Re-center code and try again</string>
<!-- Hint for Wi-Fi DPP handshake failure [CHAR LIMIT=NONE] -->
@@ -2166,8 +2168,16 @@
<string name="wifi_dpp_connecting">Connecting\u2026</string>
<!-- Title for the fragment to show that the QR code is for sharing Wi-Fi hotspot network [CHAR LIMIT=50] -->
<string name="wifi_dpp_share_hotspot">Share hotspot</string>
- <!-- Hint for the user to share Wi-Fi hotspot network [CHAR LIMIT=NONE] -->
- <string name="wifi_dpp_scan_qr_code_to_share_hotspot">Scan this QR code with another device to join hotspot \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+ <!-- Title for Wi-Fi DPP lockscreen title [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_lockscreen_title">Verify it\u0027s you</string>
+ <!-- Hint for Wi-Fi password [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_wifi_password">Wi\u2011Fi password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
+ <!-- Hint for Wi-Fi hotspot password [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_hotspot_password">Hotspot password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
+ <!-- Label for "Connect to this network using a QR code" [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_add_device">Add device</string>
+ <!-- Hint for "Add device" [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_connect_network_using_qr_code">Connect to this network using a QR code</string>
<!-- Label for the try again button [CHAR LIMIT=20]-->
<string name="retry">Retry</string>
<!-- Label for the check box to share a network with other users on the same device -->
@@ -3945,8 +3955,6 @@
<string name="lockpassword_choose_your_pattern_header_for_face">To use face authentication, set pattern</string>
<!-- Header on first screen of choose password/PIN as backup for face authentication flow. If this string cannot be translated in under 40 characters, please translate "Set face authentication backup" [CHAR LIMIT=40] -->
<string name="lockpassword_choose_your_pin_header_for_face">To use face authentication, set PIN</string>
- <!-- Message on Wi-Fi Sharing screen [CHAR LIMIT=NONE] -->
- <string name="wifi_sharing_message">Your Wi\u2011Fi name and password for \"<xliff:g id="SSID" example="GoogleGuest">%1$s</xliff:g>\" will be shared.</string>
<!-- Message to be used to explain the user that he needs to enter his pattern to continue a
particular operation. [CHAR LIMIT=70]-->
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index a93fb76..36230d1 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -22,6 +22,8 @@
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
import android.annotation.Nullable;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.IActivityManager;
@@ -92,6 +94,7 @@
import androidx.annotation.StringRes;
import androidx.core.graphics.drawable.IconCompat;
import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Lifecycle;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
@@ -101,6 +104,7 @@
import com.android.settings.core.FeatureFlags;
import com.android.settings.development.featureflags.FeatureFlagPersistent;
import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settingslib.widget.ActionBarShadowController;
import java.net.InetAddress;
import java.util.Iterator;
@@ -1023,4 +1027,28 @@
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return !(am.isLowRamDevice() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q));
}
+
+ /**
+ * Adds a shadow appear/disappear animation to action bar scroll.
+ *
+ * <p/>
+ * This method must be called after {@link Fragment#onCreate(Bundle)}.
+ */
+ public static void setActionBarShadowAnimation(Activity activity, Lifecycle lifecycle,
+ View scrollView) {
+ if (activity == null) {
+ Log.w(TAG, "No activity, cannot style actionbar.");
+ return;
+ }
+ final ActionBar actionBar = activity.getActionBar();
+ if (actionBar == null) {
+ Log.w(TAG, "No actionbar, cannot style actionbar.");
+ return;
+ }
+ actionBar.setElevation(0);
+
+ if (lifecycle != null && scrollView != null) {
+ ActionBarShadowController.attachToView(activity, lifecycle, scrollView);
+ }
+ }
}
diff --git a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
index 7aaf80d..c32a33d 100644
--- a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
+++ b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
@@ -21,6 +21,7 @@
import android.provider.SearchIndexableResource;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.EmergencyBroadcastPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -85,6 +86,10 @@
super.onResume();
mIsFirstLaunch = false;
+
+ if (mRecentAppsPreferenceController.isAvailable()) {
+ Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
+ }
}
@Override
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index be6701e..fa21f9d 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -16,25 +16,22 @@
package com.android.settings.privacy;
-import android.app.ActionBar;
-import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
-import android.util.Log;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.widget.ActionBarShadowController;
import java.util.ArrayList;
import java.util.List;
@@ -87,29 +84,11 @@
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- styleActionBar();
+ Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
initLoadingBar();
}
@VisibleForTesting
- void styleActionBar() {
- final Activity activity = getActivity();
- final ActionBar actionBar = activity.getActionBar();
- final Lifecycle lifecycle = getSettingsLifecycle();
- final View scrollView = getListView();
-
- if (actionBar == null) {
- Log.w(TAG, "No actionbar, cannot style actionbar.");
- return;
- }
-
- actionBar.setElevation(0);
- if (lifecycle != null && scrollView != null) {
- ActionBarShadowController.attachToView(activity, lifecycle, scrollView);
- }
- }
-
- @VisibleForTesting
void initLoadingBar() {
mProgressHeader = setPinnedHeaderView(R.layout.progress_header);
mProgressAnimation = mProgressHeader.findViewById(R.id.progress_bar_animation);
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index cf67f5e..891d171 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -16,6 +16,12 @@
package com.android.settings.sim;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_ID;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
+
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -23,19 +29,12 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import androidx.core.app.NotificationCompat;
-
-import com.android.internal.telephony.IccCardConstants;
import com.android.settings.R;
import com.android.settings.Settings.SimSettingsActivity;
-import com.android.settings.Utils;
-import java.util.List;
+import androidx.core.app.NotificationCompat;
public class SimSelectNotification extends BroadcastReceiver {
private static final String TAG = "SimSelectNotification";
@@ -46,71 +45,24 @@
@Override
public void onReceive(Context context, Intent intent) {
- final TelephonyManager telephonyManager = (TelephonyManager)
- context.getSystemService(Context.TELEPHONY_SERVICE);
- final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
- final int numSlots = telephonyManager.getSimCount();
-
- // Do not create notifications on single SIM devices or when provisioning i.e. Setup Wizard.
- if (numSlots < 2 || !Utils.isDeviceProvisioned(context)) {
- return;
- }
-
// Cancel any previous notifications
cancelNotification(context);
-
- // If sim state is not ABSENT or LOADED then ignore
- String simStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
- if (!(IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(simStatus) ||
- IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(simStatus))) {
- Log.d(TAG, "sim state is not Absent or Loaded");
- return;
- } else {
- Log.d(TAG, "simstatus = " + simStatus);
- }
-
- int state;
- for (int i = 0; i < numSlots; i++) {
- state = telephonyManager.getSimState(i);
- if (!(state == TelephonyManager.SIM_STATE_ABSENT
- || state == TelephonyManager.SIM_STATE_READY
- || state == TelephonyManager.SIM_STATE_UNKNOWN)) {
- Log.d(TAG, "All sims not in valid state yet");
- return;
- }
- }
-
- List<SubscriptionInfo> sil = subscriptionManager.getActiveSubscriptionInfoList(true);
- if (sil == null || sil.size() < 1) {
- Log.d(TAG, "Subscription list is empty");
- return;
- }
-
- // Clear defaults for any subscriptions which no longer exist
- subscriptionManager.clearDefaultsForInactiveSubIds();
-
- boolean dataSelected = SubscriptionManager.isUsableSubIdValue(
- SubscriptionManager.getDefaultDataSubscriptionId());
- boolean smsSelected = SubscriptionManager.isUsableSubIdValue(
- SubscriptionManager.getDefaultSmsSubscriptionId());
-
- // If data and sms defaults are selected, dont show notification (Calls default is optional)
- if (dataSelected && smsSelected) {
- Log.d(TAG, "Data & SMS default sims are selected. No notification");
- return;
- }
-
// Create a notification to tell the user that some defaults are missing
createNotification(context);
- if (sil.size() == 1) {
+ int dialogType = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
+ EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE);
+ if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES) {
+ int subId = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_ID,
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ int slotIndex = SubscriptionManager.getSlotIndex(subId);
// If there is only one subscription, ask if user wants to use if for everything
Intent newIntent = new Intent(context, SimDialogActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.PREFERRED_PICK);
- newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, sil.get(0).getSimSlotIndex());
+ newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, slotIndex);
context.startActivity(newIntent);
- } else if (!dataSelected) {
+ } else if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA) {
// If there are mulitple, ensure they pick default data
Intent newIntent = new Intent(context, SimDialogActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/settings/wifi/AddWifiNetworkPreference.java b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
index e49f2ab..cd2e4a8 100644
--- a/src/com/android/settings/wifi/AddWifiNetworkPreference.java
+++ b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
@@ -20,6 +20,7 @@
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.Log;
+import android.view.View;
import android.widget.ImageButton;
import androidx.annotation.DrawableRes;
@@ -62,6 +63,10 @@
getContext().startActivity(
WifiDppUtils.getEnrolleeQrCodeScannerIntent(/* ssid */ null));
});
+
+ final View divider = (View) holder.findViewById(
+ com.android.settingslib.R.id.two_target_divider);
+ divider.setVisibility(View.INVISIBLE);
}
}
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index f328dba..cf59dbd 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -771,14 +771,7 @@
* Share the wifi network with QR code.
*/
private void shareNetwork() {
- final String title = mContext.getString(
- R.string.lockpassword_confirm_your_pattern_header);
- final String description = String.format(
- mContext.getString(R.string.wifi_sharing_message),
- mAccessPoint.getSsidStr());
-
- WifiDppUtils.showLockScreen(mContext, title, description,
- () -> launchWifiDppConfiguratorActivity());
+ WifiDppUtils.showLockScreen(mContext, () -> launchWifiDppConfiguratorActivity());
}
/**
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 2cd5e23..4e6a0d6 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -29,6 +30,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
+import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.wifi.qrcode.QrCodeGenerator;
@@ -43,6 +45,7 @@
private static final String TAG = "WifiDppQrCodeGeneratorFragment";
private ImageView mQrCodeView;
+ private TextView mPasswordView;
private String mQrCode;
@Override
@@ -138,12 +141,27 @@
final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity();
if (wifiNetworkConfig.isHotspot()) {
mTitle.setText(R.string.wifi_dpp_share_hotspot);
- mSummary.setText(getString(R.string.wifi_dpp_scan_qr_code_to_share_hotspot,
- wifiNetworkConfig.getSsid()));
} else {
mTitle.setText(R.string.wifi_dpp_share_wifi);
+ }
+
+ final String password = wifiNetworkConfig.getPreSharedKey();
+ mPasswordView = view.findViewById(R.id.password);
+ if (TextUtils.isEmpty(password)) {
+ mSummary.setText(getString(
+ R.string.wifi_dpp_scan_open_network_qr_code_with_another_device,
+ wifiNetworkConfig.getSsid()));
+
+ mPasswordView.setVisibility(View.GONE);
+ } else {
mSummary.setText(getString(R.string.wifi_dpp_scan_qr_code_with_another_device,
wifiNetworkConfig.getSsid()));
+
+ if (wifiNetworkConfig.isHotspot()) {
+ mPasswordView.setText(getString(R.string.wifi_dpp_hotspot_password, password));
+ } else {
+ mPasswordView.setText(getString(R.string.wifi_dpp_wifi_password, password));
+ }
}
mQrCode = wifiNetworkConfig.getQrCode();
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 4535599..905d3a0 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -45,6 +45,7 @@
import android.widget.ProgressBar;
import android.widget.TextView;
+import androidx.annotation.StringRes;
import androidx.lifecycle.ViewModelProviders;
import com.android.settings.R;
@@ -52,12 +53,17 @@
import com.android.settings.wifi.qrcode.QrCamera;
import com.android.settings.wifi.qrcode.QrDecorateView;
+import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.WifiTracker;
+import com.android.settingslib.wifi.WifiTrackerFactory;
+
import java.util.List;
public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
SurfaceTextureListener,
QrCamera.ScannerCallback,
- WifiManager.ActionListener {
+ WifiManager.ActionListener,
+ WifiTracker.WifiListener {
private static final String TAG = "WifiDppQrCodeScannerFragment";
/** Message sent to hide error message */
@@ -80,6 +86,8 @@
private static final String KEY_LATEST_ERROR_CODE = "key_latest_error_code";
private static final String KEY_WIFI_CONFIGURATION = "key_wifi_configuration";
+ private static final int ARG_RESTART_CAMERA = 1;
+
private ProgressBar mProgressBar;
private QrCamera mCamera;
private TextureView mTextureView;
@@ -100,6 +108,68 @@
private int mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_FAILURE_NONE;
+ private WifiTracker mWifiTracker;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_HIDE_ERROR_MESSAGE:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+ break;
+
+ case MESSAGE_SHOW_ERROR_MESSAGE:
+ final String errorMessage = (String) msg.obj;
+
+ mErrorMessage.setVisibility(View.VISIBLE);
+ mErrorMessage.setText(errorMessage);
+ mErrorMessage.sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
+ // Cancel any pending messages to hide error view and requeue the message so
+ // user has time to see error
+ removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+ sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
+ SHOW_ERROR_MESSAGE_INTERVAL);
+
+ if (msg.arg1 == ARG_RESTART_CAMERA) {
+ mProgressBar.setVisibility(View.INVISIBLE);
+ restartCamera();
+ }
+ break;
+
+ case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+
+ if (mScanWifiDppSuccessListener == null) {
+ return;
+ }
+ mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj);
+
+ if (!mIsConfiguratorMode) {
+ mProgressBar.setVisibility(View.VISIBLE);
+ startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj);
+ updateEnrolleeSummary();
+ mSummary.sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ }
+ break;
+
+ case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+
+ final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
+ mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
+ wifiNetworkConfig.connect(getContext(),
+ /* listener */ WifiDppQrCodeScannerFragment.this);
+ break;
+
+ default:
+ return;
+ }
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -175,6 +245,9 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
+ mWifiTracker = WifiTrackerFactory.create(getActivity(), /* wifiListener */ this,
+ getSettingsLifecycle(), /* includeSaved */ false, /* includeScans */ true);
+
// setTitle for Talkback
if (mIsConfiguratorMode) {
getActivity().setTitle(R.string.wifi_dpp_add_device_to_network);
@@ -291,7 +364,7 @@
try {
mWifiQrCode = new WifiQrCode(qrCode);
} catch (IllegalArgumentException e) {
- mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false;
}
@@ -301,14 +374,14 @@
if (!mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
final String ssidQrCode = mWifiQrCode.getWifiNetworkConfig().getSsid();
if (!TextUtils.isEmpty(mSsid) && !mSsid.equals(ssidQrCode)) {
- mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false;
}
}
// It's impossible to provision other device with ZXing Wi-Fi Network config format
if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
- mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false;
}
@@ -385,59 +458,18 @@
}
}
- public void showErrorMessage(String message) {
- mErrorMessage.setVisibility(View.VISIBLE);
- mErrorMessage.setText(message);
- mErrorMessage.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-
- mHandler.removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
- mHandler.sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
- SHOW_ERROR_MESSAGE_INTERVAL);
+ private void showErrorMessage(@StringRes int messageResId) {
+ final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+ getString(messageResId));
+ message.sendToTarget();
}
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_HIDE_ERROR_MESSAGE:
- mErrorMessage.setVisibility(View.INVISIBLE);
- break;
-
- case MESSAGE_SHOW_ERROR_MESSAGE:
- showErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
- break;
-
- case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
- mErrorMessage.setVisibility(View.INVISIBLE);
-
- if (mScanWifiDppSuccessListener == null) {
- return;
- }
- mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj);
-
- if (!mIsConfiguratorMode) {
- mProgressBar.setVisibility(View.VISIBLE);
- startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj);
- updateEnrolleeSummary();
- mSummary.sendAccessibilityEvent(
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- }
- break;
-
- case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
- mErrorMessage.setVisibility(View.INVISIBLE);
-
- final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
- mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
- wifiNetworkConfig.connect(getContext(),
- /* listener */ WifiDppQrCodeScannerFragment.this);
- break;
-
- default:
- return;
- }
- }
- };
+ private void showErrorMessageAndRestartCamera(@StringRes int messageResId) {
+ final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+ getString(messageResId));
+ message.arg1 = ARG_RESTART_CAMERA;
+ message.sendToTarget();
+ }
@Override
public void onSaveInstanceState(Bundle outState) {
@@ -468,9 +500,7 @@
Log.e(TAG, "Invalid networkId " + newNetworkId);
mLatestStatusCode = EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC;
updateEnrolleeSummary();
- mProgressBar.setVisibility(View.INVISIBLE);
- showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
- restartCamera();
+ showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
}
@Override
@@ -482,23 +512,22 @@
public void onFailure(int code) {
Log.d(TAG, "EasyConnectEnrolleeStatusCallback.onFailure " + code);
+ int errorMessageResId = 0;
switch (code) {
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_URI:
- showErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
+ errorMessageResId = R.string.wifi_dpp_could_not_detect_valid_qr_code;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION:
- showErrorMessage(
- getString(R.string.wifi_dpp_failure_authentication_or_configuration));
+ errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE:
- showErrorMessage(getString(R.string.wifi_dpp_failure_not_compatible));
+ errorMessageResId = R.string.wifi_dpp_failure_not_compatible;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION:
- showErrorMessage(
- getString(R.string.wifi_dpp_failure_authentication_or_configuration));
+ errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY:
@@ -515,11 +544,11 @@
return;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT:
- showErrorMessage(getString(R.string.wifi_dpp_failure_timeout));
+ errorMessageResId = R.string.wifi_dpp_failure_timeout;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC:
- showErrorMessage(getString(R.string.wifi_dpp_failure_generic));
+ errorMessageResId = R.string.wifi_dpp_failure_generic;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED:
@@ -536,8 +565,7 @@
mLatestStatusCode = code;
updateEnrolleeSummary();
- mProgressBar.setVisibility(View.INVISIBLE);
- restartCamera();
+ showErrorMessageAndRestartCamera(errorMessageResId);
}
@Override
@@ -555,21 +583,39 @@
@Override
public void onSuccess() {
- final Intent resultIntent = new Intent();
- resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
+ if (isEnrollingWifiNetworkReachable()) {
+ final Intent resultIntent = new Intent();
+ resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
- final Activity hostActivity = getActivity();
- hostActivity.setResult(Activity.RESULT_OK, resultIntent);
- hostActivity.finish();
+ final Activity hostActivity = getActivity();
+ hostActivity.setResult(Activity.RESULT_OK, resultIntent);
+ hostActivity.finish();
+ } else {
+ Log.d(TAG, "Enroll Wi-Fi network succeeded but it's not reachable");
+ showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
+ }
}
@Override
public void onFailure(int reason) {
Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason);
+ showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
+ }
- mProgressBar.setVisibility(View.INVISIBLE);
- showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
- restartCamera();
+ private boolean isEnrollingWifiNetworkReachable() {
+ if (mWifiConfiguration == null) {
+ Log.e(TAG, "Connect succeeded but lost WifiConfiguration");
+ return false;
+ }
+
+ final List<AccessPoint> scannedAccessPoints = mWifiTracker.getAccessPoints();
+ for (AccessPoint accessPoint : scannedAccessPoints) {
+ if (accessPoint.matches(mWifiConfiguration) &&
+ accessPoint.isReachable()) {
+ return true;
+ }
+ }
+ return false;
}
// Check is Easy Connect handshaking or not
@@ -610,4 +656,25 @@
mSummary.setText(description);
}
}
+
+ /** Called when the state of Wifi has changed. */
+ @Override
+ public void onWifiStateChanged(int state) {
+ // Do nothing.
+ }
+
+ /** Called when the connection state of wifi has changed. */
+ @Override
+ public void onConnectedChanged() {
+ // Do nothing.
+ }
+
+ /**
+ * Called to indicate the list of AccessPoints has been updated and
+ * getAccessPoints should be called to get the latest information.
+ */
+ @Override
+ public void onAccessPointsChanged() {
+ // Do nothing.
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index fe7af27..bf78b3f 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -29,6 +29,8 @@
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
+import com.android.settings.R;
+
import com.android.settingslib.wifi.AccessPoint;
import java.util.List;
@@ -273,13 +275,10 @@
* user of the device.
*
* @param context The {@code Context} used to get {@code KeyguardManager} service
- * @param title The title on lock screen
- * @param description The description on lock screen
* @param successRunnable The {@code Runnable} which will be executed if the user does not setup
* device security or if lock screen is unlocked
*/
- public static void showLockScreen(Context context, String title, String description,
- Runnable successRunnable) {
+ public static void showLockScreen(Context context, Runnable successRunnable) {
final KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(
Context.KEYGUARD_SERVICE);
@@ -299,8 +298,7 @@
};
final BiometricPrompt.Builder builder = new BiometricPrompt.Builder(context)
- .setTitle(title)
- .setDescription(description);
+ .setTitle(context.getText(R.string.wifi_dpp_lockscreen_title));
if (keyguardManager.isDeviceSecure()) {
builder.setDeviceCredentialAllowed(true);
diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java
index 0c95a23..f2c919b 100644
--- a/src/com/android/settings/wifi/slice/WifiSlice.java
+++ b/src/com/android/settings/wifi/slice/WifiSlice.java
@@ -65,7 +65,10 @@
import com.android.settingslib.wifi.WifiTracker;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* {@link CustomSliceable} for Wi-Fi, used by generic clients.
@@ -150,6 +153,7 @@
return new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
.setAccentColor(COLOR_NOT_TINTED)
+ .setKeywords(getKeywords())
.addRow(new ListBuilder.RowBuilder()
.setTitle(title)
.setSubtitle(summary)
@@ -346,6 +350,14 @@
intent, 0 /* flags */);
}
+ private Set<String> getKeywords() {
+ final String keywords = mContext.getString(R.string.keywords_wifi);
+ return Arrays.asList(TextUtils.split(keywords, ","))
+ .stream()
+ .map(String::trim)
+ .collect(Collectors.toSet());
+ }
+
@Override
public Class getBackgroundWorkerClass() {
return WifiScanWorker.class;
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
index 10f3e56..b7ddcae 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
@@ -104,13 +104,7 @@
}
private void shareHotspotNetwork(Intent intent) {
- final String title = mContext.getString(
- R.string.lockpassword_confirm_your_pattern_header);
- final String description = String.format(
- mContext.getString(R.string.wifi_sharing_message), mSSID);
-
- WifiDppUtils.showLockScreen(mContext, title, description,
- () -> mContext.startActivity(intent));
+ WifiDppUtils.showLockScreen(mContext, () -> mContext.startActivity(intent));
}
@VisibleForTesting
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java b/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java
index e2566d0..64014d9 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java
@@ -39,7 +39,6 @@
private ImageButton mImageButton;
private Drawable mButtonIcon;
- private View mDivider;
private View.OnClickListener mClickListener;
private boolean mVisible;
@@ -69,8 +68,6 @@
}
private void initialize() {
- // TODO(b/129019971): use methods of divider line in parent object
- setLayoutResource(R.layout.preference);
setWidgetLayoutResource(R.layout.wifi_button_preference_widget);
}
@@ -85,17 +82,13 @@
getContext().getString(R.string.wifi_dpp_share_hotspot));
setButtonIcon(R.drawable.ic_qrcode_24dp);
mImageButton.setImageDrawable(mButtonIcon);
-
- mDivider = holder.findViewById(R.id.two_target_divider);
}
if (mVisible) {
mImageButton.setOnClickListener(mClickListener);
mImageButton.setVisibility(View.VISIBLE);
- mDivider.setVisibility(View.VISIBLE);
} else {
mImageButton.setVisibility(View.GONE);
- mDivider.setVisibility(View.GONE);
}
}
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index 37186ca..3d3aff4 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -28,6 +28,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
@@ -51,15 +53,18 @@
import android.os.storage.VolumeInfo;
import android.util.IconDrawableFactory;
import android.widget.EditText;
+import android.widget.ScrollView;
import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat;
+import androidx.fragment.app.FragmentActivity;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -259,4 +264,21 @@
public void isPackageEnabled_noApp_returnFalse() {
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
+
+ @Test
+ public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() {
+ // no crash here
+ Utils.setActionBarShadowAnimation(null, null, null);
+ }
+
+ @Test
+ public void setActionBarShadowAnimation_shouldSetElevationToZero() {
+ final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
+ final ActionBar actionBar = activity.getActionBar();
+
+ Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
+ new ScrollView(mContext));
+
+ assertThat(actionBar.getElevation()).isEqualTo(0.f);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
index 482eaeb..80f3900 100644
--- a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
@@ -80,10 +80,10 @@
}
@Test
- public void onViewCreated_shouldCallStyleActionBar() {
+ public void onViewCreated_shouldSetActionBarShadowAnimation() {
mFragment.onViewCreated(new View(mContext), new Bundle());
- verify(mFragment).styleActionBar();
+ assertThat(mFragment.getActivity().getActionBar().getElevation()).isEqualTo(0.f);
}
@Test