Merge "Migrate all default app shortcut preference to use roles."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a5586f7..e42715f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -788,7 +788,7 @@
<activity android:name=".wallpaper.WallpaperSuggestionActivity"
android:label="@string/wallpaper_settings_title"
- android:icon="@drawable/ic_suggestion_wallpaper"
+ android:icon="@drawable/ic_wallpaper"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/res/drawable/ic_suggestion_wallpaper.xml b/res/drawable/ic_suggestion_wallpaper.xml
deleted file mode 100644
index 32defce..0000000
--- a/res/drawable/ic_suggestion_wallpaper.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?android:attr/colorControlNormal">
- <path
- android:fillColor="#FF000000"
- android:pathData="M9,12.71l2.14,2.58l3,-3.87L18,16.57H6L9,12.71zM5,5h6V3H5C3.9,3 3,3.9 3,5v6h2V5zM19,19h-6v2h6c1.1,0 2,-0.9 2,-2v-6h-2V19zM5,19v-6H3v6c0,1.1 0.9,2 2,2h6v-2H5zM19,5v6h2V5c0,-1.1 -0.9,-2 -2,-2h-6v2H19zM16,9c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1c-0.55,0 -1,0.45 -1,1S15.45,9 16,9z"/>
-</vector>
diff --git a/res/layout-land/panel_layout.xml b/res/layout-land/panel_layout.xml
deleted file mode 100644
index 049fd0b..0000000
--- a/res/layout-land/panel_layout.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/panel_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:paddingBottom="24dp"
- android:paddingTop="18dp"
- android:textColor="?android:attr/colorPrimary"
- android:textSize="20sp"/>
-
- <include layout="@layout/horizontal_divider"/>
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/panel_parent_layout"
- android:scrollbars="vertical"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"/>
-
- <include layout="@layout/panel_buttons"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-land/panel_slice_list.xml b/res/layout-land/panel_slice_list.xml
new file mode 100644
index 0000000..ea7d828
--- /dev/null
+++ b/res/layout-land/panel_slice_list.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<androidx.recyclerview.widget.RecyclerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/panel_parent_layout"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
\ No newline at end of file
diff --git a/res/layout/manage_applications_apps_unsupported.xml b/res/layout/manage_applications_apps_unsupported.xml
new file mode 100644
index 0000000..d7c6726
--- /dev/null
+++ b/res/layout/manage_applications_apps_unsupported.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/empty_header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/disabled_feature"
+ android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+ <TextView
+ android:id="@+id/empty_body"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/disabled_feature_reason_slow_down_phone"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <FrameLayout
+ android:id="@+id/pinned_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ settings:layout_scrollFlags="scroll|enterAlways"/>
+ </com.google.android.material.appbar.AppBarLayout>
+
+ </LinearLayout>
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/layout/panel_buttons.xml b/res/layout/panel_buttons.xml
deleted file mode 100644
index 1bb3898..0000000
--- a/res/layout/panel_buttons.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="14dp"
- android:paddingBottom="14dp"
- android:orientation="horizontal">
-
- <Button
- android:id="@+id/see_more"
- style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="20dp"
- android:text="@string/see_more"/>
-
- <Space
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="match_parent" />
-
- <Button
- android:id="@+id/done"
- style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="20dp"
- android:text="@string/done"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index c466ce8..233a01b 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -33,11 +33,34 @@
<include layout="@layout/horizontal_divider"/>
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/panel_parent_layout"
- android:scrollbars="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
+ <include layout="@layout/panel_slice_list"/>
- <include layout="@layout/panel_buttons"/>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp">
+
+ <Button
+ android:id="@+id/see_more"
+ style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_marginStart="12dp"
+ android:text="@string/see_more"/>
+
+ <Space
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+
+ <Button
+ android:id="@+id/done"
+ style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_marginEnd="12dp"
+ android:text="@string/done"/>
+ </LinearLayout>
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/panel_slice_list.xml b/res/layout/panel_slice_list.xml
new file mode 100644
index 0000000..842441c
--- /dev/null
+++ b/res/layout/panel_slice_list.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<androidx.recyclerview.widget.RecyclerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/panel_parent_layout"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:overScrollMode="never"/>
\ No newline at end of file
diff --git a/res/layout/panel_slice_row.xml b/res/layout/panel_slice_row.xml
index 4ce3494..3288c40 100644
--- a/res/layout/panel_slice_row.xml
+++ b/res/layout/panel_slice_row.xml
@@ -25,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="20dp"
- android:paddingEnd="20dp" />
+ android:paddingEnd="20dp"/>
<include layout="@layout/horizontal_divider"/>
</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 90b72e1..cb0f027 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10183,6 +10183,10 @@
<!-- Note displayed when certain features are not available on low ram devices. [CHAR LIMIT=NONE] -->
<string name="disabled_low_ram_device">This feature is not available on this device</string>
+ <!-- Note displayed when certain features are not available. [CHAR LIMIT=NONE] -->
+ <string name="disabled_feature">This feature is not available</string>
+ <!-- Note displayed to explain that a feature is not available because it will slow down the phone. [CHAR LIMIT=NONE] -->
+ <string name="disabled_feature_reason_slow_down_phone">It will slow down this phone</string>
<!-- UI debug setting: preference title - enforce full raw GNSS satellite measurements [CHAR LIMIT=60] -->
<string name="enable_gnss_raw_meas_full_tracking">Force full GNSS measurements</string>
@@ -10706,4 +10710,7 @@
<string name="media_output_panel_title">Switch output</string>
<!-- Summary for represent which device is playing media [CHAR LIMIT=NONE] -->
<string name="media_output_panel_summary_of_playing_device">Currently playing on <xliff:g id="device_name" example="Bose headphone">%1$s</xliff:g></string>
+
+ <!-- Message for forget passpoint dialog [CHAR LIMIT=none] -->
+ <string name="forget_passpoint_dialog_message">Your subscription with this provider may be cancelled. Recurring subscriptions will not be cancelled. For more information, check with your provider.</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a907c62..a778f76 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -238,7 +238,10 @@
<style name="TextAppearance.CategoryTitle"
parent="@*android:style/TextAppearance.DeviceDefault.Body2">
- <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:textAllCaps">true</item>
+ <item name="android:textSize">11sp</item>
+ <!-- 0.8 Spacing, 0.8/11 = 0.072727273 -->
+ <item name="android:letterSpacing">0.072727273</item>
</style>
<style name="TextAppearance.TileTitle" parent="@*android:style/TextAppearance.DeviceDefault.Subhead"/>
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index e7e0c97..5cd7a6c 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -25,6 +25,8 @@
<item name="slicePreferenceStyle">@style/SlicePreference</item>
<item name="seekBarPreferenceStyle">@style/SettingsSeekBarPreference</item>
<item name="twoStateButtonPreferenceStyle">@style/TwoStateButtonPreference</item>
+ <item name="preferenceCategoryTitleTextAppearance">@style/TextAppearance.CategoryTitle
+ </item>
</style>
<style name="PreferenceTheme.SetupWizard">
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 9cb73a2..da103c5 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -58,6 +58,14 @@
android:title="@string/screen_zoom_title"
settings:searchable="false"/>
+ <ListPreference
+ android:key="dark_ui_mode_accessibility"
+ android:title="@string/dark_ui_mode"
+ android:dialogTitle="@string/dark_ui_mode_title"
+ android:entries="@array/dark_ui_mode_entries"
+ android:entryValues="@array/dark_ui_mode_values"
+ settings:searchable="false" />
+
<Preference
android:fragment="com.android.settings.accessibility.MagnificationPreferenceFragment"
android:key="magnification_preference_screen"
diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml
index 518379a..9dd5fea 100644
--- a/res/xml/app_and_notification.xml
+++ b/res/xml/app_and_notification.xml
@@ -27,7 +27,8 @@
android:key="all_app_info"
android:title="@string/applications_settings"
android:order="-999"
- android:fragment="com.android.settings.applications.manageapplications.ManageApplications"/>
+ android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
+ settings:controller="com.android.settings.applications.AllAppsInfoPreferenceController"/>
<com.android.settingslib.widget.LayoutPreference
android:key="recent_open_apps"
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index 4417d0f..05f4a81 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -42,7 +42,8 @@
android:key="system_alert_window"
android:title="@string/system_alert_window_settings"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
- settings:keywords="@string/keywords_system_alert_window">
+ settings:keywords="@string/keywords_system_alert_window"
+ settings:controller="com.android.settings.applications.specialaccess.SystemAlertWindowPreferenceController">
<extra
android:name="classname"
android:value="com.android.settings.Settings$OverlaySettingsActivity" />
diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java
index 2484948..49d027b 100644
--- a/src/com/android/settings/CryptKeeperConfirm.java
+++ b/src/com/android/settings/CryptKeeperConfirm.java
@@ -38,6 +38,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.InstrumentedFragment;
+import java.util.Arrays;
import java.util.Locale;
public class CryptKeeperConfirm extends InstrumentedFragment {
@@ -87,7 +88,12 @@
IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
try {
Bundle args = getIntent().getExtras();
- storageManager.encryptStorage(args.getInt("type", -1), args.getString("password"));
+ // TODO(b/120484642): Update vold to accept a password as a byte array
+ byte[] passwordBytes = args.getByteArray("password");
+ String password = passwordBytes != null ? new String(passwordBytes) : null;
+ Arrays.fill(passwordBytes, (byte) 0);
+ storageManager.encryptStorage(args.getInt("type", -1),
+ password);
} catch (Exception e) {
Log.e("CryptKeeper", "Error while encrypting...", e);
}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 804c783..69b8c56 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -55,6 +55,7 @@
import android.net.Network;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
+import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.INetworkManagementService;
@@ -1007,4 +1008,14 @@
return context.getResources();
}
}
+
+ /**
+ * Returns true if SYSTEM_ALERT_WINDOW permission is available.
+ * Starting from Q, SYSTEM_ALERT_WINDOW is disabled on low ram phones.
+ */
+ public static boolean isSystemAlertWindowEnabled(Context context) {
+ // SYSTEM_ALERT_WINDOW is disabled on on low ram devices starting from Q
+ ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ return !(am.isLowRamDevice() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q));
+ }
}
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index ee0cb7d..921af04 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -57,6 +57,7 @@
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
+import com.android.settings.display.DarkUIPreferenceController;
import com.android.settings.display.ToggleFontSizePreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -133,6 +134,8 @@
"accessibility_content_timeout_preference_fragment";
private static final String ACCESSIBILITY_CONTROL_TIMEOUT_PREFERENCE =
"accessibility_control_timeout_preference_fragment";
+ private static final String DARK_UI_MODE_PREFERENCE =
+ "dark_ui_mode_accessibility";
// Extras passed to sub-fragments.
@@ -236,6 +239,8 @@
private SwitchPreference mToggleInversionPreference;
private ColorInversionPreferenceController mInversionPreferenceController;
private AccessibilityHearingAidPreferenceController mHearingAidPreferenceController;
+ private ListPreference mDarkUIModePreference;
+ private DarkUIPreferenceController mDarkUIPreferenceController;
private int mLongPressTimeoutDefault;
@@ -501,6 +506,13 @@
// Vibrations.
mVibrationPreferenceScreen = findPreference(VIBRATION_PREFERENCE_SCREEN);
+
+ // Dark Mode.
+ mDarkUIModePreference = findPreference(DARK_UI_MODE_PREFERENCE);
+ mDarkUIPreferenceController = new DarkUIPreferenceController(getContext(),
+ DARK_UI_MODE_PREFERENCE);
+ mDarkUIPreferenceController.displayPreference(getPreferenceScreen());
+ mDarkUIModePreference.setSummary(mDarkUIPreferenceController.getSummary());
}
private void updateAllPreferences() {
@@ -683,6 +695,9 @@
// If the quick setting is enabled, the preference MUST be enabled.
mInversionPreferenceController.updateState(mToggleInversionPreference);
+ // Dark Mode
+ mDarkUIPreferenceController.updateState(mDarkUIModePreference);
+
// Power button ends calls.
if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
&& Utils.isVoiceCapable(getActivity())) {
diff --git a/src/com/android/settings/applications/AllAppsInfoPreferenceController.java b/src/com/android/settings/applications/AllAppsInfoPreferenceController.java
new file mode 100644
index 0000000..d39c6e9
--- /dev/null
+++ b/src/com/android/settings/applications/AllAppsInfoPreferenceController.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.app.usage.UsageStats;
+import android.content.Context;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import java.util.List;
+
+public class AllAppsInfoPreferenceController extends BasePreferenceController {
+
+ private List<UsageStats> mRecentApps;
+
+ public AllAppsInfoPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ public void setRecentApps(List<UsageStats> recentApps) {
+ mRecentApps = recentApps;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return mRecentApps == null || mRecentApps.isEmpty() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ // Show total number of installed apps as See all's summary.
+ new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON,
+ mContext.getPackageManager()) {
+ @Override
+ protected void onCountComplete(int num) {
+ preference.setSummary(mContext.getString(R.string.apps_summary, num));
+ }
+ }.execute();
+ }
+}
diff --git a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
index 4848351..7aaf80d 100644
--- a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
+++ b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
@@ -36,6 +36,10 @@
private static final String TAG = "AppAndNotifDashboard";
+ private boolean mIsFirstLaunch;
+ private RecentAppsPreferenceController mRecentAppsPreferenceController;
+ private AllAppsInfoPreferenceController mAllAppsInfoPreferenceController;
+
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY;
@@ -61,7 +65,26 @@
super.onAttach(context);
use(SpecialAppAccessPreferenceController.class).setSession(getSettingsLifecycle());
- use(RecentAppsPreferenceController.class).setFragment(this /* fragment */);
+ mRecentAppsPreferenceController = use(RecentAppsPreferenceController.class);
+ mRecentAppsPreferenceController.setFragment(this /* fragment */);
+
+ mAllAppsInfoPreferenceController = use(AllAppsInfoPreferenceController.class);
+ mAllAppsInfoPreferenceController.setRecentApps(
+ mRecentAppsPreferenceController.getRecentApps());
+
+ mIsFirstLaunch = true;
+ }
+
+ @Override
+ public void onResume() {
+ if (!mIsFirstLaunch) {
+ mRecentAppsPreferenceController.reloadData();
+ mAllAppsInfoPreferenceController.setRecentApps(
+ mRecentAppsPreferenceController.getRecentApps());
+ }
+
+ super.onResume();
+ mIsFirstLaunch = false;
}
@Override
diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index 838d758..c0d18c6 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -67,8 +67,6 @@
implements Comparator<UsageStats> {
@VisibleForTesting
- static final String KEY_ALL_APP_INFO = "all_app_info";
- @VisibleForTesting
static final String KEY_DIVIDER = "recent_apps_divider";
private static final String TAG = "RecentAppsCtrl";
@@ -79,11 +77,7 @@
@VisibleForTesting
LayoutPreference mRecentAppsPreference;
@VisibleForTesting
- Preference mAllAppPref;
- @VisibleForTesting
Preference mDivider;
- @VisibleForTesting
- boolean mIsFirstLaunch;
private final PackageManager mPm;
private final UsageStatsManager mUsageStatsManager;
@@ -119,7 +113,6 @@
mPowerManager = mContext.getSystemService(PowerManager.class);
mUsageStatsManager = mContext.getSystemService(UsageStatsManager.class);
mRecentApps = new ArrayList<>();
- mIsFirstLaunch = true;
reloadData();
}
@@ -129,14 +122,13 @@
@Override
public int getAvailabilityStatus() {
- return mRecentApps.isEmpty() ? AVAILABLE_UNSEARCHABLE : AVAILABLE;
+ return mRecentApps.isEmpty() ? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- mAllAppPref = screen.findPreference(KEY_ALL_APP_INFO);
mDivider = screen.findPreference(KEY_DIVIDER);
mRecentAppsPreference = (LayoutPreference) screen.findPreference(getPreferenceKey());
final View view = mRecentAppsPreference.findViewById(R.id.app_entities_header);
@@ -157,26 +149,18 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- // In order to improve launch time, we don't load data again at first launch.
- if (!mIsFirstLaunch) {
- reloadData();
- refreshUi();
- }
+
+ refreshUi();
// Show total number of installed apps as See all's summary.
new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON,
mContext.getPackageManager()) {
@Override
protected void onCountComplete(int num) {
- if (mHasRecentApps) {
- mAppEntitiesController.setHeaderDetails(
- mContext.getString(R.string.see_all_apps_title, num));
- mAppEntitiesController.apply();
- } else {
- mAllAppPref.setSummary(mContext.getString(R.string.apps_summary, num));
- }
+ mAppEntitiesController.setHeaderDetails(
+ mContext.getString(R.string.see_all_apps_title, num));
+ mAppEntitiesController.apply();
}
}.execute();
- mIsFirstLaunch = false;
}
@Override
@@ -185,14 +169,16 @@
return Long.compare(b.getLastTimeUsed(), a.getLastTimeUsed());
}
+ List<UsageStats> getRecentApps() {
+ return mRecentApps;
+ }
+
@VisibleForTesting
void refreshUi() {
if (mRecentApps != null && !mRecentApps.isEmpty()) {
- mHasRecentApps = true;
displayRecentApps();
} else {
- mHasRecentApps = false;
- displayOnlyAppInfo();
+ mDivider.setVisible(false);
}
}
@@ -209,13 +195,6 @@
updateDisplayableRecentAppList();
}
- private void displayOnlyAppInfo() {
- mDivider.setVisible(false);
- mAllAppPref.setTitle(R.string.applications_settings);
- mAllAppPref.setVisible(true);
- mRecentAppsPreference.setVisible(false);
- }
-
private void displayRecentApps() {
int showAppsCount = 0;
@@ -230,8 +209,6 @@
}
}
mAppEntitiesController.apply();
- mRecentAppsPreference.setVisible(true);
- mAllAppPref.setVisible(false);
mDivider.setVisible(true);
}
diff --git a/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java b/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java
index 9cf57bd..d0b26a5 100644
--- a/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java
+++ b/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java
@@ -17,6 +17,7 @@
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -25,6 +26,9 @@
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
@@ -36,6 +40,7 @@
import androidx.preference.SwitchPreference;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
import com.android.settings.applications.AppStateOverlayBridge;
@@ -70,6 +75,11 @@
mOverlayBridge = new AppStateOverlayBridge(context, mState, null);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ if (!Utils.isSystemAlertWindowEnabled(context)) {
+ mPackageInfo = null;
+ return;
+ }
+
// find preferences
addPreferencesFromResource(R.xml.draw_overlay_permissions_details);
mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
@@ -81,6 +91,18 @@
.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
}
+ // Override here so we don't have an empty screen
+ @Override
+ public View onCreateView (LayoutInflater inflater,
+ ViewGroup container,
+ Bundle savedInstanceState) {
+ // if we don't have a package info, show a page saying this is unsupported
+ if (mPackageInfo == null) {
+ return inflater.inflate(R.layout.manage_applications_apps_unsupported, null);
+ }
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
@Override
public void onResume() {
super.onResume();
@@ -142,6 +164,8 @@
@Override
protected boolean refreshUi() {
+ if (mPackageInfo == null) return true;
+
mOverlayState = mOverlayBridge.getOverlayInfo(mPackageName,
mPackageInfo.applicationInfo.uid);
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index a9de206..9586be0 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -33,6 +33,7 @@
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.app.usage.IUsageStatsManager;
import android.content.Context;
@@ -49,18 +50,22 @@
import android.util.ArraySet;
import android.util.IconDrawableFactory;
import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Filter;
import android.widget.FrameLayout;
import android.widget.SearchView;
import android.widget.Spinner;
+import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -79,6 +84,7 @@
import com.android.settings.Settings.UsageAccessSettingsActivity;
import com.android.settings.Settings.WriteSettingsActivity;
import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
import com.android.settings.applications.AppStateBaseBridge;
@@ -327,12 +333,19 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+ if (mListType == LIST_TYPE_OVERLAY && !Utils.isSystemAlertWindowEnabled(getContext())) {
+ mRootView = inflater.inflate(R.layout.manage_applications_apps_unsupported, null);
+ setHasOptionsMenu(false);
+ return mRootView;
+ }
+
mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
mLoadingContainer = mRootView.findViewById(R.id.loading_container);
mListContainer = mRootView.findViewById(R.id.list_container);
if (mListContainer != null) {
// Create adapter and list view here
mEmptyView = mListContainer.findViewById(android.R.id.empty);
+
mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
savedInstanceState);
if (savedInstanceState != null) {
diff --git a/src/com/android/settings/applications/specialaccess/SystemAlertWindowPreferenceController.java b/src/com/android/settings/applications/specialaccess/SystemAlertWindowPreferenceController.java
new file mode 100644
index 0000000..5d9e8b6
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/SystemAlertWindowPreferenceController.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.applications.specialaccess;
+
+import static com.android.settings.Utils.isSystemAlertWindowEnabled;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Build;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class SystemAlertWindowPreferenceController extends BasePreferenceController {
+ public SystemAlertWindowPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return isSystemAlertWindowEnabled(mContext)
+ ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE ;
+ }
+}
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
index 64c9866..2c4db1f 100644
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
@@ -164,8 +164,7 @@
new BatteryMeterView.BatteryMeterDrawable(context,
context.getColor(R.color.meter_background_color));
drawable.setBatteryLevel(level);
- drawable.setShowPercent(false);
- drawable.setBatteryColorFilter(new PorterDuffColorFilter(
+ drawable.setColorFilter(new PorterDuffColorFilter(
com.android.settings.Utils.getColorAttrDefaultColor(context,
android.R.attr.colorControlNormal),
PorterDuff.Mode.SRC_IN));
diff --git a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
index 6af0911..d7fcb2f 100644
--- a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
+++ b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
@@ -27,9 +27,19 @@
*/
public class FilteredCountryTimeZones {
- // New timezone list and the meta data of time zone, notUsedAfter, is introduced in Android P
- // in 2018. Only show time zone used in or after 2018.
- private static final long MIN_USE_DATE_OF_TIMEZONE = 1514764800000L; // 1/1/2018 00:00 UTC
+ /**
+ * The timestamp used to determine which time zones to show to users by using the notUsedAfter
+ * metadata Android holds for each time zone.
+ *
+ * notUsedAfter exists because some time zones effectively "merge" with other time zones after
+ * a given point in time (i.e. they have identical transitions, offsets, etc.). After that
+ * point we only need to show one of the functionally identical ones.
+ *
+ * Rather than using System.currentTimeMillis(), UX folks asked for consistent behavior and so
+ * a timestamp known to be in the recent past is used. This should be updated occasionally but
+ * it doesn't have to be very often.
+ */
+ private static final long MIN_USE_DATE_OF_TIMEZONE = 1546300800000L; // 1/1/2019 00:00 UTC
private final CountryTimeZones mCountryTimeZones;
private final List<String> mTimeZoneIds;
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index a3cff3d..6a9e9fc 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -16,11 +16,11 @@
package com.android.settings.display;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.core.TogglePreferenceController;
public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreferenceController {
diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
index 5c19ca7..daaf7b1 100644
--- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
@@ -17,6 +17,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -24,7 +25,6 @@
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
diff --git a/src/com/android/settings/fuelgauge/BatteryMeterView.java b/src/com/android/settings/fuelgauge/BatteryMeterView.java
index 822f0e9..aa26ff4 100644
--- a/src/com/android/settings/fuelgauge/BatteryMeterView.java
+++ b/src/com/android/settings/fuelgauge/BatteryMeterView.java
@@ -29,7 +29,7 @@
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settingslib.graph.BatteryMeterDrawableBase;
+import com.android.settingslib.graph.ThemedBatteryDrawable;
public class BatteryMeterView extends ImageView {
@VisibleForTesting
@@ -54,29 +54,27 @@
final int frameColor = context.getColor(R.color.meter_background_color);
mAccentColorFilter = new PorterDuffColorFilter(
Utils.getColorAttrDefaultColor(context, android.R.attr.colorAccent),
- PorterDuff.Mode.SRC_IN);
+ PorterDuff.Mode.SRC);
mErrorColorFilter = new PorterDuffColorFilter(
context.getColor(R.color.battery_icon_color_error), PorterDuff.Mode.SRC_IN);
mDrawable = new BatteryMeterDrawable(context, frameColor);
- mDrawable.setShowPercent(false);
- mDrawable.setBatteryColorFilter(mAccentColorFilter);
- mDrawable.setWarningColorFilter(
- new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
+ mDrawable.setColorFilter(mAccentColorFilter);
setImageDrawable(mDrawable);
+ setLayerType(LAYER_TYPE_SOFTWARE, null);
}
public void setBatteryLevel(int level) {
mDrawable.setBatteryLevel(level);
if (level < mDrawable.getCriticalLevel()) {
- mDrawable.setBatteryColorFilter(mErrorColorFilter);
+ mDrawable.setColorFilter(mErrorColorFilter);
} else {
- mDrawable.setBatteryColorFilter(mAccentColorFilter);
+ mDrawable.setColorFilter(mAccentColorFilter);
}
}
public void setPowerSave(boolean powerSave) {
- mDrawable.setPowerSave(powerSave);
+ mDrawable.setPowerSaveEnabled(powerSave);
mPowerSaveEnabled = powerSave;
}
@@ -85,7 +83,7 @@
}
public int getBatteryLevel() {
- return mDrawable.getBatteryLevel();
+ return mDrawable.getLevel();
}
public void setCharging(boolean charging) {
@@ -97,7 +95,7 @@
return mDrawable.getCharging();
}
- public static class BatteryMeterDrawable extends BatteryMeterDrawableBase {
+ public static class BatteryMeterDrawable extends ThemedBatteryDrawable {
private final int mIntrinsicWidth;
private final int mIntrinsicHeight;
@@ -119,16 +117,5 @@
public int getIntrinsicHeight() {
return mIntrinsicHeight;
}
-
- public void setWarningColorFilter(@Nullable ColorFilter colorFilter) {
- mWarningTextPaint.setColorFilter(colorFilter);
- }
-
- public void setBatteryColorFilter(@Nullable ColorFilter colorFilter) {
- mFramePaint.setColorFilter(colorFilter);
- mBatteryPaint.setColorFilter(colorFilter);
- mBoltPaint.setColorFilter(colorFilter);
- }
}
-
}
diff --git a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
index 9f0a613..4abf09a 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
@@ -21,14 +21,13 @@
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
-
public class DoubleTapScreenPreferenceController extends GesturePreferenceController {
private final int ON = 1;
diff --git a/src/com/android/settings/gestures/DoubleTapScreenSettings.java b/src/com/android/settings/gestures/DoubleTapScreenSettings.java
index 8122504..300ce48 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenSettings.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenSettings.java
@@ -19,9 +19,9 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.SearchIndexableResource;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index c41d3c6..db402cc 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -18,9 +18,9 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.SearchIndexableResource;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
diff --git a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
index 9366a15..98eddff 100644
--- a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
+++ b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
@@ -18,11 +18,11 @@
import android.content.ContentResolver;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.Settings;
import androidx.annotation.NonNull;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
diff --git a/src/com/android/settings/gestures/PickupGesturePreferenceController.java b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
index 7619b69..0738a51 100644
--- a/src/com/android/settings/gestures/PickupGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
@@ -21,12 +21,11 @@
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
-
public class PickupGesturePreferenceController extends GesturePreferenceController {
private static final int ON = 1;
diff --git a/src/com/android/settings/gestures/PickupGestureSettings.java b/src/com/android/settings/gestures/PickupGestureSettings.java
index 6d47902..f1cc3f0 100644
--- a/src/com/android/settings/gestures/PickupGestureSettings.java
+++ b/src/com/android/settings/gestures/PickupGestureSettings.java
@@ -19,9 +19,9 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.SearchIndexableResource;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
diff --git a/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java b/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java
index bbffc7c..ba2b869 100644
--- a/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java
@@ -20,12 +20,11 @@
import android.annotation.UserIdInt;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
-
public class TapScreenGesturePreferenceController extends GesturePreferenceController {
private static final String PREF_KEY_VIDEO = "gesture_tap_screen_video";
diff --git a/src/com/android/settings/gestures/TapScreenGestureSettings.java b/src/com/android/settings/gestures/TapScreenGestureSettings.java
index d80c03d..a86e682 100644
--- a/src/com/android/settings/gestures/TapScreenGestureSettings.java
+++ b/src/com/android/settings/gestures/TapScreenGestureSettings.java
@@ -18,9 +18,9 @@
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.SearchIndexableResource;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
diff --git a/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java b/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java
index 96a3580..e9d03d7 100644
--- a/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java
@@ -20,12 +20,12 @@
import android.annotation.UserIdInt;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.aware.AwareFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
diff --git a/src/com/android/settings/homepage/contextualcards/CardContentProvider.java b/src/com/android/settings/homepage/contextualcards/CardContentProvider.java
index e7ede14..a9a832d 100644
--- a/src/com/android/settings/homepage/contextualcards/CardContentProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/CardContentProvider.java
@@ -39,12 +39,18 @@
public static final String CARD_AUTHORITY = "com.android.settings.homepage.CardContentProvider";
- public static final Uri URI = new Uri.Builder()
+ public static final Uri REFRESH_CARD_URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(CardContentProvider.CARD_AUTHORITY)
.appendPath(CardDatabaseHelper.CARD_TABLE)
.build();
+ public static final Uri DELETE_CARD_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(CardContentProvider.CARD_AUTHORITY)
+ .appendPath(CardDatabaseHelper.CardColumns.CARD_DISMISSED)
+ .build();
+
private static final String TAG = "CardContentProvider";
/** URI matcher for ContentProvider queries. */
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
diff --git a/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java b/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
index b9bab21..39c48c1 100644
--- a/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
@@ -208,7 +208,7 @@
* Mark a specific ContextualCard with dismissal flag in the database to indicate that the
* card has been dismissed.
*
- * @param context Context
+ * @param context Context
* @param cardName The card name of the ContextualCard which is dismissed by user.
* @return The number of rows updated
*/
@@ -220,7 +220,7 @@
final String[] selectionArgs = {cardName};
final int rowsUpdated = database.update(CARD_TABLE, values, selection, selectionArgs);
database.close();
- context.getContentResolver().notifyChange(CardContentProvider.URI, null);
+ context.getContentResolver().notifyChange(CardContentProvider.DELETE_CARD_URI, null);
return rowsUpdated;
}
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
index d6ea6ca..ea6ac43 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
@@ -59,13 +59,16 @@
private final ContentObserver mObserver = new ContentObserver(
new Handler(Looper.getMainLooper())) {
@Override
- public void onChange(boolean selfChange) {
+ public void onChange(boolean selfChange, Uri uri) {
if (isStarted()) {
+ mNotifyUri = uri;
forceLoad();
}
}
};
+ @VisibleForTesting
+ Uri mNotifyUri;
private Context mContext;
ContextualCardLoader(Context context) {
@@ -77,7 +80,10 @@
@Override
protected void onStartLoading() {
super.onStartLoading();
- mContext.getContentResolver().registerContentObserver(CardContentProvider.URI,
+ mNotifyUri = null;
+ mContext.getContentResolver().registerContentObserver(CardContentProvider.REFRESH_CARD_URI,
+ false /*notifyForDescendants*/, mObserver);
+ mContext.getContentResolver().registerContentObserver(CardContentProvider.DELETE_CARD_URI,
false /*notifyForDescendants*/, mObserver);
}
@@ -156,10 +162,12 @@
// Two large cards
return visibleCards;
} finally {
- //TODO(b/121196921): Should not call this if user click dismiss
- final ContextualCardFeatureProvider contextualCardFeatureProvider =
- FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
- contextualCardFeatureProvider.logContextualCardDisplay(visibleCards, hiddenCards);
+ if (!CardContentProvider.DELETE_CARD_URI.equals(mNotifyUri)) {
+ final ContextualCardFeatureProvider contextualCardFeatureProvider =
+ FeatureFactory.getFactory(mContext)
+ .getContextualCardFeatureProvider(mContext);
+ contextualCardFeatureProvider.logContextualCardDisplay(visibleCards, hiddenCards);
+ }
}
}
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 2d40efe..48e9f1e 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -118,7 +118,8 @@
sliceLiveData.observe(mLifecycleOwner, slice -> {
if (slice == null) {
Log.w(TAG, "Slice is null");
- mContext.getContentResolver().notifyChange(CardContentProvider.URI, null);
+ mContext.getContentResolver().notifyChange(CardContentProvider.REFRESH_CARD_URI,
+ null);
return;
} else {
//TODO(b/120629936): Take this out once blank card issue is fixed.
diff --git a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java
index 7b37855..733d0d9 100644
--- a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java
+++ b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java
@@ -50,13 +50,18 @@
}
private void updateSummary(Preference preference) {
- Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(mContext, getRingtoneType());
- final CharSequence summary = Ringtone.getTitle(
- mContext, ringtoneUri, false /* followSettingsUri */, true /* allowRemote */);
+ final Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(
+ mContext, getRingtoneType());
+
+ final CharSequence summary;
+ if (ringtoneUri == null) {
+ summary = null;
+ } else {
+ summary = Ringtone.getTitle(
+ mContext, ringtoneUri, false /* followSettingsUri */, true /* allowRemote */);
+ }
if (summary != null) {
- ThreadUtils.postOnMainThread(() -> {
- preference.setSummary(summary);
- });
+ ThreadUtils.postOnMainThread(() -> preference.setSummary(summary));
}
}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index cf62112..4a758be 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -76,6 +76,7 @@
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.FooterPreferenceMixinCompat;
+import java.util.Arrays;
import java.util.List;
public class ChooseLockGeneric extends SettingsActivity {
@@ -151,7 +152,7 @@
private boolean mPasswordConfirmed = false;
private boolean mWaitingForConfirmation = false;
private boolean mForChangeCredRequiredForBoot = false;
- private String mUserPassword;
+ private byte[] mUserPassword;
private LockPatternUtils mLockPatternUtils;
private FingerprintManager mFingerprintManager;
private FaceManager mFaceManager;
@@ -200,7 +201,7 @@
.getBooleanExtra(CONFIRM_CREDENTIALS, true);
if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
mPasswordConfirmed = !confirmCredentials;
- mUserPassword = getActivity().getIntent().getStringExtra(
+ mUserPassword = getActivity().getIntent().getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
}
@@ -224,7 +225,7 @@
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
if (mUserPassword == null) {
- mUserPassword = savedInstanceState.getString(
+ mUserPassword = savedInstanceState.getByteArray(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
}
}
@@ -383,11 +384,11 @@
if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
mPasswordConfirmed = true;
mUserPassword = data != null
- ? data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)
+ ? data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)
: null;
updatePreferencesOrFinish(false /* isRecreatingActivity */);
if (mForChangeCredRequiredForBoot) {
- if (!TextUtils.isEmpty(mUserPassword)) {
+ if (!(mUserPassword == null || mUserPassword.length == 0)) {
maybeEnableEncryption(
mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false);
} else {
@@ -447,7 +448,7 @@
outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
if (mUserPassword != null) {
- outState.putString(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword);
+ outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword);
}
}
@@ -669,7 +670,7 @@
setPreferenceSummary(ScreenLockType.MANAGED, R.string.secure_lock_encryption_warning);
}
- protected Intent getLockManagedPasswordIntent(String password) {
+ protected Intent getLockManagedPasswordIntent(byte[] password) {
return mManagedPasswordProvider.createIntent(false, password);
}
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index cd48182..c9d1af3 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -78,6 +78,7 @@
import com.google.android.setupdesign.GlifLayout;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
public class ChooseLockPassword extends SettingsActivity {
@@ -123,7 +124,7 @@
return this;
}
- public IntentBuilder setPassword(String password) {
+ public IntentBuilder setPassword(byte[] password) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
return this;
}
@@ -185,8 +186,8 @@
private static final String KEY_CURRENT_PASSWORD = "current_password";
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
- private String mCurrentPassword;
- private String mChosenPassword;
+ private byte[] mCurrentPassword;
+ private byte[] mChosenPassword;
private boolean mHasChallenge;
private long mChallenge;
private ImeAwareEditText mPasswordEntry;
@@ -215,7 +216,7 @@
protected boolean mForFingerprint;
protected boolean mForFace;
- private String mFirstPin;
+ private byte[] mFirstPin;
private RecyclerView mPasswordRestrictionView;
protected boolean mIsAlphaMode;
protected FooterButton mSkipOrClearButton;
@@ -234,7 +235,7 @@
private static final int MIN_NUMBER_IN_PASSWORD = 4;
private static final int MIN_NON_LETTER_IN_PASSWORD = 5;
- // Error code returned from {@link #validatePassword(String)}.
+ // Error code returned from {@link #validatePassword(byte[])}.
static final int NO_ERROR = 0;
static final int CONTAIN_INVALID_CHARACTERS = 1 << 0;
static final int TOO_SHORT = 1 << 1;
@@ -394,12 +395,13 @@
SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
- String current = intent.getStringExtra(
+ byte[] currentBytes = intent.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+
w.setBlocking(true);
w.setListener(this);
- w.start(mChooseLockSettingsHelper.utils(), required,
- false, 0, current, current, mRequestedQuality, mUserId);
+ w.start(mChooseLockSettingsHelper.utils(), required, false, 0,
+ currentBytes, currentBytes, mRequestedQuality, mUserId);
}
mTextChangedHandler = new TextChangedHandler();
}
@@ -474,7 +476,8 @@
Intent intent = getActivity().getIntent();
final boolean confirmCredentials = intent.getBooleanExtra(
ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
- mCurrentPassword = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ mCurrentPassword = intent.getByteArrayExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
@@ -486,8 +489,9 @@
mUserId);
}
} else {
+
// restore from previous state
- mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN);
+ mFirstPin = savedInstanceState.getByteArray(KEY_FIRST_PIN);
final String state = savedInstanceState.getString(KEY_UI_STAGE);
if (state != null) {
mUiStage = Stage.valueOf(state);
@@ -495,7 +499,7 @@
}
if (mCurrentPassword == null) {
- mCurrentPassword = savedInstanceState.getString(KEY_CURRENT_PASSWORD);
+ mCurrentPassword = savedInstanceState.getByteArray(KEY_CURRENT_PASSWORD);
}
// Re-attach to the exiting worker if there is one.
@@ -553,8 +557,8 @@
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_UI_STAGE, mUiStage.name());
- outState.putString(KEY_FIRST_PIN, mFirstPin);
- outState.putString(KEY_CURRENT_PASSWORD, mCurrentPassword);
+ outState.putByteArray(KEY_FIRST_PIN, mFirstPin);
+ outState.putByteArray(KEY_CURRENT_PASSWORD, mCurrentPassword);
}
@Override
@@ -567,7 +571,7 @@
getActivity().setResult(RESULT_FINISHED);
getActivity().finish();
} else {
- mCurrentPassword = data.getStringExtra(
+ mCurrentPassword = data.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
}
break;
@@ -712,22 +716,22 @@
* @return the validation result.
*/
@VisibleForTesting
- int validatePassword(String password) {
+ int validatePassword(byte[] password) {
int errorCode = NO_ERROR;
final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
mergeMinComplexityAndDpmRequirements(metrics.quality);
- if (password.length() < mPasswordMinLength) {
+ if (password == null || password.length < mPasswordMinLength) {
if (mPasswordMinLength > mPasswordMinLengthToFulfillAllPolicies) {
errorCode |= TOO_SHORT;
}
- } else if (password.length() > mPasswordMaxLength) {
+ } else if (password.length > mPasswordMaxLength) {
errorCode |= TOO_LONG;
} else {
// The length requirements are fulfilled.
if (!mPasswordNumSequenceAllowed
&& !requiresLettersOrSymbols()
- && metrics.numeric == password.length()) {
+ && metrics.numeric == password.length) {
// Check for repeated characters or sequences (e.g. '1234', '0000', '2468')
// if DevicePolicyManager or min password complexity requires a complex numeric
// password. There can be two cases in the UI: 1. User chooses to enroll a
@@ -757,8 +761,8 @@
}
// Allow non-control Latin-1 characters only.
- for (int i = 0; i < password.length(); i++) {
- char c = password.charAt(i);
+ for (int i = 0; i < password.length; i++) {
+ char c = (char) password[i];
if (c < 32 || c > 127) {
errorCode |= CONTAIN_INVALID_CHARACTERS;
break;
@@ -809,8 +813,9 @@
public void handleNext() {
if (mSaveAndFinishWorker != null) return;
- mChosenPassword = mPasswordEntry.getText().toString();
- if (TextUtils.isEmpty(mChosenPassword)) {
+ // TODO(b/120484642): This is a point of entry for passwords from the UI
+ mChosenPassword = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
+ if (mChosenPassword == null || mChosenPassword.length == 0) {
return;
}
if (mUiStage == Stage.Introduction) {
@@ -818,9 +823,11 @@
mFirstPin = mChosenPassword;
mPasswordEntry.setText("");
updateStage(Stage.NeedToConfirm);
+ } else {
+ Arrays.fill(mChosenPassword, (byte) 0);
}
} else if (mUiStage == Stage.NeedToConfirm) {
- if (mFirstPin.equals(mChosenPassword)) {
+ if (Arrays.equals(mFirstPin, mChosenPassword)) {
startSaveAndFinish();
} else {
CharSequence tmp = mPasswordEntry.getText();
@@ -828,6 +835,7 @@
Selection.setSelection((Spannable) tmp, 0, tmp.length());
}
updateStage(Stage.ConfirmWrong);
+ Arrays.fill(mChosenPassword, (byte) 0);
}
}
}
@@ -940,8 +948,8 @@
*/
protected void updateUi() {
final boolean canInput = mSaveAndFinishWorker == null;
- String password = mPasswordEntry.getText().toString();
- final int length = password.length();
+ byte[] password = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
+ final int length = password.length;
if (mUiStage == Stage.Introduction) {
mPasswordRestrictionView.setVisibility(View.VISIBLE);
final int errorCode = validatePassword(password);
@@ -967,6 +975,7 @@
setNextText(mUiStage.buttonText);
mPasswordEntryInputDisabler.setInputEnabled(canInput);
+ Arrays.fill(password, (byte) 0);
}
protected int toVisibility(boolean visibleOrGone) {
@@ -1025,6 +1034,18 @@
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
getActivity().setResult(RESULT_FINISHED, resultData);
+ if (mChosenPassword != null) {
+ Arrays.fill(mChosenPassword, (byte) 0);
+ }
+ if (mCurrentPassword != null) {
+ Arrays.fill(mCurrentPassword, (byte) 0);
+ }
+ if (mFirstPin != null) {
+ Arrays.fill(mFirstPin, (byte) 0);
+ }
+
+ mPasswordEntry.setText("");
+
if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) {
@@ -1061,13 +1082,13 @@
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
- private String mChosenPassword;
- private String mCurrentPassword;
+ private byte[] mChosenPassword;
+ private byte[] mCurrentPassword;
private int mRequestedQuality;
public void start(LockPatternUtils utils, boolean required,
boolean hasChallenge, long challenge,
- String chosenPassword, String currentPassword, int requestedQuality, int userId) {
+ byte[] chosenPassword, byte[] currentPassword, int requestedQuality, int userId) {
prepare(utils, required, hasChallenge, challenge, userId);
mChosenPassword = chosenPassword;
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index 584cc61..d5ad1ab 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -55,6 +55,7 @@
import com.google.android.setupdesign.GlifLayout;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -114,7 +115,7 @@
return this;
}
- public IntentBuilder setPattern(String pattern) {
+ public IntentBuilder setPattern(byte[] pattern) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
return this;
}
@@ -187,7 +188,7 @@
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
- private String mCurrentPattern;
+ private byte[] mCurrentPattern;
private boolean mHasChallenge;
private long mChallenge;
protected TextView mTitleText;
@@ -224,7 +225,7 @@
getActivity().setResult(RESULT_FINISHED);
getActivity().finish();
} else {
- mCurrentPattern = data.getStringExtra(
+ mCurrentPattern = data.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
}
@@ -457,12 +458,12 @@
SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
- String current = intent.getStringExtra(
+ byte[] current = intent.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true);
w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required,
- false, 0, LockPatternUtils.stringToPattern(current), current, mUserId);
+ false, 0, LockPatternUtils.byteArrayToPattern(current), current, mUserId);
}
mForFingerprint = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
@@ -540,7 +541,8 @@
final boolean confirmCredentials = getActivity().getIntent()
.getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
Intent intent = getActivity().getIntent();
- mCurrentPattern = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ mCurrentPattern =
+ intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
@@ -563,13 +565,13 @@
}
} else {
// restore from previous state
- final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
- if (patternString != null) {
- mChosenPattern = LockPatternUtils.stringToPattern(patternString);
+ final byte[] pattern = savedInstanceState.getByteArray(KEY_PATTERN_CHOICE);
+ if (pattern != null) {
+ mChosenPattern = LockPatternUtils.byteArrayToPattern(pattern);
}
if (mCurrentPattern == null) {
- mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN);
+ mCurrentPattern = savedInstanceState.getByteArray(KEY_CURRENT_PATTERN);
}
updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
@@ -665,13 +667,12 @@
outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
if (mChosenPattern != null) {
- outState.putString(KEY_PATTERN_CHOICE,
- LockPatternUtils.patternToString(mChosenPattern));
+ outState.putByteArray(KEY_PATTERN_CHOICE,
+ LockPatternUtils.patternToByteArray(mChosenPattern));
}
if (mCurrentPattern != null) {
- outState.putString(KEY_CURRENT_PATTERN,
- mCurrentPattern);
+ outState.putByteArray(KEY_CURRENT_PATTERN, mCurrentPattern);
}
}
@@ -818,6 +819,10 @@
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
getActivity().setResult(RESULT_FINISHED, resultData);
+ if (mCurrentPattern != null) {
+ Arrays.fill(mCurrentPattern, (byte) 0);
+ }
+
if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) {
@@ -831,12 +836,12 @@
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private List<LockPatternView.Cell> mChosenPattern;
- private String mCurrentPattern;
+ private byte[] mCurrentPattern;
private boolean mLockVirgin;
public void start(LockPatternUtils utils, boolean credentialRequired,
boolean hasChallenge, long challenge,
- List<LockPatternView.Cell> chosenPattern, String currentPattern, int userId) {
+ List<LockPatternView.Cell> chosenPattern, byte[] currentPattern, int userId) {
prepare(utils, credentialRequired, hasChallenge, challenge, userId);
mCurrentPattern = currentPattern;
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index f893870..6c61967 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -323,8 +323,9 @@
return;
}
- final String pin = mPasswordEntry.getText().toString();
- if (TextUtils.isEmpty(pin)) {
+ // TODO(b/120484642): This is a point of entry for passwords from the UI
+ final byte[] pin = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
+ if (pin == null || pin.length == 0) {
return;
}
@@ -350,7 +351,7 @@
return getActivity() instanceof ConfirmLockPassword.InternalActivity;
}
- private void startVerifyPassword(final String pin, final Intent intent) {
+ private void startVerifyPassword(final byte[] pin, final Intent intent) {
long challenge = getActivity().getIntent().getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
final int localEffectiveUserId = mEffectiveUserId;
@@ -381,7 +382,7 @@
onVerifyCallback);
}
- private void startCheckPassword(final String pin, final Intent intent) {
+ private void startCheckPassword(final byte[] pin, final Intent intent) {
final int localEffectiveUserId = mEffectiveUserId;
mPendingLockCheck = LockPatternChecker.checkPassword(
mLockPatternUtils,
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index 29cdfef..6d3d6e5 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -448,7 +448,7 @@
mLockPatternUtils, pattern, challenge, localUserId,
onVerifyCallback)
: LockPatternChecker.verifyTiedProfileChallenge(
- mLockPatternUtils, LockPatternUtils.patternToString(pattern),
+ mLockPatternUtils, LockPatternUtils.patternToByteArray(pattern),
true, challenge, localUserId, onVerifyCallback);
}
@@ -473,7 +473,7 @@
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
StorageManager.CRYPT_TYPE_PATTERN);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
- LockPatternUtils.patternToString(pattern));
+ LockPatternUtils.patternToByteArray(pattern));
}
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
localEffectiveUserId);
diff --git a/src/com/android/settings/password/ManagedLockPasswordProvider.java b/src/com/android/settings/password/ManagedLockPasswordProvider.java
index 2494af5..5006926 100644
--- a/src/com/android/settings/password/ManagedLockPasswordProvider.java
+++ b/src/com/android/settings/password/ManagedLockPasswordProvider.java
@@ -59,7 +59,7 @@
* @param password Current lock password.
* @return Intent that should update lock password to a managed password.
*/
- Intent createIntent(boolean requirePasswordToDecrypt, String password) {
+ Intent createIntent(boolean requirePasswordToDecrypt, byte[] password) {
return null;
}
}
diff --git a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
index 2c6368e..453cdbf 100644
--- a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
+++ b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.permission.PermissionControllerManager;
import android.permission.RuntimePermissionUsageInfo;
import android.provider.DeviceConfig;
@@ -31,12 +32,15 @@
import android.view.View;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.Utils;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.widget.BarChartInfo;
import com.android.settingslib.widget.BarChartPreference;
@@ -48,14 +52,17 @@
public class PermissionBarChartPreferenceController extends BasePreferenceController implements
- PermissionControllerManager.OnPermissionUsageResultCallback, LifecycleObserver, OnStart {
+ PermissionControllerManager.OnPermissionUsageResultCallback, LifecycleObserver, OnCreate,
+ OnStart, OnSaveInstanceState {
private static final String TAG = "BarChartPreferenceCtl";
+ private static final String KEY_PERMISSION_USAGE = "usage_infos";
+ @VisibleForTesting
+ List<RuntimePermissionUsageInfo> mOldUsageInfos;
private PackageManager mPackageManager;
private PrivacyDashboardFragment mParent;
private BarChartPreference mBarChartPreference;
- private List<RuntimePermissionUsageInfo> mOldUsageInfos;
public PermissionBarChartPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -68,6 +75,18 @@
}
@Override
+ public void onCreate(Bundle savedInstanceState) {
+ if (savedInstanceState != null) {
+ mOldUsageInfos = savedInstanceState.getParcelableArrayList(KEY_PERMISSION_USAGE);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ outState.putParcelableList(KEY_PERMISSION_USAGE, mOldUsageInfos);
+ }
+
+ @Override
public int getAvailabilityStatus() {
return Boolean.parseBoolean(
DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE,
@@ -92,6 +111,9 @@
.build();
mBarChartPreference.initializeBarChart(info);
+ if (!mOldUsageInfos.isEmpty()) {
+ mBarChartPreference.setBarViewInfos(createBarViews(mOldUsageInfos));
+ }
}
@Override
@@ -100,7 +122,9 @@
return;
}
- mBarChartPreference.updateLoadingState(true /* isLoading */);
+ // We don't hide chart when we have existing data.
+ mBarChartPreference.updateLoadingState(mOldUsageInfos.isEmpty() /* isLoading */);
+ // But we still need to hint user with progress bar that we are updating new usage data.
mParent.setLoadingEnabled(true /* enabled */);
retrievePermissionUsageData();
}
diff --git a/src/com/android/settings/security/CryptKeeperSettings.java b/src/com/android/settings/security/CryptKeeperSettings.java
index c80ad11..6555f56 100644
--- a/src/com/android/settings/security/CryptKeeperSettings.java
+++ b/src/com/android/settings/security/CryptKeeperSettings.java
@@ -173,7 +173,7 @@
if (helper.utils().getKeyguardStoredPasswordQuality(UserHandle.myUserId())
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "");
+ showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes());
return true;
}
@@ -193,14 +193,14 @@
// confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK && data != null) {
int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1);
- String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
- if (!TextUtils.isEmpty(password)) {
+ byte[] password = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ if (!(password == null || password.length == 0)) {
showFinalConfirmation(type, password);
}
}
}
- private void showFinalConfirmation(int type, String password) {
+ private void showFinalConfirmation(int type, byte[] password) {
Preference preference = new Preference(getPreferenceManager().getContext());
preference.setFragment(CryptKeeperConfirm.class.getName());
preference.setTitle(R.string.crypt_keeper_confirm_title);
@@ -208,16 +208,16 @@
((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference);
}
- private void addEncryptionInfoToPreference(Preference preference, int type, String password) {
+ private void addEncryptionInfoToPreference(Preference preference, int type, byte[] password) {
Activity activity = getActivity();
DevicePolicyManager dpm = (DevicePolicyManager)
activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm.getDoNotAskCredentialsOnBoot()) {
preference.getExtras().putInt(TYPE, StorageManager.CRYPT_TYPE_DEFAULT);
- preference.getExtras().putString(PASSWORD, "");
+ preference.getExtras().putByteArray(PASSWORD, "".getBytes());
} else {
preference.getExtras().putInt(TYPE, type);
- preference.getExtras().putString(PASSWORD, password);
+ preference.getExtras().putByteArray(PASSWORD, password);
}
}
}
diff --git a/src/com/android/settings/security/LockUnificationPreferenceController.java b/src/com/android/settings/security/LockUnificationPreferenceController.java
index 978986c..bf374de 100644
--- a/src/com/android/settings/security/LockUnificationPreferenceController.java
+++ b/src/com/android/settings/security/LockUnificationPreferenceController.java
@@ -70,8 +70,8 @@
private RestrictedSwitchPreference mUnifyProfile;
- private String mCurrentDevicePassword;
- private String mCurrentProfilePassword;
+ private byte[] mCurrentDevicePassword;
+ private byte[] mCurrentProfilePassword;
private boolean mKeepDeviceLock;
@Override
@@ -151,13 +151,13 @@
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword =
- data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
launchConfirmProfileLock();
return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentProfilePassword =
- data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
unifyLocks();
return true;
}
@@ -226,7 +226,7 @@
// PASSWORD_QUALITY_SOMETHING means pattern, everything above means PIN/password.
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
- LockPatternUtils.stringToPattern(mCurrentProfilePassword),
+ LockPatternUtils.byteArrayToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID);
} else {
mLockPatternUtils.saveLockPassword(
diff --git a/src/com/android/settings/security/LockscreenDashboardFragment.java b/src/com/android/settings/security/LockscreenDashboardFragment.java
index 1935f05..3472d48 100644
--- a/src/com/android/settings/security/LockscreenDashboardFragment.java
+++ b/src/com/android/settings/security/LockscreenDashboardFragment.java
@@ -18,11 +18,11 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.SearchIndexableResource;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController;
diff --git a/src/com/android/settings/slices/SlicesIndexer.java b/src/com/android/settings/slices/SlicesIndexer.java
index ec2be29..1b3a25e 100644
--- a/src/com/android/settings/slices/SlicesIndexer.java
+++ b/src/com/android/settings/slices/SlicesIndexer.java
@@ -71,7 +71,7 @@
long startTime = System.currentTimeMillis();
database.beginTransaction();
try {
- mHelper.reconstruct(mHelper.getWritableDatabase());
+ mHelper.reconstruct(database);
List<SliceData> indexData = getSliceData();
insertSliceData(database, indexData);
diff --git a/src/com/android/settings/users/MultiUserSwitchBarController.java b/src/com/android/settings/users/MultiUserSwitchBarController.java
index 9588f71..58de149 100644
--- a/src/com/android/settings/users/MultiUserSwitchBarController.java
+++ b/src/com/android/settings/users/MultiUserSwitchBarController.java
@@ -17,27 +17,34 @@
package com.android.settings.users;
import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.widget.SwitchWidgetController;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
public class MultiUserSwitchBarController implements SwitchWidgetController.OnSwitchChangeListener,
LifecycleObserver, OnStart, OnStop {
+ private static final String TAG = "MultiUserSwitchBarCtrl";
interface OnMultiUserSwitchChangedListener {
void onMultiUserSwitchChanged(boolean newState);
}
+ @VisibleForTesting
+ final SwitchWidgetController mSwitchBar;
- private static final String TAG = "MultiUserSwitchBarCtrl";
private final Context mContext;
- private final SwitchWidgetController mSwitchBar;
private final UserCapabilities mUserCapabilities;
private final OnMultiUserSwitchChangedListener mListener;
+
MultiUserSwitchBarController(Context context, SwitchWidgetController switchBar,
OnMultiUserSwitchChangedListener listener) {
mContext = context;
@@ -45,8 +52,15 @@
mListener = listener;
mUserCapabilities = UserCapabilities.create(context);
mSwitchBar.setChecked(mUserCapabilities.mUserSwitcherEnabled);
- mSwitchBar.setEnabled(!mUserCapabilities.mDisallowSwitchUser
- && !mUserCapabilities.mIsGuest && mUserCapabilities.isAdmin());
+
+ if (mUserCapabilities.mDisallowSwitchUser) {
+ mSwitchBar.setDisabledByAdmin(RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(mContext, UserManager.DISALLOW_USER_SWITCH,
+ UserHandle.myUserId()));
+ } else {
+ mSwitchBar.setEnabled(!mUserCapabilities.mDisallowSwitchUser
+ && !mUserCapabilities.mIsGuest && mUserCapabilities.isAdmin());
+ }
mSwitchBar.setListener(this);
}
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 1d78485..e7db5db 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -376,12 +376,12 @@
}
WifiInfo info = mAccessPoint.getInfo();
- if (info != null && info.getTxLinkSpeedMbps() != -1) {
+ if (info != null && info.getTxLinkSpeedMbps() != WifiInfo.LINK_SPEED_UNKNOWN) {
addRow(group, R.string.tx_wifi_speed, String.format(
res.getString(R.string.tx_link_speed), info.getTxLinkSpeedMbps()));
}
- if (info != null && info.getRxLinkSpeedMbps() != -1) {
+ if (info != null && info.getRxLinkSpeedMbps() != WifiInfo.LINK_SPEED_UNKNOWN) {
addRow(group, R.string.rx_wifi_speed, String.format(
res.getString(R.string.rx_link_speed), info.getRxLinkSpeedMbps()));
}
@@ -1509,7 +1509,7 @@
// Populate the Wi-Fi security spinner with the various supported key management types
spinnerAdapter.add(mContext.getString(R.string.wifi_security_none));
mSecurityInPosition[idx++] = AccessPoint.SECURITY_NONE;
- if (mWifiManager.isOweSupported()) {
+ if (mWifiManager.isEnhancedOpenSupported()) {
spinnerAdapter.add(mContext.getString(R.string.wifi_security_owe));
mSecurityInPosition[idx++] = AccessPoint.SECURITY_OWE;
}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 27c495e..c00fe24 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -1116,7 +1116,12 @@
return;
}
} else if (mSelectedAccessPoint.getConfig().isPasspoint()) {
- mWifiManager.removePasspointConfiguration(mSelectedAccessPoint.getConfig().FQDN);
+ try {
+ mWifiManager.removePasspointConfiguration(mSelectedAccessPoint.getConfig().FQDN);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Failed to remove Passpoint configuration with error: " + e);
+ return;
+ }
} else {
mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, mForgetListener);
}
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 53b1530..bc33f4f 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.TRANSPORT_WIFI;
import android.app.Activity;
+import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver;
@@ -45,7 +46,6 @@
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;
@@ -61,6 +61,7 @@
import com.android.settings.Utils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
import com.android.settings.widget.EntityHeaderController;
import com.android.settings.wifi.WifiDialog;
import com.android.settings.wifi.WifiDialog.WifiDialogListener;
@@ -568,6 +569,12 @@
mWifiManager.disableEphemeralNetwork(mWifiInfo.getSSID());
} else if (mWifiConfig != null) {
if (mWifiConfig.isPasspoint()) {
+ // Post a dialog to confirm if user really want to forget the passpoint network.
+ if (FeatureFlagPersistent.isEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2)) {
+ showConfirmForgetDialog();
+ return;
+ }
+
mWifiManager.removePasspointConfiguration(mWifiConfig.FQDN);
} else {
mWifiManager.forget(mWifiConfig.networkId, null /* action listener */);
@@ -578,6 +585,22 @@
mFragment.getActivity().finish();
}
+ @VisibleForTesting
+ protected void showConfirmForgetDialog() {
+ final AlertDialog dialog = new AlertDialog.Builder(mContext)
+ .setPositiveButton(R.string.forget, ((dialog1, which) -> {
+ mWifiManager.removePasspointConfiguration(mWifiConfig.FQDN);
+ mMetricsFeatureProvider.action(
+ mFragment.getActivity(), SettingsEnums.ACTION_WIFI_FORGET);
+ mFragment.getActivity().finish();
+ }))
+ .setNegativeButton(R.string.cancel, null /* listener */)
+ .setTitle(R.string.wifi_forget_dialog_title)
+ .setMessage(R.string.forget_passpoint_dialog_message)
+ .create();
+ dialog.show();
+ }
+
/**
* Show QR code to share the network represented by this preference.
*/
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index 1770a02..be5a12f 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -156,7 +156,7 @@
cancelActivity = true;
} else {
final WifiNetworkConfig connectedConfig = getConnectedWifiNetworkConfigOrNull();
- if (connectedConfig == null) {
+ if (connectedConfig == null || !connectedConfig.isSupportWifiDpp(this)) {
showChooseSavedWifiNetworkFragment(/* addToBackStack */ false);
} else {
mWifiNetworkConfig = connectedConfig;
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 2264ba6..daa41d9f 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -86,7 +86,7 @@
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity();
MenuItem menuItem;
- if (wifiNetworkConfig.isSupportConfiguratorQrCodeScanner(getActivity())) {
+ if (wifiNetworkConfig.isSupportWifiDpp(getActivity())) {
menuItem = menu.add(0, Menu.FIRST, 0, R.string.next_label);
menuItem.setIcon(R.drawable.ic_scan_24dp);
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
index 6135cba..a483073 100644
--- a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
+++ b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
@@ -212,7 +212,7 @@
wifiManager.connect(wifiConfiguration, listener);
}
- public boolean isSupportConfiguratorQrCodeScanner(Context context) {
+ public boolean isSupportWifiDpp(Context context) {
if (!WifiDppUtils.isWifiDppEnabled(context)) {
return false;
}
diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java
index 679ab8b..8d20f7f 100644
--- a/src/com/android/settings/wifi/slice/WifiSlice.java
+++ b/src/com/android/settings/wifi/slice/WifiSlice.java
@@ -118,10 +118,19 @@
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri());
final List<AccessPoint> results = worker != null ? worker.getResults() : null;
+ final int apCount = results == null ? 0 : results.size();
- // Need a loading text when results are not ready.
- boolean needLoadingRow = results == null;
- final int apCount = needLoadingRow ? 0 : results.size();
+ // Need a loading text when results are not ready or out of date.
+ boolean needLoadingRow = true;
+ int index = apCount > 0 && results.get(0).isActive() ? 1 : 0;
+ // This loop checks the existence of reachable APs to determine the validity of the current
+ // AP list.
+ for (; index < apCount; index++) {
+ if (results.get(index).isReachable()) {
+ needLoadingRow = false;
+ break;
+ }
+ }
// Add AP rows
final CharSequence placeholder = mContext.getText(R.string.summary_placeholder);
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index 96d5bf5..8c53019 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -21,14 +21,17 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
+import android.app.UiModeManager;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Vibrator;
import android.provider.Settings;
+import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.android.settings.R;
+import com.android.settings.display.DarkUIPreferenceController;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
@@ -47,10 +50,13 @@
"accessibility_content_timeout_preference_fragment";
private static final String ACCESSIBILITY_CONTROL_TIMEOUT_PREFERENCE =
"accessibility_control_timeout_preference_fragment";
+ private static final String DARK_UI_MODE_PREFERENCE =
+ "dark_ui_mode_accessibility";
private Context mContext;
private ContentResolver mContentResolver;
private AccessibilitySettings mSettings;
+ private UiModeManager mUiModeManager;
@Before
public void setup() {
@@ -59,6 +65,7 @@
mContentResolver = mContext.getContentResolver();
mSettings = spy(new AccessibilitySettings());
doReturn(mContext).when(mSettings).getContext();
+ mUiModeManager = mContext.getSystemService(UiModeManager.class);
}
@Test
@@ -146,4 +153,29 @@
assertThat(preference.getSummary()).isEqualTo(mContext.getResources().getString(resId));
}
+
+ @Test
+ public void testDarkUIModePreferenceSummary_shouldUpdateSummary() {
+ final ListPreference darkUIModePreference = new ListPreference(mContext);
+ final DarkUIPreferenceController mController;
+ doReturn(darkUIModePreference).when(mSettings).findPreference(
+ DARK_UI_MODE_PREFERENCE);
+ mController = new DarkUIPreferenceController(mContext, DARK_UI_MODE_PREFERENCE);
+ final String darkUIModeDescription = modeToDescription(mUiModeManager.getNightMode());
+ darkUIModePreference.setSummary(mController.getSummary());
+
+ assertThat(darkUIModePreference.getSummary()).isEqualTo(darkUIModeDescription);
+ }
+
+ private String modeToDescription(int mode) {
+ String[] values = mContext.getResources().getStringArray(R.array.dark_ui_mode_entries);
+ switch (mode) {
+ case UiModeManager.MODE_NIGHT_YES:
+ return values[0];
+ case UiModeManager.MODE_NIGHT_NO:
+ case UiModeManager.MODE_NIGHT_AUTO:
+ default:
+ return values[1];
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/AllAppsInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/AllAppsInfoPreferenceControllerTest.java
new file mode 100644
index 0000000..ec3cf65
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/AllAppsInfoPreferenceControllerTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.usage.UsageStats;
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class AllAppsInfoPreferenceControllerTest {
+
+ private AllAppsInfoPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ final Context context = RuntimeEnvironment.application;
+ mController = new AllAppsInfoPreferenceController(context, "test_key");
+ }
+
+ @Test
+ public void getAvailabilityStatus_hasRecentApps_shouldReturnConditionallyUnavailable() {
+ final List<UsageStats> stats = new ArrayList<>();
+ final UsageStats stat1 = new UsageStats();
+ stat1.mLastTimeUsed = System.currentTimeMillis();
+ stat1.mPackageName = "pkg.class";
+ stats.add(stat1);
+ mController.setRecentApps(stats);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_noRecentApps_shouldReturnAvailable() {
+ // No data
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
index e2a1657..1a28f37 100644
--- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
@@ -18,6 +18,7 @@
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
@@ -111,7 +112,6 @@
final View appEntitiesHeaderView = LayoutInflater.from(context).inflate(
R.layout.app_entities_header, null /* root */);
- final Preference seeAllPreference = new Preference(context);
final Preference dividerPreference = new Preference(context);
mRecentAppsPreference = spy(new LayoutPreference(context, appEntitiesHeaderView));
@@ -119,11 +119,8 @@
mController.setFragment(mFragment);
mController.mAppEntitiesController = mock(AppEntitiesHeaderController.class);
mController.mRecentAppsPreference = mRecentAppsPreference;
- mController.mAllAppPref = seeAllPreference;
mController.mDivider = dividerPreference;
- when(mScreen.findPreference(RecentAppsPreferenceController.KEY_ALL_APP_INFO))
- .thenReturn(seeAllPreference);
when(mScreen.findPreference(RecentAppsPreferenceController.KEY_DIVIDER))
.thenReturn(dividerPreference);
when(mScreen.findPreference("test_key")).thenReturn(mRecentAppsPreference);
@@ -152,9 +149,33 @@
}
@Test
- public void getAvailabilityStatus_noRecentApps_shouldReturnAvailableUnsearchable() {
+ public void getAvailabilityStatus_noRecentApps_shouldReturnConditionallyUnavailable() {
// No data
- assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_powerSaverModeOn_shouldReturnConditionallyUnavailable() {
+ when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+
+ final List<UsageStats> stats = new ArrayList<>();
+ final UsageStats stat1 = new UsageStats();
+
+ stat1.mLastTimeUsed = System.currentTimeMillis();
+ stat1.mPackageName = "pkg.class";
+ stats.add(stat1);
+
+ // stat1, stat2 are valid apps. stat3 is invalid.
+ when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
+ .thenReturn(mAppEntry);
+ when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
+ .thenReturn(new ResolveInfo());
+ when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
+ .thenReturn(stats);
+ mAppEntry.info = mApplicationInfo;
+ mController.reloadData();
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
@@ -179,25 +200,6 @@
}
@Test
- public void updateState_firstLaunch_shouldNotReloadData() {
- mController.mIsFirstLaunch = true;
-
- mController.updateState(mRecentAppsPreference);
-
- verify(mController, never()).reloadData();
- }
-
- @Test
- public void updateState_afterFirstLaunch_shouldReloadDataAndRefreshUi() {
- mController.mIsFirstLaunch = false;
-
- mController.updateState(mRecentAppsPreference);
-
- verify(mController).reloadData();
- verify(mController).refreshUi();
- }
-
- @Test
public void updateState_threeValidRecentOpenAppsSet_setAppEntityThreeTime() {
final List<UsageStats> stats = new ArrayList<>();
final UsageStats stat1 = new UsageStats();
@@ -227,7 +229,7 @@
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
mAppEntry.info = mApplicationInfo;
- mController.mIsFirstLaunch = false;
+ mController.reloadData();
mController.updateState(mRecentAppsPreference);
@@ -235,7 +237,6 @@
.setAppEntity(anyInt(), any(AppEntityInfo.class));
assertThat(mController.mRecentAppsPreference.isVisible()).isTrue();
assertThat(mController.mDivider.isVisible()).isTrue();
- assertThat(mController.mAllAppPref.isVisible()).isFalse();
}
@Test
@@ -268,7 +269,7 @@
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
mAppEntry.info = mApplicationInfo;
- mController.mIsFirstLaunch = false;
+ mController.reloadData();
mController.updateState(mRecentAppsPreference);
@@ -278,35 +279,6 @@
.setAppEntity(anyInt(), any(AppEntityInfo.class));
assertThat(mController.mRecentAppsPreference.isVisible()).isTrue();
assertThat(mController.mDivider.isVisible()).isTrue();
- assertThat(mController.mAllAppPref.isVisible()).isFalse();
- }
-
- @Test
- public void updateState_powerSaverModeOn_headerIsNotVisible() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(true);
-
- final List<UsageStats> stats = new ArrayList<>();
- final UsageStats stat1 = new UsageStats();
-
- stat1.mLastTimeUsed = System.currentTimeMillis();
- stat1.mPackageName = "pkg.class";
- stats.add(stat1);
-
- // stat1, stat2 are valid apps. stat3 is invalid.
- when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
- .thenReturn(mAppEntry);
- when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
- .thenReturn(new ResolveInfo());
- when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
- .thenReturn(stats);
- mAppEntry.info = mApplicationInfo;
- mController.mIsFirstLaunch = false;
-
- mController.updateState(mRecentAppsPreference);
-
- assertThat(mController.mRecentAppsPreference.isVisible()).isFalse();
- assertThat(mController.mDivider.isVisible()).isFalse();
- assertThat(mController.mAllAppPref.isVisible()).isTrue();
}
@Test
@@ -341,7 +313,7 @@
// Make sure stat2 is considered an instant app.
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
(InstantAppDataProvider) (ApplicationInfo info) -> info == stat2Entry.info);
- mController.mIsFirstLaunch = false;
+ mController.reloadData();
mController.updateState(mRecentAppsPreference);
@@ -417,7 +389,7 @@
.thenReturn(new ResolveInfo());
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
- mController.mIsFirstLaunch = false;
+ mController.reloadData();
mController.updateState(mRecentAppsPreference);
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/SystemAlertWindowPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/SystemAlertWindowPreferenceControllerTest.java
new file mode 100644
index 0000000..bc90f2b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/SystemAlertWindowPreferenceControllerTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.specialaccess;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settings.testutils.shadow.ShadowUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowUtils.class})
+public class SystemAlertWindowPreferenceControllerTest {
+
+ private Context mContext;
+ private SystemAlertWindowPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mController = new SystemAlertWindowPreferenceController(mContext, "key");
+ }
+
+ @Test
+ public void systemAlertWindow_byDefault_shouldBeShown() {
+ ShadowUtils.setIsSystemAlertWindowEnabled(true);
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void systemAlertWindow_lowMemory_shouldNotBeShown() {
+ ShadowUtils.setIsSystemAlertWindowEnabled(false);
+ assertThat(mController.isAvailable()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
index f8e0a74..7cd5a23 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
@@ -23,9 +23,9 @@
import android.content.ContentResolver;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.Settings;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
index e36b394..fbfb8a4 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
@@ -29,12 +29,12 @@
import android.content.ContentResolver;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java
index 4bdcd55..3e99433 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java
@@ -73,14 +73,14 @@
public void testSetBatteryInfo_levelLow_setErrorColor() {
mBatteryMeterView.setBatteryLevel(BATTERY_LOW_LEVEL);
- verify(mDrawable).setBatteryColorFilter(mErrorColorFilter);
+ verify(mDrawable).setColorFilter(mErrorColorFilter);
}
@Test
public void testSetBatteryInfo_levelNormal_setNormalColor() {
mBatteryMeterView.setBatteryLevel(BATTERY_LEVEL);
- verify(mDrawable).setBatteryColorFilter(mAccentColorFilter);
+ verify(mDrawable).setColorFilter(mAccentColorFilter);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
index 52cb75d..0dc7a78 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
@@ -26,8 +26,8 @@
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java
index 5422eab..b2ba216 100644
--- a/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/PickupGesturePreferenceControllerTest.java
@@ -26,8 +26,8 @@
import android.content.Context;
import android.content.SharedPreferences;
+import android.hardware.display.AmbientDisplayConfiguration;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/gestures/TapScreenGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/TapScreenGesturePreferenceControllerTest.java
index c09e4eb..12715fd 100644
--- a/tests/robotests/src/com/android/settings/gestures/TapScreenGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/TapScreenGesturePreferenceControllerTest.java
@@ -25,8 +25,7 @@
import static org.mockito.Mockito.when;
import android.content.Context;
-
-import com.android.internal.hardware.AmbientDisplayConfiguration;
+import android.hardware.display.AmbientDisplayConfiguration;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java
index ecda5fd..471914a 100644
--- a/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java
@@ -28,8 +28,8 @@
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.hardware.display.AmbientDisplayConfiguration;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.aware.AwareFeatureProvider;
import com.android.settings.testutils.FakeFeatureFactory;
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
index 18aa1c4..8b04ef3 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
@@ -24,7 +24,9 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import android.content.Context;
import android.net.Uri;
@@ -33,6 +35,7 @@
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
@@ -52,6 +55,7 @@
private Context mContext;
private ContextualCardLoader mContextualCardLoader;
private EligibleCardChecker mEligibleCardChecker;
+ private FakeFeatureFactory mFakeFeatureFactory;
@Before
public void setUp() {
@@ -59,6 +63,7 @@
mContextualCardLoader = spy(new ContextualCardLoader(mContext));
mEligibleCardChecker =
spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
}
@Test
@@ -158,6 +163,26 @@
assertThat(mContextualCardLoader.loadInBackground()).isEmpty();
}
+ @Test
+ public void getDisplayableCards_refreshCardUri_shouldLogContextualCardDisplay() {
+ mContextualCardLoader.mNotifyUri = CardContentProvider.REFRESH_CARD_URI;
+
+ mContextualCardLoader.getDisplayableCards(new ArrayList<ContextualCard>());
+
+ verify(mFakeFeatureFactory.mContextualCardFeatureProvider).logContextualCardDisplay(
+ any(List.class), any(List.class));
+ }
+
+ @Test
+ public void getDisplayableCards_deleteCardUri_shouldNotLogContextualCardDisplay() {
+ mContextualCardLoader.mNotifyUri = CardContentProvider.DELETE_CARD_URI;
+
+ mContextualCardLoader.getDisplayableCards(new ArrayList<ContextualCard>());
+
+ verify(mFakeFeatureFactory.mContextualCardFeatureProvider, never())
+ .logContextualCardDisplay(any(List.class), any(List.class));
+ }
+
private ContextualCard getContextualCard(String sliceUri) {
return new ContextualCard.Builder()
.setName("test_card")
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java
index 7e1a32c..e97e01e 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java
@@ -75,7 +75,7 @@
@Test
public void onDismissed_cardShouldBeMarkedAsDismissed() {
- final Uri providerUri = CardContentProvider.URI;
+ final Uri providerUri = CardContentProvider.REFRESH_CARD_URI;
mResolver.insert(providerUri, generateOneRow());
doNothing().when(mController).showFeedbackDialog(any(ContextualCard.class));
@@ -96,7 +96,7 @@
@Test
public void onDismissed_noFeedbackEmail_shouldNotShowFeedbackDialog() {
- mResolver.insert(CardContentProvider.URI, generateOneRow());
+ mResolver.insert(CardContentProvider.REFRESH_CARD_URI, generateOneRow());
final ContextualCardsFragment fragment =
FragmentController.of(new ContextualCardsFragment()).create().get();
final ShadowActivity shadowActivity = Shadows.shadowOf(fragment.getActivity());
@@ -109,7 +109,7 @@
@Test
@Config(qualifiers = "mcc999")
public void onDismissed_hasFeedbackEmail_shouldShowFeedbackDialog() {
- mResolver.insert(CardContentProvider.URI, generateOneRow());
+ mResolver.insert(CardContentProvider.REFRESH_CARD_URI, generateOneRow());
final ContextualCardsFragment fragment =
FragmentController.of(new ContextualCardsFragment()).create().get();
final ShadowActivity shadowActivity = Shadows.shadowOf(fragment.getActivity());
diff --git a/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java
index f22a782..2fb1738 100644
--- a/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java
@@ -20,31 +20,31 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.media.RingtoneManager;
+import android.provider.Settings;
import androidx.preference.Preference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class RingtonePreferenceControllerBaseTest {
- @Mock
private Context mContext;
private RingtonePreferenceControllerBase mController;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
mController = new RingtonePreferenceControllerBaseTestable(mContext);
}
@@ -56,14 +56,26 @@
@Test
public void updateState_shouldSetSummary() {
Preference preference = mock(Preference.class);
+ Settings.System.putString(mContext.getContentResolver(), Settings.System.RINGTONE,
+ "content://test/ringtone");
mController.updateState(preference);
verify(preference).setSummary(anyString());
}
+ @Test
+ public void updateState_nullRingtone_shouldNotGetTitle() {
+ Preference preference = mock(Preference.class);
+ Settings.System.putString(mContext.getContentResolver(), Settings.System.RINGTONE, null);
+
+ mController.updateState(preference);
+
+ verify(preference, never()).setSummary(anyString());
+ }
+
private class RingtonePreferenceControllerBaseTestable
- extends RingtonePreferenceControllerBase {
+ extends RingtonePreferenceControllerBase {
RingtonePreferenceControllerBaseTestable(Context context) {
super(context);
}
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
index 404d205..73707a6 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
@@ -87,7 +87,7 @@
@Test
public void intentBuilder_setPassword_shouldAddExtras() {
Intent intent = new IntentBuilder(application)
- .setPassword("password")
+ .setPassword("password".getBytes())
.setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
.setUserId(123)
.build();
@@ -95,9 +95,9 @@
assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true))
.named("EXTRA_KEY_HAS_CHALLENGE")
.isFalse();
- assertThat(intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
+ assertThat(intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD")
- .isEqualTo("password");
+ .isEqualTo("password".getBytes());
assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0))
.named("PASSWORD_TYPE_KEY")
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
@@ -366,7 +366,9 @@
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity);
ChooseLockPassword activity = buildChooseLockPasswordActivity(intent);
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(activity);
- int validateResult = fragment.validatePassword(userEnteredPassword);
+ byte[] userEnteredPasswordBytes = userEnteredPassword != null
+ ? userEnteredPassword.getBytes() : null;
+ int validateResult = fragment.validatePassword(userEnteredPasswordBytes);
String[] messages = fragment.convertErrorCodeToMessages(validateResult);
assertThat(messages).asList().containsExactly((Object[]) expectedValidationResult);
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
index 6b1029c..3509d75 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
@@ -52,7 +52,7 @@
@Test
public void intentBuilder_setPattern_shouldAddExtras() {
Intent intent = new IntentBuilder(application)
- .setPattern("pattern")
+ .setPattern("pattern".getBytes())
.setUserId(123)
.build();
@@ -61,9 +61,9 @@
.named("EXTRA_KEY_HAS_CHALLENGE")
.isFalse();
assertThat(intent
- .getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
+ .getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD")
- .isEqualTo("pattern");
+ .isEqualTo("pattern".getBytes());
assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0))
.named("EXTRA_USER_ID")
.isEqualTo(123);
diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
index f664f4f..332156e 100644
--- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
@@ -125,6 +125,18 @@
}
@Test
+ public void displayPreference_usageInfosSet_shouldSetBarViewInfos() {
+ final RuntimePermissionUsageInfo info1 =
+ new RuntimePermissionUsageInfo("permission 1", 10);
+ mController.mOldUsageInfos.add(info1);
+
+ mController.displayPreference(mScreen);
+
+ verify(mPreference).setBarViewInfos(any(BarViewInfo[].class));
+ verify(mPreference).initializeBarChart(any(BarChartInfo.class));
+ }
+
+ @Test
public void onPermissionUsageResult_differentPermissionResultSet_shouldSetBarViewInfos() {
final List<RuntimePermissionUsageInfo> infos1 = new ArrayList<>();
final RuntimePermissionUsageInfo info1 =
@@ -159,7 +171,7 @@
}
@Test
- public void onStart_permissionHubEnabled_shouldShowProgressBar() {
+ public void onStart_usageInfosNotSetAndPermissionHubEnabled_shouldShowProgressBar() {
DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE,
DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true);
mController.displayPreference(mScreen);
@@ -171,6 +183,21 @@
}
@Test
+ public void onStart_usageInfosSetAndPermissionHubEnabled_shouldNotUpdatePrefLoadingState() {
+ DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE,
+ DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true);
+ final RuntimePermissionUsageInfo info1 =
+ new RuntimePermissionUsageInfo("permission 1", 10);
+ mController.mOldUsageInfos.add(info1);
+ mController.displayPreference(mScreen);
+
+ mController.onStart();
+
+ verify(mFragment).setLoadingEnabled(true /* enabled */);
+ verify(mPreference).updateLoadingState(false /* isLoading */);
+ }
+
+ @Test
public void onStart_permissionHubDisabled_shouldNotShowProgressBar() {
DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE,
DeviceConfig.Privacy.PROPERTY_PERMISSIONS_HUB_ENABLED, "false", false);
diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
index d84d42c..fdd4475 100644
--- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java
+++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
@@ -253,6 +253,18 @@
assertThat(hasText(sliceItems, subtitle, null /* hints */)).isTrue();
}
+ /**
+ * Assert no slice item contains subtitle.
+ *
+ * @param sliceItems All slice items of a Slice.
+ * @param subtitle Subtitle for asserting.
+ */
+ public static void assertNoSliceItemContainsSubtitle(List<SliceItem> sliceItems,
+ String subtitle) {
+ // Subtitle has no hints
+ assertThat(hasText(sliceItems, subtitle, null /* hints */)).isFalse();
+ }
+
private static boolean hasText(List<SliceItem> sliceItems, String text, String hints) {
boolean hasText = false;
for (SliceItem item : sliceItems) {
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
index f287085..e9be346 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
@@ -66,12 +66,12 @@
}
@Implementation
- protected byte[] getPasswordHistoryHashFactor(String currentPassword, int userId) {
+ protected byte[] getPasswordHistoryHashFactor(byte[] currentPassword, int userId) {
return null;
}
@Implementation
- protected boolean checkPasswordHistory(String passwordToCheck, byte[] hashFactor, int userId) {
+ protected boolean checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId) {
return false;
}
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index 9a18c1f..bceba3c 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -26,6 +26,7 @@
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
+import org.robolectric.annotation.Resetter;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,6 +39,8 @@
@Implements(value = UserManager.class)
public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
+ private static boolean sIsSupportsMultipleUsers;
+
private final List<String> mRestrictions = new ArrayList<>();
private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
@@ -50,6 +53,11 @@
mUserProfileInfos.add(userInfo);
}
+ @Resetter
+ public static void reset() {
+ sIsSupportsMultipleUsers = false;
+ }
+
@Implementation
protected List<UserInfo> getProfiles(@UserIdInt int userHandle) {
return mUserProfileInfos;
@@ -124,4 +132,13 @@
public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
mUserSwitchEnabled = userSwitchEnabled;
}
+
+ @Implementation
+ protected static boolean supportsMultipleUsers() {
+ return sIsSupportsMultipleUsers;
+ }
+
+ public void setSupportsMultipleUsers(boolean supports) {
+ sIsSupportsMultipleUsers = supports;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
index 4797e8c..f8644d9 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -38,6 +38,7 @@
private static boolean sIsDemoUser;
private static ComponentName sDeviceOwnerComponentName;
private static Map<String, String> sAppNameMap;
+ private static boolean sIsSystemAlertWindowEnabled;
@Implementation
protected static int enforceSameOwner(Context context, int userId) {
@@ -113,4 +114,13 @@
}
sAppNameMap.put(packageName, appLabel);
}
+
+ @Implementation
+ protected static boolean isSystemAlertWindowEnabled(Context context) {
+ return sIsSystemAlertWindowEnabled;
+ }
+
+ public static void setIsSystemAlertWindowEnabled(boolean enabled) {
+ sIsSystemAlertWindowEnabled = enabled;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
new file mode 100644
index 0000000..718e01b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.users;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.SwitchBarController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowUserManager.class})
+public class MultiUserSwitchBarControllerTest {
+
+ private Context mContext;
+ private ShadowUserManager mUserManager;
+ private SwitchBarController mSwitchBarController;
+
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mUserManager = ShadowUserManager.getShadow();
+ mSwitchBarController = spy(new SwitchBarController(new SwitchBar(mContext)));
+ mUserManager.setSupportsMultipleUsers(true);
+ }
+
+ @After
+ public void tearDown() {
+ ShadowUserManager.reset();
+ }
+
+ @Test
+ public void onStart_disallowUserSwitch_shouldSetDisabledByAdmin() {
+ mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+ UserManager.DISALLOW_USER_SWITCH, true);
+
+ final MultiUserSwitchBarController controller = new MultiUserSwitchBarController(mContext,
+ mSwitchBarController, null);
+
+ verify(mSwitchBarController).setDisabledByAdmin(any());
+ }
+
+ @Test
+ public void onStart_allowUserSwitch_shouldNotSetDisabledByAdmin() {
+ mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+ UserManager.DISALLOW_USER_SWITCH, false);
+
+ final MultiUserSwitchBarController controller = new MultiUserSwitchBarController(mContext,
+ mSwitchBarController, null);
+
+ verify(mSwitchBarController, never()).setDisabledByAdmin(any());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index fd25f7d..b16d900 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -324,7 +324,7 @@
WifiManager wifiManager = mock(WifiManager.class);
when(wifiManager.isWpa3SaeSupported()).thenReturn(saeVisible);
when(wifiManager.isWpa3SuiteBSupported()).thenReturn(suitebVisible);
- when(wifiManager.isOweSupported()).thenReturn(oweVisible);
+ when(wifiManager.isEnhancedOpenSupported()).thenReturn(oweVisible);
mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */,
WifiConfigUiBase.MODE_MODIFY, wifiManager);
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 308d4b5..640c426 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -65,6 +65,8 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
@@ -429,7 +431,7 @@
@Test
public void linkSpeedPref_shouldNotShowIfNotSet() {
- when(mockWifiInfo.getTxLinkSpeedMbps()).thenReturn(-1);
+ when(mockWifiInfo.getTxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN);
displayAndResume();
@@ -447,7 +449,7 @@
@Test
public void rxLinkSpeedPref_shouldNotShowIfNotSet() {
- when(mockWifiInfo.getRxLinkSpeedMbps()).thenReturn(-1);
+ when(mockWifiInfo.getRxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN);
displayAndResume();
@@ -756,6 +758,36 @@
}
@Test
+ public void forgetNetwork_Passpoint() {
+ mockWifiConfig.networkId = 5;
+ when(mockWifiConfig.isPasspoint()).thenReturn(true);
+
+ mController.displayPreference(mockScreen);
+ mForgetClickListener.getValue().onClick(null);
+
+ verify(mockWifiManager).removePasspointConfiguration(mockWifiConfig.FQDN);
+ verify(mockMetricsFeatureProvider)
+ .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
+ }
+
+ @Test
+ public void forgetNetwork_PasspointV2_shouldShowDialog() {
+ final WifiDetailPreferenceController spyController = spy(mController);
+
+ mockWifiConfig.networkId = 5;
+ when(mockWifiConfig.isPasspoint()).thenReturn(true);
+ FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, true);
+
+ spyController.displayPreference(mockScreen);
+ mForgetClickListener.getValue().onClick(null);
+
+ verify(mockWifiManager, times(0)).removePasspointConfiguration(mockWifiConfig.FQDN);
+ verify(mockMetricsFeatureProvider, times(0))
+ .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
+ verify(spyController).showConfirmForgetDialog();
+ }
+
+ @Test
public void networkStateChangedIntent_shouldRefetchInfo() {
displayAndResume();
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
index 6af8f80..01feb8e 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
@@ -21,6 +21,7 @@
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
+import static com.android.settings.wifi.slice.WifiSlice.WifiScanWorker;
import static com.google.common.truth.Truth.assertThat;
@@ -32,6 +33,8 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.net.NetworkInfo;
+import android.net.Uri;
import android.net.wifi.WifiManager;
import androidx.core.graphics.drawable.IconCompat;
@@ -44,24 +47,33 @@
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
+import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.testutils.SliceTester;
+import com.android.settingslib.wifi.AccessPoint;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class WifiSliceTest {
+ private static final String AP1_NAME = "ap1";
+ private static final String AP2_NAME = "ap2";
+
private Context mContext;
private ContentResolver mResolver;
private WifiManager mWifiManager;
private WifiSlice mWifiSlice;
- private WifiSlice.WifiScanWorker mWifiScanWorker;
+ private WifiScanWorker mWifiScanWorker;
@Before
public void setUp() {
@@ -75,7 +87,7 @@
mWifiManager.setWifiEnabled(true);
mWifiSlice = new WifiSlice(mContext);
- mWifiScanWorker = new WifiSlice.WifiScanWorker(mContext, WIFI_SLICE_URI);
+ mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
}
@Test
@@ -122,6 +134,107 @@
mContext.getString(R.string.wifi_empty_list_wifi_on));
}
+ private AccessPoint createAccessPoint(String name, boolean active, boolean reachable) {
+ final AccessPoint accessPoint = mock(AccessPoint.class);
+ doReturn(name).when(accessPoint).getConfigName();
+ doReturn(active).when(accessPoint).isActive();
+ doReturn(reachable).when(accessPoint).isReachable();
+ if (active) {
+ final NetworkInfo networkInfo = mock(NetworkInfo.class);
+ doReturn(networkInfo).when(accessPoint).getNetworkInfo();
+ doReturn(NetworkInfo.State.CONNECTED).when(networkInfo).getState();
+ }
+ return accessPoint;
+ }
+
+ private void setWorkerResults(AccessPoint... accessPoints) {
+ final ArrayList<AccessPoint> results = new ArrayList<>();
+ for (AccessPoint ap : accessPoints) {
+ results.add(ap);
+ }
+ final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(mWifiSlice.getUri());
+ doReturn(results).when(worker).getResults();
+ }
+
+ @Test
+ @Config(shadows = ShadowSliceBackgroundWorker.class)
+ public void getWifiSlice_noReachableAp_shouldReturnLoadingRow() {
+ setWorkerResults(
+ createAccessPoint(AP1_NAME, false, false),
+ createAccessPoint(AP2_NAME, false, false));
+ final Slice wifiSlice = mWifiSlice.getSlice();
+
+ final List<SliceItem> sliceItems = wifiSlice.getItems();
+
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP2_NAME);
+ // Has scanning text
+ SliceTester.assertAnySliceItemContainsSubtitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
+ }
+
+ @Test
+ @Config(shadows = ShadowSliceBackgroundWorker.class)
+ public void getWifiSlice_oneActiveAp_shouldReturnLoadingRow() {
+ setWorkerResults(createAccessPoint(AP1_NAME, true, true));
+ final Slice wifiSlice = mWifiSlice.getSlice();
+
+ final List<SliceItem> sliceItems = wifiSlice.getItems();
+
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
+ // Has scanning text
+ SliceTester.assertAnySliceItemContainsSubtitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
+ }
+
+ @Test
+ @Config(shadows = ShadowSliceBackgroundWorker.class)
+ public void getWifiSlice_oneActiveApAndOneUnreachableAp_shouldReturnLoadingRow() {
+ setWorkerResults(
+ createAccessPoint(AP1_NAME, true, true),
+ createAccessPoint(AP2_NAME, false, false));
+ final Slice wifiSlice = mWifiSlice.getSlice();
+
+ final List<SliceItem> sliceItems = wifiSlice.getItems();
+
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP2_NAME);
+ // Has scanning text
+ SliceTester.assertAnySliceItemContainsSubtitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
+ }
+
+ @Test
+ @Config(shadows = ShadowSliceBackgroundWorker.class)
+ public void getWifiSlice_oneReachableAp_shouldNotReturnLoadingRow() {
+ setWorkerResults(createAccessPoint(AP1_NAME, false, true));
+ final Slice wifiSlice = mWifiSlice.getSlice();
+
+ final List<SliceItem> sliceItems = wifiSlice.getItems();
+
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
+ // No scanning text
+ SliceTester.assertNoSliceItemContainsSubtitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
+ }
+
+ @Test
+ @Config(shadows = ShadowSliceBackgroundWorker.class)
+ public void getWifiSlice_allReachableAps_shouldNotReturnLoadingRow() {
+ setWorkerResults(
+ createAccessPoint(AP1_NAME, false, true),
+ createAccessPoint(AP2_NAME, false, true));
+ final Slice wifiSlice = mWifiSlice.getSlice();
+
+ final List<SliceItem> sliceItems = wifiSlice.getItems();
+
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP2_NAME);
+ // No scanning text
+ SliceTester.assertNoSliceItemContainsSubtitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
+ }
+
@Test
public void handleUriChange_updatesWifi() {
final Intent intent = mWifiSlice.getIntent();
@@ -146,4 +259,14 @@
verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
}
+
+ @Implements(SliceBackgroundWorker.class)
+ public static class ShadowSliceBackgroundWorker {
+ private static WifiScanWorker mWifiScanWorker = mock(WifiScanWorker.class);
+
+ @Implementation
+ public static SliceBackgroundWorker getInstance(Uri uri) {
+ return mWifiScanWorker;
+ }
+ }
}
diff --git a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
index 4c72b34..807ac6f 100644
--- a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
+++ b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
@@ -52,7 +52,9 @@
"Display",
"Sound",
"Storage",
- "Security & location",
+ "Security",
+ "Location",
+ "Privacy",
"Accounts",
"Accessibility",
"System"