Snap for 7347062 from fc9217fca5 to sc-release

Change-Id: I6bbd071d9987ca9192ae488f5d8a41b66117aa72
This commit is contained in:
android-build-team Robot
2021-05-08 03:08:33 +00:00
82 changed files with 980 additions and 1537 deletions

View File

@@ -3684,17 +3684,6 @@
android:value="com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleSettings" />
</activity>
<activity android:name="Settings$GlobalActionsPanelSettingsActivity"
android:exported="true"
android:label="@string/cards_passes_sentence">
<intent-filter>
<action android:name="com.android.settings.GLOBAL_ACTIONS_PANEL_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.gestures.GlobalActionsPanelSettings" />
</activity>
<activity android:name="Settings$PowerMenuSettingsActivity"
android:exported="true"
android:label="@string/power_menu_setting_name">

View File

@@ -18,7 +18,7 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:orientation="vertical">

View File

@@ -61,5 +61,15 @@
android:singleLine="true"
android:textAppearance="@style/TextAppearance.HomepagePreferenceTitle"
android:ellipsize="marquee"/>
<TextView android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="4"/>
</RelativeLayout>
</LinearLayout>

View File

@@ -1311,16 +1311,16 @@
<!-- Title for security picker to choose the unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="lock_settings_picker_title">Choose screen lock</string>
<!-- Screen title. This title is asking the user to choose a type of screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=27] -->
<!-- Screen title. This title is asking the user to choose a type of screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=55] -->
<string name="lock_settings_picker_new_lock_title">Choose a screen lock</string>
<!-- Screen title. This title is asking the user to choose a new screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=27] -->
<!-- Screen title. This title is asking the user to choose a new screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=55] -->
<string name="lock_settings_picker_update_lock_title">Choose a new screen lock</string>
<!-- Screen title. This title is asking the user to choose a type of screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=27] -->
<!-- Screen title. This title is asking the user to choose a type of screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=56] -->
<string name="lock_settings_picker_new_profile_lock_title">Choose a lock for work apps</string>
<!-- Screen title. This title is asking the user to choose a new screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=27] -->
<!-- Screen title. This title is asking the user to choose a new screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=55] -->
<string name="lock_settings_picker_update_profile_lock_title">Choose a new work lock</string>
<!-- Title for security picker in setup wizard to choose the unlock method: None/Pattern/PIN/Password (tablet) [CHAR LIMIT=22] -->
@@ -2426,7 +2426,7 @@
<!-- Wifi details preference title to display router IP subnet mask -->
<string name="wifi_details_subnet_mask">Subnet mask</string>
<!-- Wifi details preference title to display wifi type info [CHAR LIMIT=50]-->
<string name="wifi_type_title">TYPE</string>
<string name="wifi_type_title">Type</string>
<!-- Wifi details preference title to display router DNS info -->
<string name="wifi_details_dns">DNS</string>
<!-- Wifi details preference category title for IPv6 information -->
@@ -4980,7 +4980,7 @@
<!-- Title for the 'Spell checker for work' preference. [CHAR LIMIT=45] -->
<string name="user_dict_settings_for_work_title">Personal dictionary for work</string>
<!-- User dictionary settings. The summary of the list item to go into the Personal dictionary settings screen. -->
<string name="user_dict_settings_summary">""</string>
<string name="user_dict_settings_summary">Add words to be used in apps such as Spell checker</string>
<!-- User dictionary settings. The title of the menu item to add a new word to the user dictionary. -->
<string name="user_dict_settings_add_menu_title">Add</string>
<!-- User dictionary settings. The title of the dialog to add a new word to the user dictionary. [CHAR LIMIT=25] -->
@@ -8079,8 +8079,7 @@
<string name="keywords_profile_challenge">work challenge, work, profile</string>
<string name="keywords_unification">work profile, managed profile, unify, unification, work, profile</string>
<string name="keywords_gesture">gestures</string>
<string name="keywords_cards_passes">cards, passes</string>
<string name="keywords_device_controls">device controls, controls</string>
<string name="keywords_wallet">wallet</string>
<string name="keywords_payment_settings">pay, tap, payments</string>
<string name="keywords_backup">backup, back up</string>
<string name="keywords_assist_gesture_launch">gesture</string>
@@ -12969,32 +12968,11 @@
<!-- Power menu setting title [CHAR LIMIT=NONE] -->
<string name="power_menu_setting_title">Power button menu</string>
<!-- Power menu setting option cards and passes [CHAR LIMIT=NONE] -->
<string name="power_menu_cards_passes">Show cards &amp; passes</string>
<!-- Power menu setting lock screen category name [CHAR LIMIT=40] -->
<string name="power_menu_lock_screen_category">Lock screen</string>
<!-- Power menu setting option none [CHAR LIMIT=NONE] -->
<string name="power_menu_none">Don\u2019t show any content</string>
<!-- Power menu setting Privacy [CHAR LIMIT=40] -->
<string name="power_menu_privacy">Sensitive content</string>
<!-- Power menu setting privacy show all [CHAR LIMIT=NONE] -->
<string name="power_menu_privacy_show">Show cards and controls when locked</string>
<!-- Power menu setting privacy show controls [CHAR LIMIT=NONE] -->
<string name="power_menu_privacy_show_controls">Show controls when locked</string>
<!-- Power menu setting privacy show cards [CHAR LIMIT=NONE] -->
<string name="power_menu_privacy_show_cards">Show cards when locked</string>
<!-- Power menu setting privacy hide all [CHAR LIMIT=NONE] -->
<string name="power_menu_privacy_hide">Hide cards and controls when locked</string>
<!-- Power menu setting privacy no secure screen lock set [CHAR_LIMIT=NONE] -->
<string name="power_menu_privacy_not_secure">To use, first set a screen lock</string>
<string name="lockscreen_privacy_not_secure">To use, first set a screen lock</string>
<!-- Power menu setting use long press power to invoke assistant. [CHAR_LIMIT=NONE] -->
<string name="power_menu_long_press_for_assist">Hold for Assistant</string>
@@ -13002,17 +12980,15 @@
<!-- Power menu setting use log press power to invoke assistant summary. [CHAR_LIMIT=NONE] -->
<string name="power_menu_long_press_for_assist_summary">Trigger the Assistant by holding the power button</string>
<!-- Wallet (formerly Cards and passes) toggle name [CHAR LIMIT=60] -->
<string name="lockscreen_privacy_wallet_setting_toggle">Show wallet</string>
<!-- Wallet (formerly Cards and passes) summary [CHAR LIMIT=NONE] -->
<string name="lockscreen_privacy_wallet_summary">Allow access to wallet from lock screen and quick settings</string>
<!-- Device controls toggle name [CHAR LIMIT=60] -->
<string name="device_controls_setting_toggle">Show device controls</string>
<!-- Cards and passes toggle name [CHAR LIMIT=60] -->
<string name="cards_passes_setting_toggle">Show cards &amp; passes</string>
<!-- Device controls toggle subtitle [CHAR LIMIT=NONE] -->
<string name="device_controls_setting_subtitle">To access controls for connected devices, hold the Power button</string>
<!-- Cards and passes toggle subtitle [CHAR LIMIT=NONE] -->
<string name="cards_passes_setting_subtitle">To access things like your payment methods and boarding passes, press and hold the Power button.</string>
<string name="lockscreen_privacy_controls_setting_toggle">Show device controls</string>
<!-- Device controls summary [CHAR LIMIT=NONE] -->
<string name="lockscreen_privacy_controls_summary">Access controls when locked</string>
<!-- Title for RTT setting. [CHAR LIMIT=NONE] -->
<string name="rtt_settings_title"></string>

View File

@@ -1,36 +0,0 @@
<?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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/cards_passes_sentence">
<com.android.settings.widget.VideoPreference
android:key="global_actions_panel_video"
app:animation="@raw/gesture_global_actions_panel"
app:controller="com.android.settings.widget.VideoPreferenceController" />
<SwitchPreference
android:key="gesture_global_actions_panel_switch"
android:title="@string/cards_passes_setting_toggle"
android:summary="@string/cards_passes_setting_subtitle"
app:keywords="@string/keywords_cards_passes"
app:controller="com.android.settings.gestures.GlobalActionsPanelPreferenceController"
app:allowDividerAbove="true" />
</PreferenceScreen>

View File

@@ -57,6 +57,7 @@
<Preference
android:key="key_user_dictionary_settings"
android:title="@string/user_dict_settings_title"
android:summary="@string/user_dict_settings_summary"
android:fragment="com.android.settings.inputmethod.UserDictionaryList"
settings:controller="com.android.settings.language.UserDictionaryPreferenceController" />
</PreferenceCategory>

View File

@@ -26,19 +26,4 @@
android:summary="@string/power_menu_long_press_for_assist_summary"
settings:controller="com.android.settings.gestures.LongPressPowerButtonPreferenceController"
/>
<Preference
android:key="gesture_global_actions_panel_summary"
android:title="@string/cards_passes_sentence"
android:fragment="com.android.settings.gestures.GlobalActionsPanelSettings"
settings:controller="com.android.settings.gestures.GlobalActionsPanelPreferenceController" />
<PreferenceCategory
android:title="@string/power_menu_lock_screen_category" >
<SwitchPreference
android:key="gesture_power_menu_privacy"
android:title="@string/power_menu_privacy"
settings:controller="com.android.settings.gestures.PowerMenuPrivacyPreferenceController" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -46,11 +46,16 @@
android:summary="@string/owner_info_settings_summary" />
<SwitchPreference
android:key="security_setting_lockdown_enabled"
android:title="@string/lockdown_settings_title"
android:summary="@string/lockdown_settings_summary"
settings:controller="com.android.settings.security.LockdownButtonPreferenceController" />
android:key="lockscreen_privacy_wallet_switch"
android:title="@string/lockscreen_privacy_wallet_setting_toggle"
android:summary="@string/lockscreen_privacy_wallet_summary"
settings:controller="com.android.settings.display.WalletPrivacyPreferenceController" />
<SwitchPreference
android:key="lockscreen_privacy_controls_switch"
android:title="@string/lockscreen_privacy_controls_setting_toggle"
android:summary="@string/lockscreen_privacy_controls_summary"
settings:controller="com.android.settings.display.ControlsPrivacyPreferenceController" />
</PreferenceCategory>
<PreferenceCategory

View File

@@ -26,6 +26,7 @@
android:key="top_level_network"
android:order="-150"
android:title="@string/network_dashboard_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.network.TopLevelNetworkEntryPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -34,6 +35,7 @@
android:key="top_level_connected_devices"
android:order="-140"
android:title="@string/connected_devices_dashboard_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.connecteddevice.TopLevelConnectedDevicesPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -41,14 +43,16 @@
android:icon="@drawable/ic_homepage_apps_v2"
android:key="top_level_apps"
android:order="-130"
android:title="@string/apps_dashboard_title"/>
android:title="@string/apps_dashboard_title"
android:summary="@string/app_and_notification_dashboard_summary"/>
<com.android.settings.homepage.HomepagePreference
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"
android:icon="@drawable/ic_homepage_notification_v2"
android:key="top_level_notification"
android:order="-120"
android:title="@string/configure_notification_settings"/>
android:title="@string/configure_notification_settings"
android:summary="@string/notification_dashboard_summary"/>
<com.android.settings.homepage.HomepagePreference
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
@@ -56,6 +60,7 @@
android:key="top_level_battery"
android:order="-110"
android:title="@string/power_usage_summary_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -64,6 +69,7 @@
android:key="top_level_storage"
android:order="-100"
android:title="@string/storage_settings"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -71,7 +77,8 @@
android:icon="@drawable/ic_homepage_sound_v2"
android:key="top_level_sound"
android:order="-90"
android:title="@string/sound_settings"/>
android:title="@string/sound_settings"
android:summary="@string/sound_dashboard_summary"/>
<com.android.settings.homepage.HomepagePreference
android:fragment="com.android.settings.DisplaySettings"
@@ -79,6 +86,7 @@
android:key="top_level_display"
android:order="-80"
android:title="@string/display_settings"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.display.TopLevelDisplayPreferenceController"/>
<com.android.settings.homepage.RestrictedHomepagePreference
@@ -86,6 +94,7 @@
android:key="top_level_wallpaper"
android:order="-70"
android:title="@string/wallpaper_settings_title"
android:summary="@string/wallpaper_dashboard_summary"
settings:controller="com.android.settings.display.TopLevelWallpaperPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -94,6 +103,7 @@
android:key="top_level_accessibility"
android:order="-60"
android:title="@string/accessibility_settings"
android:summary="@string/accessibility_settings_summary"
settings:controller="com.android.settings.accessibility.TopLevelAccessibilityPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -102,6 +112,7 @@
android:key="top_level_security"
android:order="-50"
android:title="@string/security_settings_title"
android:summary="@string/security_dashboard_summary_biometric"
settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -109,7 +120,8 @@
android:icon="@drawable/ic_homepage_privacy_v2"
android:key="top_level_privacy"
android:order="-40"
android:title="@string/privacy_dashboard_title"/>
android:title="@string/privacy_dashboard_title"
android:summary="@string/privacy_dashboard_summary"/>
<com.android.settings.homepage.HomepagePreference
android:fragment="com.android.settings.location.LocationSettings"
@@ -117,11 +129,13 @@
android:key="top_level_location"
android:order="-30"
android:title="@string/location_settings_title"
android:summary="@string/location_settings_loading_app_permission_stats"
settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
android:key="top_level_emergency"
android:title="@string/emergency_settings_preference_title"
android:summary="@string/emergency_dashboard_summary"
android:icon="@drawable/ic_homepage_emergency_v2"
android:order="-20"
android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>
@@ -132,6 +146,7 @@
android:key="top_level_accounts"
android:order="-10"
android:title="@string/account_dashboard_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -139,7 +154,8 @@
android:icon="@drawable/ic_homepage_system_dashboard_v2"
android:key="top_level_system"
android:order="10"
android:title="@string/header_category_system"/>
android:title="@string/header_category_system"
android:summary="@string/system_dashboard_summary"/>
<com.android.settings.homepage.HomepagePreference
android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
@@ -147,6 +163,7 @@
android:key="top_level_about_device"
android:order="20"
android:title="@string/about_settings"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
<com.android.settings.homepage.HomepagePreference
@@ -154,6 +171,7 @@
android:key="top_level_support"
android:order="100"
android:title="@string/page_tab_title_support"
android:summary="@string/support_summary"
settings:controller="com.android.settings.support.SupportPreferenceController"/>
</PreferenceScreen>

View File

@@ -295,9 +295,7 @@ public class Settings extends SettingsActivity {
public static class BluetoothDeviceDetailActivity extends SettingsActivity { /* empty */ }
public static class WifiCallingDisclaimerActivity extends SettingsActivity { /* empty */ }
public static class MobileNetworkListActivity extends SettingsActivity {}
public static class GlobalActionsPanelSettingsActivity extends SettingsActivity {}
public static class PowerMenuSettingsActivity extends SettingsActivity {}
public static class DeviceControlsSettingsActivity extends SettingsActivity {}
/**
* Activity for BugReportHandlerPicker.
*/

View File

@@ -1205,7 +1205,7 @@ public final class Utils extends com.android.settingslib.Utils {
public static boolean isPageTransitionEnabled(Context context) {
final boolean isSilkyHome = FeatureFlagUtils.isEnabled(context, FeatureFlags.SILKY_HOME);
final boolean isTransitionEnabled = Settings.Global.getInt(context.getContentResolver(),
SETTINGS_SHARED_AXIS_ENABLED, 0) == 1;
SETTINGS_SHARED_AXIS_ENABLED, 1) == 1;
return isSilkyHome && isTransitionEnabled;
}

View File

@@ -17,11 +17,9 @@
package com.android.settings.accounts;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
public class TopLevelAccountEntryPreferenceController extends BasePreferenceController {
public TopLevelAccountEntryPreferenceController(Context context, String preferenceKey) {
@@ -35,10 +33,6 @@ public class TopLevelAccountEntryPreferenceController extends BasePreferenceCont
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
return mContext.getString(R.string.account_dashboard_default_summary);
}
}

View File

@@ -271,7 +271,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
mIsFingerprintEnrollable = fingerprintManager.getEnrolledFingerprints(mUserId).size()
< fpProperties.get(0).maxEnrollmentsPerUser;
if (!mConfirmingCredentials && mGkPwHandle == null) {
if (!mConfirmingCredentials) {
mConfirmingCredentials = true;
if (!userHasPassword(mUserId)) {
launchChooseLock();
@@ -298,9 +298,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
private void launchChooseLock() {
Log.d(TAG, "launchChooseLock");
Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
@@ -350,8 +348,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
final Intent intent;
// If only device credential was specified, ask the user to only set that up.
intent = new Intent(this, ChooseLockGeneric.class);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
launchEnrollActivity(intent);
}

View File

@@ -222,9 +222,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
private void launchChooseLock() {
Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(getExtraKeyForBiometric(), true);
if (mUserId != UserHandle.USER_NULL) {

View File

@@ -19,7 +19,6 @@ import static android.app.Activity.RESULT_OK;
import static com.android.settings.password.ChooseLockPattern.RESULT_FINISHED;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.hardware.face.FaceManager;
@@ -193,9 +192,8 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
if (!launched) {
Intent intent = BiometricUtils.getChooseLockIntent(getActivity(), getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);

View File

@@ -37,6 +37,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.span.LinkSpan;
import com.google.android.setupdesign.template.RequireScrollMixin;
import java.util.List;
@@ -69,14 +70,18 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
.build()
);
mFooterBarMixin.setPrimaryButton(
new FooterButton.Builder(this)
.setText(R.string.security_settings_fingerprint_enroll_introduction_agree)
.setListener(this::onNextButtonClick)
.setButtonType(FooterButton.ButtonType.NEXT)
.setTheme(R.style.SudGlifButton_Primary)
.build()
);
final FooterButton nextButton = new FooterButton.Builder(this)
.setText(R.string.security_settings_fingerprint_enroll_introduction_agree)
.setListener(this::onNextButtonClick)
.setButtonType(FooterButton.ButtonType.NEXT)
.setTheme(R.style.SudGlifButton_Primary)
.build();
mFooterBarMixin.setPrimaryButton(nextButton);
final RequireScrollMixin requireScrollMixin =
getLayout().getMixin(RequireScrollMixin.class);
requireScrollMixin.requireScrollWithButton(this, nextButton,
R.string.security_settings_face_enroll_introduction_more, this::onNextButtonClick);
}
int getNegativeButtonTextId() {

View File

@@ -685,9 +685,7 @@ public class FingerprintSettings extends SubSettings {
// TODO: This should be cleaned up. ChooseLockGeneric should provide a way of
// specifying arguments/requests, instead of relying on callers setting extras.
intent.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS,
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
true);
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);

View File

@@ -17,11 +17,9 @@
package com.android.settings.connecteddevice;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
public class TopLevelConnectedDevicesPreferenceController extends BasePreferenceController {
@@ -38,11 +36,6 @@ public class TopLevelConnectedDevicesPreferenceController extends BasePreference
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
return mContext.getText(
AdvancedConnectedDeviceController.getConnectedDevicesSummaryResourceId(mContext));
}

View File

@@ -1,72 +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.
*/
package com.android.settings.core;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import android.app.Activity;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import com.android.settings.development.OverlaySettingsPreferenceController;
/**
* A mixin that adds window flag to prevent non-system overlays showing on top of Settings
* activities.
*/
public class HideNonSystemOverlayMixin implements LifecycleObserver {
private final Activity mActivity;
public HideNonSystemOverlayMixin(Activity activity) {
mActivity = activity;
}
@VisibleForTesting
boolean isEnabled() {
return !OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mActivity);
}
@OnLifecycleEvent(ON_START)
public void onStart() {
if (mActivity == null || !isEnabled()) {
return;
}
mActivity.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
android.util.EventLog.writeEvent(0x534e4554, "120484087", -1, "");
}
@OnLifecycleEvent(ON_STOP)
public void onStop() {
if (mActivity == null || !isEnabled()) {
return;
}
final Window window = mActivity.getWindow();
final WindowManager.LayoutParams attrs = window.getAttributes();
attrs.privateFlags &= ~SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
window.setAttributes(attrs);
}
}

View File

@@ -47,6 +47,7 @@ import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.dashboard.CategoryManager;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.transition.SettingsTransitionHelper;

View File

@@ -99,7 +99,6 @@ import com.android.settings.gestures.DoubleTapPowerSettings;
import com.android.settings.gestures.DoubleTapScreenSettings;
import com.android.settings.gestures.DoubleTwistGestureSettings;
import com.android.settings.gestures.GestureNavigationSettingsFragment;
import com.android.settings.gestures.GlobalActionsPanelSettings;
import com.android.settings.gestures.PickupGestureSettings;
import com.android.settings.gestures.PowerMenuSettings;
import com.android.settings.gestures.SwipeToNotificationSettings;
@@ -308,7 +307,6 @@ public class SettingsGateway {
BatterySaverScheduleSettings.class.getName(),
MobileNetworkListFragment.class.getName(),
PowerMenuSettings.class.getName(),
GlobalActionsPanelSettings.class.getName(),
DarkModeSettingsFragment.class.getName(),
BugReportHandlerPicker.class.getName(),
GestureNavigationSettingsFragment.class.getName(),

View File

@@ -261,12 +261,6 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
}
private DynamicDataObserver bindSummaryAndGetObserver(Preference preference, Tile tile) {
// Skip binding homepage tile summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)
&& TextUtils.equals(tile.getCategory(), CategoryKey.CATEGORY_HOMEPAGE)) {
return null;
}
final CharSequence summary = tile.getSummary(mContext);
if (summary != null) {
preference.setSummary(summary);

View File

@@ -16,8 +16,10 @@
package com.android.settings.development;
import static com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin.SECURE_OVERLAY_SETTINGS;
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -33,7 +35,6 @@ import com.android.settingslib.development.DeveloperOptionsPreferenceController;
public class OverlaySettingsPreferenceController extends DeveloperOptionsPreferenceController
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
public static final String SHARE_PERFS = "overlay_settings";
private static final String KEY_OVERLAY_SETTINGS = "overlay_settings";
public OverlaySettingsPreferenceController(Context context) {
@@ -64,10 +65,10 @@ public class OverlaySettingsPreferenceController extends DeveloperOptionsPrefere
/**
* Check if this setting is enabled or not.
*/
public static boolean isOverlaySettingsEnabled(Context context) {
final SharedPreferences editor = context.getSharedPreferences(SHARE_PERFS,
Context.MODE_PRIVATE);
return editor.getBoolean(SHARE_PERFS, false /* defValue */);
@VisibleForTesting
static boolean isOverlaySettingsEnabled(Context context) {
return Settings.Secure.getInt(context.getContentResolver(),
SECURE_OVERLAY_SETTINGS, 0 /* defValue */) != 0;
}
/**
@@ -75,9 +76,8 @@ public class OverlaySettingsPreferenceController extends DeveloperOptionsPrefere
*/
@VisibleForTesting
static void setOverlaySettingsEnabled(Context context, boolean enabled) {
final SharedPreferences editor = context.getSharedPreferences(SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(SHARE_PERFS, enabled).apply();
Settings.Secure.putInt(context.getContentResolver(),
SECURE_OVERLAY_SETTINGS, enabled ? 1 : 0);
}
@Override

View File

@@ -19,14 +19,12 @@ package com.android.settings.deviceinfo;
import android.content.Context;
import android.os.storage.StorageManager;
import android.text.format.Formatter;
import android.util.FeatureFlagUtils;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import com.android.settingslib.utils.ThreadUtils;
@@ -52,11 +50,6 @@ public class TopLevelStoragePreferenceController extends BasePreferenceControlle
@Override
protected void refreshSummary(Preference preference) {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return;
}
if (preference == null) {
return;
}

View File

@@ -17,10 +17,8 @@
package com.android.settings.deviceinfo.aboutphone;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
import com.android.settings.deviceinfo.DeviceNamePreferenceController;
public class TopLevelAboutDevicePreferenceController extends BasePreferenceController {
@@ -36,11 +34,6 @@ public class TopLevelAboutDevicePreferenceController extends BasePreferenceContr
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
final DeviceNamePreferenceController deviceNamePreferenceController =
new DeviceNamePreferenceController(mContext, "unused_key");
return deviceNamePreferenceController.getSummary();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 The Android Open Source Project
* Copyright (C) 2021 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.
@@ -14,9 +14,8 @@
* limitations under the License.
*/
package com.android.settings.gestures;
package com.android.settings.display;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
@@ -29,16 +28,14 @@ import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
public class PowerMenuPrivacyPreferenceController extends TogglePreferenceController {
/**
* Preference for showing/hiding sensitive device controls content while the device is locked.
*/
public class ControlsPrivacyPreferenceController extends TogglePreferenceController {
private static final String SETTING_KEY = Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT;
private static final String CARDS_AVAILABLE_KEY =
Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
private static final String CARDS_ENABLED_KEY = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
private static final String SETTING_KEY = "lockscreen_show_controls";
public PowerMenuPrivacyPreferenceController(Context context,
String preferenceKey) {
public ControlsPrivacyPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@@ -55,22 +52,12 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro
@Override
public CharSequence getSummary() {
boolean cardsAvailable = Settings.Secure.getInt(mContext.getContentResolver(),
CARDS_AVAILABLE_KEY, 0) != 0;
boolean controlsAvailable = isControlsAvailable();
final int res;
if (!isSecure()) {
res = R.string.power_menu_privacy_not_secure;
} else if (cardsAvailable && controlsAvailable) {
res = R.string.power_menu_privacy_show;
} else if (!cardsAvailable && controlsAvailable) {
res = R.string.power_menu_privacy_show_controls;
} else if (cardsAvailable) {
res = R.string.power_menu_privacy_show_cards;
res = R.string.lockscreen_privacy_not_secure;
} else {
// In this case, neither cards nor controls are available. This preference should not
// be accessible as the power menu setting is not accessible
return "";
res = R.string.lockscreen_privacy_controls_summary;
}
return mContext.getText(res);
}
@@ -78,7 +65,6 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro
@Override
public int getAvailabilityStatus() {
// hide if lockscreen isn't secure for this user
return isEnabled() && isSecure() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
}
@@ -90,10 +76,7 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro
}
private boolean isEnabled() {
final ContentResolver resolver = mContext.getContentResolver();
boolean cardsAvailable = Settings.Secure.getInt(resolver, CARDS_AVAILABLE_KEY, 0) != 0;
boolean cardsEnabled = Settings.Secure.getInt(resolver, CARDS_ENABLED_KEY, 0) != 0;
return (cardsAvailable && cardsEnabled) || isControlsAvailable();
return isControlsAvailable();
}
private boolean isSecure() {

View File

@@ -17,11 +17,9 @@
package com.android.settings.display;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
public class TopLevelDisplayPreferenceController extends BasePreferenceController {
@@ -38,11 +36,6 @@ public class TopLevelDisplayPreferenceController extends BasePreferenceControlle
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
final WallpaperPreferenceController controller =
new WallpaperPreferenceController(mContext, "unused_key");
if (controller.isAvailable()) {

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2021 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.display;
import android.content.Context;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
/**
* Preference for showing/hiding sensitive wallet content while the device is locked.
*/
public class WalletPrivacyPreferenceController extends TogglePreferenceController {
private static final String SETTING_KEY = "lockscreen_show_wallet";
private final QuickAccessWalletClient mClient;
public WalletPrivacyPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mClient = initWalletClient();
}
@Override
public boolean isChecked() {
return Settings.Secure.getInt(mContext.getContentResolver(), SETTING_KEY, 0) != 0;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putInt(mContext.getContentResolver(), SETTING_KEY,
isChecked ? 1 : 0);
}
@Override
public CharSequence getSummary() {
final int res;
if (!isSecure()) {
res = R.string.lockscreen_privacy_not_secure;
} else {
res = R.string.lockscreen_privacy_wallet_summary;
}
return mContext.getText(res);
}
@Override
public int getAvailabilityStatus() {
return isEnabled() && isSecure() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
preference.setEnabled(getAvailabilityStatus() != DISABLED_DEPENDENT_SETTING);
refreshSummary(preference);
}
private boolean isEnabled() {
return mClient.isWalletServiceAvailable();
}
private boolean isSecure() {
final LockPatternUtils utils = FeatureFactory.getFactory(mContext)
.getSecurityFeatureProvider()
.getLockPatternUtils(mContext);
int userId = UserHandle.myUserId();
return utils.isSecure(userId);
}
@VisibleForTesting
QuickAccessWalletClient initWalletClient() {
return QuickAccessWalletClient.create(mContext);
}
}

View File

@@ -53,8 +53,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnDestroy,
BatteryChartView.OnSelectListener, ExpandDividerPreference.OnExpandListener {
private static final String TAG = "BatteryChartPreferenceController";
private static final int CHART_KEY_ARRAY_SIZE = 25;
/** Desired battery history size for timestamp slots. */
public static final int DESIRED_HISTORY_SIZE = 25;
private static final int CHART_LEVEL_ARRAY_SIZE = 13;
private static final int CHART_KEY_ARRAY_SIZE = DESIRED_HISTORY_SIZE;
private static final long VALID_USAGE_TIME_DURATION = DateUtils.HOUR_IN_MILLIS * 2;
private static final long VALID_DIFF_DURATION = DateUtils.MINUTE_IN_MILLIS * 3;
@@ -176,51 +178,52 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
}
void setBatteryHistoryMap(
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
}
private void setBatteryHistoryMapInner(
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
// Resets all battery history data relative variables.
if (batteryHistoryMap == null) {
if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
mBatteryIndexedMap = null;
mBatteryHistoryKeys = null;
mBatteryHistoryLevels = null;
return;
}
// Generates battery history keys.
// Generates battery history timestamp slots.
final List<Long> batteryHistoryKeyList =
new ArrayList<Long>(batteryHistoryMap.keySet());
new ArrayList<>(batteryHistoryMap.keySet());
Collections.sort(batteryHistoryKeyList);
validateSlotTimestamp(batteryHistoryKeyList);
mBatteryHistoryKeys = new long[CHART_KEY_ARRAY_SIZE];
final int listSize = batteryHistoryKeyList.size();
final int elementSize = Math.min(listSize, CHART_KEY_ARRAY_SIZE);
for (int index = 0; index < elementSize; index++) {
mBatteryHistoryKeys[CHART_KEY_ARRAY_SIZE - index - 1] =
batteryHistoryKeyList.get(listSize - index - 1);
for (int index = 0; index < CHART_KEY_ARRAY_SIZE; index++) {
mBatteryHistoryKeys[index] = batteryHistoryKeyList.get(index);
}
// Generates the battery history levels.
// Generates the battery history levels for chart graph.
mBatteryHistoryLevels = new int[CHART_LEVEL_ARRAY_SIZE];
for (int index = 0; index < CHART_LEVEL_ARRAY_SIZE; index++) {
final Long timestamp = Long.valueOf(mBatteryHistoryKeys[index * 2]);
final List<BatteryHistEntry> entryList = batteryHistoryMap.get(timestamp);
if (entryList != null && !entryList.isEmpty()) {
// All battery levels are the same in the same timestamp snapshot.
mBatteryHistoryLevels[index] = entryList.get(0).mBatteryLevel;
} else if (entryList != null && entryList.isEmpty()) {
Log.e(TAG, "abnormal entry list in the timestamp:" +
ConvertUtils.utcToLocalTime(timestamp));
final long timestamp = mBatteryHistoryKeys[index * 2];
final Map<String, BatteryHistEntry> entryMap = batteryHistoryMap.get(timestamp);
if (entryMap == null || entryMap.isEmpty()) {
Log.e(TAG, "abnormal entry list in the timestamp:"
+ ConvertUtils.utcToLocalTime(timestamp));
continue;
}
// Averages the battery level in each time slot to avoid corner conditions.
float batteryLevelCounter = 0;
for (BatteryHistEntry entry : entryMap.values()) {
batteryLevelCounter += entry.mBatteryLevel;
}
mBatteryHistoryLevels[index] =
Math.round(batteryLevelCounter / entryMap.size());
}
// Generates indexed usage map for chart.
mBatteryIndexedMap =
ConvertUtils.getIndexedUsageMap(
mPrefContext, /*timeSlotSize=*/ CHART_LEVEL_ARRAY_SIZE - 1,
mBatteryHistoryKeys, batteryHistoryMap,
/*purgeLowPercentageData=*/ true);
/*purgeLowPercentageAndFakeData=*/ true);
forceRefreshUi();
Log.d(TAG, String.format(
@@ -532,25 +535,4 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
}
return true;
}
@VisibleForTesting
static boolean validateSlotTimestamp(List<Long> batteryHistoryKeys) {
// Whether the nearest two slot time diff is valid or not?
final int size = batteryHistoryKeys.size();
for (int index = 0; index < size - 1; index++) {
final long currentTime = batteryHistoryKeys.get(index);
final long nextTime = batteryHistoryKeys.get(index + 1);
final long diffTime = Math.abs(
DateUtils.HOUR_IN_MILLIS - Math.abs(currentTime - nextTime));
if (currentTime == 0) {
continue;
} else if (diffTime > VALID_DIFF_DURATION) {
Log.e(TAG, String.format("validateSlotTimestamp() %s > %s",
ConvertUtils.utcToLocalTime(currentTime),
ConvertUtils.utcToLocalTime(nextTime)));
return false;
}
}
return true;
}
}

View File

@@ -20,12 +20,11 @@ import android.content.Context;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.utils.AsyncLoaderCompat;
import java.util.List;
import java.util.Map;
/** Loader that can be used to load battery history information. */
public class BatteryHistoryLoader
extends AsyncLoaderCompat<Map<Long, List<BatteryHistEntry>>> {
extends AsyncLoaderCompat<Map<Long, Map<String, BatteryHistEntry>>> {
private static final String TAG = "BatteryHistoryLoader";
private final Context mContext;
@@ -36,11 +35,11 @@ public class BatteryHistoryLoader
}
@Override
protected void onDiscardResult(Map<Long, List<BatteryHistEntry>> result) {
protected void onDiscardResult(Map<Long, Map<String, BatteryHistEntry>> result) {
}
@Override
public Map<Long, List<BatteryHistEntry>> loadInBackground() {
public Map<Long, Map<String, BatteryHistEntry>> loadInBackground() {
final PowerUsageFeatureProvider powerUsageFeatureProvider =
FeatureFactory.getFactory(mContext).getPowerUsageFeatureProvider(mContext);
return powerUsageFeatureProvider.getBatteryHistory(mContext);

View File

@@ -18,12 +18,15 @@ import android.content.ContentValues;
import android.content.Context;
import android.os.BatteryUsageStats;
import android.os.UserHandle;
import android.text.format.DateUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -41,6 +44,8 @@ public final class ConvertUtils {
private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new HashMap<>();
private static final BatteryHistEntry EMPTY_BATTERY_HIST_ENTRY =
new BatteryHistEntry(new ContentValues());
// Maximum total time value for each slot cumulative data at most 2 hours.
private static final float TOTAL_TIME_THRESHOLD = DateUtils.HOUR_IN_MILLIS * 2;
@VisibleForTesting
static double PERCENTAGE_OF_TOTAL_THRESHOLD = 1f;
@@ -144,30 +149,12 @@ public final class ConvertUtils {
final Context context,
final int timeSlotSize,
final long[] batteryHistoryKeys,
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap,
final boolean purgeLowPercentageData) {
final Map<Integer, List<BatteryDiffEntry>> resultMap = new HashMap<>();
// Generates a temporary map to calculate diff usage data, which converts the inputted
// List<BatteryDiffEntry> into Map<String, BatteryHistEntry> with the key comes from
// the BatteryHistEntry.getKey() method.
final Map<Long, Map<String, BatteryHistEntry>> newBatteryHistoryMap = new HashMap<>();
for (int index = 0; index < batteryHistoryKeys.length; index++) {
final Long timestamp = Long.valueOf(batteryHistoryKeys[index]);
final List<BatteryHistEntry> entries = batteryHistoryMap.get(timestamp);
if (entries == null || entries.isEmpty()) {
continue;
}
final Map<String, BatteryHistEntry> slotBatteryHistDataMap = new HashMap<>();
for (BatteryHistEntry entry : entries) {
// Excludes auto-generated fake BatteryHistEntry data,
// which is used to record battery level and status purpose only.
if (!FAKE_PACKAGE_NAME.equals(entry.mPackageName)) {
slotBatteryHistDataMap.put(entry.getKey(), entry);
}
}
newBatteryHistoryMap.put(timestamp, slotBatteryHistDataMap);
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
final boolean purgeLowPercentageAndFakeData) {
if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
return new HashMap<>();
}
final Map<Integer, List<BatteryDiffEntry>> resultMap = new HashMap<>();
// Each time slot usage diff data =
// Math.abs(timestamp[i+2] data - timestamp[i+1] data) +
// Math.abs(timestamp[i+1] data - timestamp[i] data);
@@ -176,25 +163,28 @@ public final class ConvertUtils {
for (int index = 0; index < timeSlotSize; index++) {
final Long currentTimestamp =
Long.valueOf(batteryHistoryKeys[index * timestampStride]);
// Uses empty list if the timestamp is default value.
if (currentTimestamp == 0) {
resultMap.put(Integer.valueOf(index), new ArrayList<BatteryDiffEntry>());
continue;
}
final Long nextTimestamp =
Long.valueOf(batteryHistoryKeys[index * timestampStride + 1]);
final Long nextTwoTimestamp =
Long.valueOf(batteryHistoryKeys[index * timestampStride + 2]);
// Fetches BatteryHistEntry data from corresponding time slot.
final Map<String, BatteryHistEntry> currentBatteryHistMap =
newBatteryHistoryMap.getOrDefault(currentTimestamp, EMPTY_BATTERY_MAP);
batteryHistoryMap.getOrDefault(currentTimestamp, EMPTY_BATTERY_MAP);
final Map<String, BatteryHistEntry> nextBatteryHistMap =
newBatteryHistoryMap.getOrDefault(nextTimestamp, EMPTY_BATTERY_MAP);
batteryHistoryMap.getOrDefault(nextTimestamp, EMPTY_BATTERY_MAP);
final Map<String, BatteryHistEntry> nextTwoBatteryHistMap =
newBatteryHistoryMap.getOrDefault(nextTwoTimestamp, EMPTY_BATTERY_MAP);
batteryHistoryMap.getOrDefault(nextTwoTimestamp, EMPTY_BATTERY_MAP);
// We should not get the empty list since we have at least one fake data to record
// the battery level and status in each time slot, the empty list is used to
// represent there is no enough data to apply interpolation arithmetic.
if (currentBatteryHistMap.isEmpty()
|| nextBatteryHistMap.isEmpty()
|| nextTwoBatteryHistMap.isEmpty()) {
resultMap.put(Integer.valueOf(index), new ArrayList<BatteryDiffEntry>());
continue;
}
// Collects all keys in these three time slot records as population.
// Collects all keys in these three time slot records as all populations.
final Set<String> allBatteryHistEntryKeys = new HashSet<>();
allBatteryHistEntryKeys.addAll(currentBatteryHistMap.keySet());
allBatteryHistEntryKeys.addAll(nextBatteryHistMap.keySet());
@@ -214,12 +204,12 @@ public final class ConvertUtils {
final BatteryHistEntry nextTwoEntry =
nextTwoBatteryHistMap.getOrDefault(key, EMPTY_BATTERY_HIST_ENTRY);
// Cumulative values is a specific time slot for a specific app.
final long foregroundUsageTimeInMs =
long foregroundUsageTimeInMs =
getDiffValue(
currentEntry.mForegroundUsageTimeInMs,
nextEntry.mForegroundUsageTimeInMs,
nextTwoEntry.mForegroundUsageTimeInMs);
final long backgroundUsageTimeInMs =
long backgroundUsageTimeInMs =
getDiffValue(
currentEntry.mBackgroundUsageTimeInMs,
nextEntry.mBackgroundUsageTimeInMs,
@@ -233,8 +223,8 @@ public final class ConvertUtils {
// Excludes entry since we don't have enough data to calculate.
if (foregroundUsageTimeInMs == 0
&& backgroundUsageTimeInMs == 0
&& consumePower == 0) {
&& backgroundUsageTimeInMs == 0
&& consumePower == 0) {
continue;
}
final BatteryHistEntry selectedBatteryEntry =
@@ -242,6 +232,21 @@ public final class ConvertUtils {
if (selectedBatteryEntry == null) {
continue;
}
// Force refine the cumulative value since it may introduce deviation
// error since we will apply the interpolation arithmetic.
final float totalUsageTimeInMs =
foregroundUsageTimeInMs + backgroundUsageTimeInMs;
if (totalUsageTimeInMs > TOTAL_TIME_THRESHOLD) {
final float ratio = TOTAL_TIME_THRESHOLD / totalUsageTimeInMs;
Log.w(TAG, String.format("abnormal usage time %d|%d for:\n%s",
Duration.ofMillis(foregroundUsageTimeInMs).getSeconds(),
Duration.ofMillis(backgroundUsageTimeInMs).getSeconds(),
currentEntry));
foregroundUsageTimeInMs =
Math.round(foregroundUsageTimeInMs * ratio);
backgroundUsageTimeInMs =
Math.round(backgroundUsageTimeInMs * ratio);
}
batteryDiffEntryList.add(
new BatteryDiffEntry(
context,
@@ -255,10 +260,10 @@ public final class ConvertUtils {
diffEntry.setTotalConsumePower(totalConsumePower);
}
}
insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
if (purgeLowPercentageData) {
purgeLowPercentageData(resultMap);
if (purgeLowPercentageAndFakeData) {
purgeLowPercentageAndFakeData(resultMap);
}
insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
return resultMap;
}
@@ -294,13 +299,15 @@ public final class ConvertUtils {
indexedUsageMap.put(Integer.valueOf(desiredIndex), resultList);
}
private static void purgeLowPercentageData(
// Removes low percentage data and fake usage data, which will be zero value.
private static void purgeLowPercentageAndFakeData(
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
for (List<BatteryDiffEntry> entries : indexedUsageMap.values()) {
final Iterator<BatteryDiffEntry> iterator = entries.iterator();
while (iterator.hasNext()) {
final BatteryDiffEntry entry = iterator.next();
if (entry.getPercentOfTotal() < PERCENTAGE_OF_TOTAL_THRESHOLD) {
if (entry.getPercentOfTotal() < PERCENTAGE_OF_TOTAL_THRESHOLD
|| FAKE_PACKAGE_NAME.equals(entry.getPackageName())) {
iterator.remove();
}
}

View File

@@ -52,7 +52,7 @@ public class PowerUsageAdvanced extends PowerUsageBase {
@VisibleForTesting
BatteryHistoryPreference mHistPref;
@VisibleForTesting
Map<Long, List<BatteryHistEntry>> mBatteryHistoryMap;
Map<Long, Map<String, BatteryHistEntry>> mBatteryHistoryMap;
@VisibleForTesting
final BatteryHistoryLoaderCallbacks mBatteryHistoryLoaderCallbacks =
new BatteryHistoryLoaderCallbacks();
@@ -210,25 +210,26 @@ public class PowerUsageAdvanced extends PowerUsageBase {
};
private class BatteryHistoryLoaderCallbacks
implements LoaderManager.LoaderCallbacks<Map<Long, List<BatteryHistEntry>>> {
implements LoaderManager.LoaderCallbacks<Map<Long, Map<String, BatteryHistEntry>>> {
private int mRefreshType;
@Override
@NonNull
public Loader<Map<Long, List<BatteryHistEntry>>> onCreateLoader(int id, Bundle bundle) {
public Loader<Map<Long, Map<String, BatteryHistEntry>>> onCreateLoader(
int id, Bundle bundle) {
mRefreshType = bundle.getInt(KEY_REFRESH_TYPE);
return new BatteryHistoryLoader(getContext());
}
@Override
public void onLoadFinished(Loader<Map<Long, List<BatteryHistEntry>>> loader,
Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
public void onLoadFinished(Loader<Map<Long, Map<String, BatteryHistEntry>>> loader,
Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
mBatteryHistoryMap = batteryHistoryMap;
PowerUsageAdvanced.this.onLoadFinished(mRefreshType);
}
@Override
public void onLoaderReset(Loader<Map<Long, List<BatteryHistEntry>>> loader) {
public void onLoaderReset(Loader<Map<Long, Map<String, BatteryHistEntry>>> loader) {
}
}

View File

@@ -23,7 +23,6 @@ import android.util.SparseIntArray;
import com.android.internal.os.BatterySipper;
import com.android.settingslib.fuelgauge.Estimate;
import java.util.List;
import java.util.Map;
/**
@@ -136,5 +135,5 @@ public interface PowerUsageFeatureProvider {
/**
* Returns battery history data with corresponding timestamp key.
*/
Map<Long, List<BatteryHistEntry>> getBatteryHistory(Context context);
Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context);
}

View File

@@ -26,7 +26,6 @@ import com.android.internal.os.BatterySipper;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.fuelgauge.Estimate;
import java.util.List;
import java.util.Map;
public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider {
@@ -160,7 +159,7 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
}
@Override
public Map<Long, List<BatteryHistEntry>> getBatteryHistory(Context context) {
public Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context) {
return null;
}
}

View File

@@ -17,7 +17,6 @@
package com.android.settings.fuelgauge;
import android.content.Context;
import android.util.FeatureFlagUtils;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -25,7 +24,6 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -87,10 +85,6 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle
}
private CharSequence getSummary(boolean batteryStatusUpdate) {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
// Display help message if battery is not present.
if (!mIsBatteryPresent) {
return mContext.getText(R.string.battery_missing_message);

View File

@@ -1,48 +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
*/
package com.android.settings.gestures;
import android.app.settings.SettingsEnums;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
@SearchIndexable
public class GlobalActionsPanelSettings extends DashboardFragment {
private static final String TAG = "GlobalActionsPanelSettings";
@Override
public int getMetricsCategory() {
return SettingsEnums.GLOBAL_ACTIONS_PANEL_SETTINGS;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.global_actions_panel_settings;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.global_actions_panel_settings);
}

View File

@@ -17,44 +17,24 @@
package com.android.settings.gestures;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
public class PowerMenuPreferenceController extends BasePreferenceController {
private static final String KEY = "gesture_power_menu_summary";
private static final String CARDS_ENABLED_SETTING =
Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
private static final String CARDS_AVAILABLE_SETTING =
Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
public PowerMenuPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public CharSequence getSummary() {
boolean cardsVisible = isCardsAvailable()
&& Settings.Secure.getInt(mContext.getContentResolver(),
CARDS_ENABLED_SETTING, 0) == 1;
if (cardsVisible) {
return mContext.getText(R.string.power_menu_cards_passes);
} else {
return mContext.getText(R.string.power_menu_none);
}
return mContext.getText(R.string.power_menu_long_press_for_assist);
}
@Override
public int getAvailabilityStatus() {
return isCardsAvailable() || isAssistInvocationAvailable()
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
private boolean isCardsAvailable() {
return Settings.Secure.getInt(mContext.getContentResolver(),
CARDS_AVAILABLE_SETTING, 0) == 1;
return isAssistInvocationAvailable() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
private boolean isAssistInvocationAvailable() {

View File

@@ -39,9 +39,9 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.accounts.AvatarViewMixin;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
import com.android.settingslib.transition.SettingsTransitionHelper;
public class SettingsHomepageActivity extends FragmentActivity {

View File

@@ -11,7 +11,6 @@ import android.location.LocationManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionControllerManager;
import android.util.FeatureFlagUtils;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -19,7 +18,6 @@ import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -52,11 +50,6 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
if (mLocationManager.isLocationEnabled()) {
if (mNumTotal == -1) {
return mContext.getString(R.string.location_settings_loading_app_permission_stats);

View File

@@ -20,12 +20,10 @@ import android.content.Context;
import android.icu.text.ListFormatter;
import android.text.BidiFormatter;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
import com.android.settings.wifi.WifiPrimarySwitchPreferenceController;
import java.util.ArrayList;
@@ -53,11 +51,6 @@ public class TopLevelNetworkEntryPreferenceController extends BasePreferenceCont
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
final String wifiSummary = BidiFormatter.getInstance()
.unicodeWrap(mContext.getString(R.string.wifi_settings_title));
final String mobileSummary = mContext.getString(

View File

@@ -31,10 +31,9 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
/**
* Dialog Activity to host channel settings

View File

@@ -35,7 +35,7 @@ import androidx.fragment.app.FragmentManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
/**
* Dialog Activity to host Settings Slices.

View File

@@ -75,8 +75,6 @@ import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -112,8 +110,7 @@ public class ChooseLockGeneric extends SettingsActivity {
private static final String KEY_SKIP_BIOMETRICS = "unlock_skip_biometrics";
private static final String PASSWORD_CONFIRMED = "password_confirmed";
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs";
public static final String HIDE_INSECURE_OPTIONS = "hide_insecure_options";
public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
public static final String KEY_LOCK_SETTINGS_FOOTER ="lock_settings_footer";
@@ -277,21 +274,20 @@ public class ChooseLockGeneric extends SettingsActivity {
arguments,
intent.getExtras()).getIdentifier();
mIsManagedProfile = UserManager.get(getActivity()).isManagedProfile(mUserId);
mController = new ChooseLockGenericController(
getContext(), mUserId, mRequestedMinComplexity,
mOnlyEnforceDevicePasswordRequirement,
mLockPatternUtils);
final int aggregatedComplexity = mController.getAggregatedPasswordComplexity();
final boolean isComplexityProvidedByAdmin =
aggregatedComplexity > mRequestedMinComplexity
&& aggregatedComplexity > PASSWORD_COMPLEXITY_NONE;
mController = new ChooseLockGenericController.Builder(
getContext(), mUserId, mLockPatternUtils)
.setAppRequestedMinComplexity(mRequestedMinComplexity)
.setEnforceDevicePasswordRequirementOnly(mOnlyEnforceDevicePasswordRequirement)
.setProfileToUnify(mUnificationProfileId)
.setHideInsecureScreenLockTypes(alwaysHideInsecureScreenLockTypes()
|| intent.getBooleanExtra(HIDE_INSECURE_OPTIONS, false))
.build();
// If the complexity is provided by the admin, do not get the caller app's name.
// If the app requires, for example, low complexity, and the admin requires high
// complexity, it does not make sense to show a footer telling the user it's the app
// requesting a particular complexity because the admin-set complexity will override it.
mCallerAppName = isComplexityProvidedByAdmin ? null :
mCallerAppName = mController.isComplexityProvidedByAdmin() ? null :
intent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME);
mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, mUserId);
@@ -330,6 +326,10 @@ public class ChooseLockGeneric extends SettingsActivity {
return super.onCreateView(inflater, container, savedInstanceState);
}
protected boolean alwaysHideInsecureScreenLockTypes() {
return false;
}
private void updateActivityTitle() {
if (mLockPatternUtils == null) {
// mLockPatternUtils will be uninitialized if ChooseLockGenericFragment.onCreate()
@@ -606,16 +606,12 @@ public class ChooseLockGeneric extends SettingsActivity {
}
if (quality == -1) {
// If caller didn't specify password quality, show UI and allow the user to choose.
quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
quality = mController.upgradeQuality(quality);
final boolean hideDisabledPrefs = intent.getBooleanExtra(
HIDE_DISABLED_PREFS, false);
final PreferenceScreen prefScreen = getPreferenceScreen();
if (prefScreen != null) {
prefScreen.removeAll();
}
addPreferences();
disableUnusablePreferences(quality, hideDisabledPrefs);
disableUnusablePreferences();
updatePreferenceText();
updateCurrentPreference();
updatePreferenceSummaryIfNeeded();
@@ -746,71 +742,23 @@ public class ChooseLockGeneric extends SettingsActivity {
return lock != null ? lock.preferenceKey : null;
}
/***
* Disables preferences that are less secure than required quality. The actual
* implementation is in disableUnusablePreferenceImpl.
*
* @param quality the requested quality.
* @param hideDisabledPrefs if false preferences show why they were disabled; otherwise
* they're not shown at all.
*/
protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) {
disableUnusablePreferencesImpl(quality, hideDisabledPrefs);
}
/***
* Disables preferences that are less secure than required quality.
*
* @param quality the requested quality.
* @param hideDisabled whether to hide disable screen lock options.
*/
protected void disableUnusablePreferencesImpl(final int quality,
boolean hideDisabled) {
private void disableUnusablePreferences() {
final PreferenceScreen entries = getPreferenceScreen();
int adminEnforcedQuality = LockPatternUtils.credentialTypeToPasswordQuality(
mLockPatternUtils.getRequestedPasswordMetrics(
mUserId, mOnlyEnforceDevicePasswordRequirement).credType);
EnforcedAdmin enforcedAdmin =
RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(getActivity(),
mUserId);
// If we are to unify a work challenge at the end of the credential enrollment, manually
// merge any password policy from that profile here, so we are enrolling a compliant
// password. This is because once unified, the profile's password policy will
// be enforced on the new credential.
if (mUnificationProfileId != UserHandle.USER_NULL) {
int profileEnforceQuality = mDpm.getPasswordQuality(null, mUnificationProfileId);
if (profileEnforceQuality > adminEnforcedQuality) {
adminEnforcedQuality = profileEnforceQuality;
enforcedAdmin = EnforcedAdmin.combine(enforcedAdmin,
RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(
getActivity(), mUnificationProfileId));
}
}
for (ScreenLockType lock : ScreenLockType.values()) {
String key = lock.preferenceKey;
Preference pref = findPreference(key);
if (pref instanceof RestrictedPreference) {
boolean visible = mController.isScreenLockVisible(lock);
boolean enabled = mController.isScreenLockEnabled(lock, quality);
boolean disabledByAdmin =
mController.isScreenLockDisabledByAdmin(lock, adminEnforcedQuality);
if (hideDisabled) {
visible = visible && enabled;
}
boolean enabled = mController.isScreenLockEnabled(lock);
if (!visible) {
entries.removePreference(pref);
} else if (disabledByAdmin && enforcedAdmin != null) {
((RestrictedPreference) pref).setDisabledByAdmin(enforcedAdmin);
} else if (!enabled) {
// we need to setDisabledByAdmin to null first to disable the padlock
// in case it was set earlier.
((RestrictedPreference) pref).setDisabledByAdmin(null);
pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
pref.setEnabled(false);
} else {
((RestrictedPreference) pref).setDisabledByAdmin(null);
}
}
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
@@ -24,6 +25,7 @@ import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordMetrics;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -36,84 +38,140 @@ import java.util.List;
/**
* A controller for ChooseLockGeneric, and other similar classes which shows a list of possible
* screen locks for the user to choose from.
* screen lock types for the user to choose from. This is the main place where different
* restrictions on allowed screen lock types are aggregated in Settings.
*
* Each screen lock type has two states: whether it is visible and whether it is enabled.
* Visibility is affected by things like resource configs, whether it's for a managed profile,
* or whether the caller allows it or not. This is determined by
* {@link #isScreenLockVisible(ScreenLockType)}. For visible screen lock types, they can be disabled
* by a combination of admin policies and request from the calling app, which is determined by
* {@link #isScreenLockEnabled(ScreenLockType}.
*/
public class ChooseLockGenericController {
private final Context mContext;
private final int mUserId;
@PasswordComplexity private final int mRequestedMinComplexity;
private final boolean mHideInsecureScreenLockTypes;
@PasswordComplexity private final int mAppRequestedMinComplexity;
private final boolean mDevicePasswordRequirementOnly;
private ManagedLockPasswordProvider mManagedPasswordProvider;
private final int mUnificationProfileId;
private final ManagedLockPasswordProvider mManagedPasswordProvider;
private final LockPatternUtils mLockPatternUtils;
public ChooseLockGenericController(Context context, int userId) {
this(
context,
userId,
PASSWORD_COMPLEXITY_NONE,
/* mOnlyEnforceDevicePasswordRequirement */ false,
new LockPatternUtils(context));
}
/**
* @param requestedMinComplexity specifies the min password complexity to be taken into account
* when determining the available screen lock types
*/
public ChooseLockGenericController(Context context, int userId,
@PasswordComplexity int requestedMinComplexity,
boolean devicePasswordRequirementOnly,
LockPatternUtils lockPatternUtils) {
this(
context,
userId,
requestedMinComplexity,
devicePasswordRequirementOnly,
ManagedLockPasswordProvider.get(context, userId),
lockPatternUtils);
}
@VisibleForTesting
ChooseLockGenericController(
Context context,
int userId,
@PasswordComplexity int requestedMinComplexity,
boolean devicePasswordRequirementOnly,
ManagedLockPasswordProvider managedLockPasswordProvider,
LockPatternUtils lockPatternUtils) {
ManagedLockPasswordProvider managedPasswordProvider, LockPatternUtils lockPatternUtils,
boolean hideInsecureScreenLockTypes, int appRequestedMinComplexity,
boolean devicePasswordRequirementOnly, int unificationProfileId) {
mContext = context;
mUserId = userId;
mRequestedMinComplexity = requestedMinComplexity;
mDevicePasswordRequirementOnly = devicePasswordRequirementOnly;
mManagedPasswordProvider = managedLockPasswordProvider;
mManagedPasswordProvider = managedPasswordProvider;
mLockPatternUtils = lockPatternUtils;
mHideInsecureScreenLockTypes = hideInsecureScreenLockTypes;
mAppRequestedMinComplexity = appRequestedMinComplexity;
mDevicePasswordRequirementOnly = devicePasswordRequirementOnly;
mUnificationProfileId = unificationProfileId;
}
/** Builder class for {@link ChooseLockGenericController} */
public static class Builder {
private final Context mContext;
private final int mUserId;
private final ManagedLockPasswordProvider mManagedPasswordProvider;
private final LockPatternUtils mLockPatternUtils;
private boolean mHideInsecureScreenLockTypes = false;
@PasswordComplexity private int mAppRequestedMinComplexity = PASSWORD_COMPLEXITY_NONE;
private boolean mDevicePasswordRequirementOnly = false;
private int mUnificationProfileId = UserHandle.USER_NULL;
public Builder(Context context, int userId) {
this(context, userId, new LockPatternUtils(context));
}
public Builder(Context context, int userId,
LockPatternUtils lockPatternUtils) {
this(
context,
userId,
ManagedLockPasswordProvider.get(context, userId),
lockPatternUtils);
}
@VisibleForTesting
Builder(
Context context,
int userId,
ManagedLockPasswordProvider managedLockPasswordProvider,
LockPatternUtils lockPatternUtils) {
mContext = context;
mUserId = userId;
mManagedPasswordProvider = managedLockPasswordProvider;
mLockPatternUtils = lockPatternUtils;
}
/**
* Sets the password complexity requested by the calling app via
* {@link android.app.admin.DevicePolicyManager#EXTRA_PASSWORD_COMPLEXITY}.
*/
public Builder setAppRequestedMinComplexity(int complexity) {
mAppRequestedMinComplexity = complexity;
return this;
}
/**
* Sets whether the enrolment flow should discard any password policies originating from the
* work profile, even if the work profile currently has unified challenge. This can be
* requested by the calling app via
* {@link android.app.admin.DevicePolicyManager#EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY}.
*/
public Builder setEnforceDevicePasswordRequirementOnly(boolean deviceOnly) {
mDevicePasswordRequirementOnly = deviceOnly;
return this;
}
/**
* Sets the user ID of any profile whose work challenge should be unified at the end of this
* enrolment flow. This will lead to all password policies from that profile to be taken
* into consideration by this class, so that we are enrolling a compliant password. This is
* because once unified, the profile's password policy will be enforced on the new
* credential.
*/
public Builder setProfileToUnify(int profileId) {
mUnificationProfileId = profileId;
return this;
}
/**
* Sets whether insecure screen lock types (NONE and SWIPE) should be hidden in the UI.
*/
public Builder setHideInsecureScreenLockTypes(boolean hide) {
mHideInsecureScreenLockTypes = hide;
return this;
}
/** Creates {@link ChooseLockGenericController} instance. */
public ChooseLockGenericController build() {
return new ChooseLockGenericController(mContext, mUserId, mManagedPasswordProvider,
mLockPatternUtils, mHideInsecureScreenLockTypes, mAppRequestedMinComplexity,
mDevicePasswordRequirementOnly, mUnificationProfileId);
}
}
/**
* Returns the highest quality among the specified {@code quality}, the password requirement
* set by device admins (legacy password quality metrics and password complexity), and the
* min password complexity requested by the calling app.
*/
public int upgradeQuality(int quality) {
// Compare specified quality and dpm quality
// TODO(b/142781408): convert from quality to credential type once PIN is supported.
int dpmUpgradedQuality = Math.max(quality, LockPatternUtils.credentialTypeToPasswordQuality(
getAggregatedPasswordMetrics().credType));
return Math.max(dpmUpgradedQuality,
PasswordMetrics.complexityLevelToMinQuality(getAggregatedPasswordComplexity()));
}
/**
* Whether the given screen lock type should be visible in the given context.
* Returns whether the given screen lock type should be visible in the given context.
*/
public boolean isScreenLockVisible(ScreenLockType type) {
final boolean managedProfile = mUserId != UserHandle.myUserId();
final boolean managedProfile = mContext.getSystemService(UserManager.class)
.isManagedProfile(mUserId);
switch (type) {
case NONE:
return !mContext.getResources().getBoolean(R.bool.config_hide_none_security_option)
return !mHideInsecureScreenLockTypes
&& !mContext.getResources().getBoolean(R.bool.config_hide_none_security_option)
&& !managedProfile; // Profiles should use unified challenge instead.
case SWIPE:
return !mContext.getResources().getBoolean(R.bool.config_hide_swipe_security_option)
return !mHideInsecureScreenLockTypes
&& !mContext.getResources().getBoolean(R.bool.config_hide_swipe_security_option)
&& !managedProfile; // Swipe doesn't make sense for profiles.
case MANAGED:
return mManagedPasswordProvider.isManagedPasswordChoosable();
@@ -128,29 +186,27 @@ public class ChooseLockGenericController {
}
/**
* Whether screen lock with {@code type} should be enabled.
*
* @param type The screen lock type.
* @param quality The minimum required quality. This can either be requirement by device policy
* manager or because some flow only makes sense with secure lock screens.
* Whether screen lock with {@code type} should be enabled assuming all relevant password
* requirements. The lock's visibility ({@link #isScreenLockVisible}) is not considered here.
*/
public boolean isScreenLockEnabled(ScreenLockType type, int quality) {
return type.maxQuality >= quality;
public boolean isScreenLockEnabled(ScreenLockType type) {
return type.maxQuality >= upgradeQuality(PASSWORD_QUALITY_UNSPECIFIED);
}
/**
* Whether screen lock with {@code type} is disabled by device policy admin.
*
* @param type The screen lock type.
* @param adminEnforcedQuality The minimum quality that the admin enforces.
* Increases the given quality to be as high as the combined quality from all relevant
* password requirements.
*/
public boolean isScreenLockDisabledByAdmin(ScreenLockType type, int adminEnforcedQuality) {
boolean disabledByAdmin = type.maxQuality < adminEnforcedQuality;
if (type == ScreenLockType.MANAGED) {
disabledByAdmin = disabledByAdmin
|| !mManagedPasswordProvider.isManagedPasswordChoosable();
}
return disabledByAdmin;
// TODO(b/142781408): convert from quality to credential type once PIN is supported.
public int upgradeQuality(int quality) {
return Math.max(quality,
Math.max(
LockPatternUtils.credentialTypeToPasswordQuality(
getAggregatedPasswordMetrics().credType),
PasswordMetrics.complexityLevelToMinQuality(
getAggregatedPasswordComplexity())
)
);
}
/**
@@ -175,43 +231,72 @@ public class ChooseLockGenericController {
}
/**
* Gets a list of screen locks that should be visible for the given quality. The returned list
* is ordered in the natural order of the enum (the order those enums were defined).
*
* @param quality The minimum quality required in the context of the current flow. This should
* be one of the constants defined in
* {@code DevicePolicyManager#PASSWORD_QUALITY_*}.
* @param includeDisabled Whether to include screen locks disabled by {@code quality}
* requirements in the returned list.
* Gets a list of screen lock types that should be visible for the given quality. The returned
* list is ordered in the natural order of the enum (the order those enums were defined). Screen
* locks disabled by password policy will not be returned.
*/
@NonNull
public List<ScreenLockType> getVisibleScreenLockTypes(int quality, boolean includeDisabled) {
int upgradedQuality = upgradeQuality(quality);
public List<ScreenLockType> getVisibleAndEnabledScreenLockTypes() {
List<ScreenLockType> locks = new ArrayList<>();
// EnumSet's iterator guarantees the natural order of the enums
for (ScreenLockType lock : ScreenLockType.values()) {
if (isScreenLockVisible(lock)) {
if (includeDisabled || isScreenLockEnabled(lock, upgradedQuality)) {
locks.add(lock);
}
if (isScreenLockVisible(lock) && isScreenLockEnabled(lock)) {
locks.add(lock);
}
}
return locks;
}
/**
* Returns the combined password metrics from all relevant policies which affects the current
* user. Normally password policies set on the current user's work profile instance will be
* taken into consideration here iff the work profile doesn't have its own work challenge.
* By setting {@link #mUnificationProfileId}, the work profile's password policy will always
* be combined here. Alternatively, by setting {@link #mDevicePasswordRequirementOnly}, its
* password policy will always be disregarded here.
*/
public PasswordMetrics getAggregatedPasswordMetrics() {
return mLockPatternUtils.getRequestedPasswordMetrics(mUserId,
PasswordMetrics metrics = mLockPatternUtils.getRequestedPasswordMetrics(mUserId,
mDevicePasswordRequirementOnly);
if (mUnificationProfileId != UserHandle.USER_NULL) {
metrics.maxWith(mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
}
return metrics;
}
/**
* Returns the combined password complexity from all relevant policies which affects the current
* user. The same logic of handling work profile password policies as
* {@link #getAggregatedPasswordMetrics} applies here.
*/
public int getAggregatedPasswordComplexity() {
return Math.max(mRequestedMinComplexity,
int complexity = Math.max(mAppRequestedMinComplexity,
mLockPatternUtils.getRequestedPasswordComplexity(
mUserId, mDevicePasswordRequirementOnly));
if (mUnificationProfileId != UserHandle.USER_NULL) {
complexity = Math.max(complexity,
mLockPatternUtils.getRequestedPasswordComplexity(mUnificationProfileId));
}
return complexity;
}
/**
* Returns whether any screen lock type has been disabled only due to password policy
* from the admin. Will return {@code false} if the restriction is purely due to calling
* app's request.
*/
public boolean isScreenLockRestrictedByAdmin() {
return getAggregatedPasswordMetrics().credType != CREDENTIAL_TYPE_NONE
|| getAggregatedPasswordComplexity() != PASSWORD_COMPLEXITY_NONE;
|| isComplexityProvidedByAdmin();
}
/**
* Returns whether the aggregated password complexity is non-zero and comes from
* admin policy.
*/
public boolean isComplexityProvidedByAdmin() {
final int aggregatedComplexity = getAggregatedPasswordComplexity();
return aggregatedComplexity > mAppRequestedMinComplexity
&& aggregatedComplexity > PASSWORD_COMPLEXITY_NONE;
}
}

View File

@@ -416,19 +416,6 @@ public class ChooseLockPassword extends SettingsActivity {
mMinComplexity = intent.getIntExtra(EXTRA_KEY_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
mMinMetrics = intent.getParcelableExtra(EXTRA_KEY_MIN_METRICS);
if (mMinMetrics == null) mMinMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
// If we are to unify a work challenge at the end of the credential enrollment, manually
// merge any password policy from that profile here, so we are enrolling a compliant
// password. This is because once unified, the profile's password policy will
// be enforced on the new credential.
//TODO: Move this logic to ChooseLockGeneric; let ChooseLockGeneric be the only place
//where password requirement mixing happens. ChooseLockPassword simply enforces what's
//set via IntentBuilder.setPasswordRequirement()
if (mUnificationProfileId != UserHandle.USER_NULL) {
mMinMetrics.maxWith(
mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
mMinComplexity = Math.max(mMinComplexity,
mLockPatternUtils.getRequestedPasswordComplexity(mUnificationProfileId));
}
if (intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {

View File

@@ -18,7 +18,6 @@ package com.android.settings.password;
import android.app.Activity;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
@@ -100,7 +99,9 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final int userId = getArguments().getInt(ARG_USER_ID);
mController = new ChooseLockGenericController(getContext(), userId);
mController = new ChooseLockGenericController.Builder(getContext(), userId)
.setHideInsecureScreenLockTypes(true)
.build();
}
@Override
@@ -124,10 +125,7 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getContext();
Builder builder = new Builder(context);
List<ScreenLockType> locks =
mController.getVisibleScreenLockTypes(
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
false /* includeDisabled */);
List<ScreenLockType> locks = mController.getVisibleAndEnabledScreenLockTypes();
mAdapter = new ScreenLockAdapter(context, locks, mController);
builder.setAdapter(mAdapter, this);
builder.setTitle(R.string.setup_lock_settings_options_dialog_title);

View File

@@ -19,7 +19,6 @@ package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static com.android.internal.util.Preconditions.checkNotNull;
@@ -145,10 +144,8 @@ final class SetNewPasswordController {
private Bundle getBiometricChooseLockExtras() {
Bundle chooseLockExtras = new Bundle();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
return chooseLockExtras;
@@ -156,10 +153,8 @@ final class SetNewPasswordController {
private Bundle getFingerprintChooseLockExtras() {
Bundle chooseLockExtras = new Bundle();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
return chooseLockExtras;
@@ -167,10 +162,8 @@ final class SetNewPasswordController {
private Bundle getFaceChooseLockExtras() {
Bundle chooseLockExtras = new Bundle();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
return chooseLockExtras;

View File

@@ -21,7 +21,6 @@ import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -160,22 +159,12 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric {
return SetupChooseLockGeneric.InternalActivity.class;
}
/***
* Disables preferences that are less secure than required quality and shows only secure
* screen lock options here.
*
* @param quality the requested quality.
*/
@Override
protected void disableUnusablePreferences(final int quality, boolean hideDisabled) {
protected boolean alwaysHideInsecureScreenLockTypes() {
// At this part of the flow, the user has already indicated they want to add a pin,
// pattern or password, so don't show "None" or "Slide". We disable them here and set
// the HIDE_DISABLED flag to true to hide them. This only happens for setup wizard.
// We do the following max check here since the device may already have a Device Admin
// installed with a policy we need to honor.
final int newQuality = Math.max(quality,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
super.disableUnusablePreferencesImpl(newQuality, true /* hideDisabled */);
// pattern or password, so don't show "None" or "Slide". We disable them here.
// This only happens for setup wizard.
return true;
}
@Override

View File

@@ -17,7 +17,6 @@
package com.android.settings.password;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -81,9 +80,11 @@ public class SetupChooseLockPassword extends ChooseLockPassword {
super.onViewCreated(view, savedInstanceState);
final Activity activity = getActivity();
ChooseLockGenericController chooseLockGenericController =
new ChooseLockGenericController(activity, mUserId);
boolean anyOptionsShown = chooseLockGenericController.getVisibleScreenLockTypes(
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false).size() > 0;
new ChooseLockGenericController.Builder(activity, mUserId)
.setHideInsecureScreenLockTypes(true)
.build();
boolean anyOptionsShown = chooseLockGenericController
.getVisibleAndEnabledScreenLockTypes().size() > 0;
boolean showOptionsButton = activity.getIntent().getBooleanExtra(
ChooseLockGeneric.ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false);
if (!anyOptionsShown) {

View File

@@ -44,9 +44,9 @@ import androidx.fragment.app.FragmentActivity;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.vpn2.VpnUtils;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
/**
* CredentialStorage handles resetting and installing keys into KeyStore.

View File

@@ -1,7 +1,9 @@
# Enterprise security reviewers
eranm@google.com
pgrafov@google.com
rubinxu@google.com
# Emergency
sandness@google.com
# Emeritus
eranm@google.com

View File

@@ -136,8 +136,8 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
if (passwordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
chooseLockIntent.putExtra(
ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
true);
startActivityForResult(chooseLockIntent, CHANGE_LOCK_METHOD_REQUEST);
return false;
}

View File

@@ -17,17 +17,11 @@
package com.android.settings.security;
import android.content.Context;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.overlay.FeatureFactory;
@@ -42,26 +36,6 @@ public class TopLevelSecurityEntryPreferenceController extends BasePreferenceCon
return AVAILABLE;
}
@Override
public CharSequence getSummary() {
// Remove homepage summaries for silky home.
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
return null;
}
final FingerprintManager fpm =
Utils.getFingerprintManagerOrNull(mContext);
final FaceManager faceManager =
Utils.getFaceManagerOrNull(mContext);
if (faceManager != null && faceManager.isHardwareDetected()) {
return mContext.getText(R.string.security_dashboard_summary_face);
} else if (fpm != null && fpm.isHardwareDetected()) {
return mContext.getText(R.string.security_dashboard_summary);
} else {
return mContext.getText(R.string.security_dashboard_summary_no_fingerprint);
}
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {

View File

@@ -432,8 +432,8 @@ public class UserSettings extends SettingsPreferenceFragment
private void launchChooseLockscreen() {
Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
chooseLockIntent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
chooseLockIntent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
true);
startActivityForResult(chooseLockIntent, REQUEST_CHOOSE_LOCK);
}

View File

@@ -30,7 +30,7 @@ import androidx.fragment.app.FragmentManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
/**
* When apps send a new intent with a WifiConfiguration list extra to Settings APP. Settings APP

View File

@@ -43,6 +43,7 @@ import com.android.settings.testutils.CommonUtils;
import com.android.settings.testutils.Constants;
import com.android.settings.testutils.UiUtils;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,7 +62,7 @@ public class WifiSettings2ActivityTest {
BatterySaverButtonPreferenceControllerComponentTest.class.getSimpleName();
private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
@Test
@Test @Ignore
public void test_connect_to_wifi() throws Exception {
//For some reason the ActivityScenario gets null activity here
mInstrumentation.getTargetContext().startActivity(

View File

@@ -19,10 +19,8 @@ package com.android.settings.accounts;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -40,7 +38,6 @@ public class TopLevelAccountEntryPreferenceControllerTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new TopLevelAccountEntryPreferenceController(mContext, "test_key");
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -48,11 +45,4 @@ public class TopLevelAccountEntryPreferenceControllerTest {
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.account_dashboard_default_summary));
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -22,10 +22,8 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -46,7 +44,6 @@ public class TopLevelConnectedDevicesPreferenceControllerTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new TopLevelConnectedDevicesPreferenceController(mContext, "test_key");
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -67,13 +64,6 @@ public class TopLevelConnectedDevicesPreferenceControllerTest {
.isEqualTo(mContext.getText(R.string.settings_label_launcher));
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
@Implements(AdvancedConnectedDeviceController.class)
private static class ShadowAdvancedConnectedDeviceController {

View File

@@ -1,104 +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.
*/
package com.android.settings.core;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.android.settings.R;
import com.android.settings.development.OverlaySettingsPreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ActivityController;
@RunWith(RobolectricTestRunner.class)
public class HideNonSystemOverlayMixinTest {
private ActivityController<TestActivity> mActivityController;
@Before
public void setUp() {
mActivityController = Robolectric.buildActivity(TestActivity.class);
}
@Test
public void startActivity_shouldHideNonSystemOverlay() {
mActivityController.setup();
TestActivity activity = mActivityController.get();
// Activity start: HIDE_NON_SYSTEM_OVERLAY should be set.
final WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
assertThat(attrs.privateFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
.isNotEqualTo(0);
}
@Test
public void stopActivity_shouldUnhideNonSystemOverlay() {
mActivityController.setup().stop();
TestActivity activity = mActivityController.get();
final WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
assertThat(attrs.privateFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
.isEqualTo(0);
}
@Test
public void isEnabled_isAllowedOverlaySettings_returnFalse() {
mActivityController.setup();
final TestActivity activity = mActivityController.get();
final SharedPreferences editor = activity.getSharedPreferences(
OverlaySettingsPreferenceController.SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(OverlaySettingsPreferenceController.SHARE_PERFS, true).apply();
assertThat(new HideNonSystemOverlayMixin(activity).isEnabled()).isFalse();
}
@Test
public void isEnabled_isNotAllowedOverlaySettings_returnTrue() {
mActivityController.setup();
TestActivity activity = mActivityController.get();
final SharedPreferences editor = activity.getSharedPreferences(
OverlaySettingsPreferenceController.SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(OverlaySettingsPreferenceController.SHARE_PERFS, false).apply();
assertThat(new HideNonSystemOverlayMixin(activity).isEnabled()).isTrue();
}
public static class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.Theme_AppCompat);
getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
}
}
}

View File

@@ -673,33 +673,6 @@ public class DashboardFeatureProviderImplTest {
verify(mActivity, never()).getSupportFragmentManager();
}
@Test
public void bindPreference_silkyHomeEnabled_shouldNotBindHomepageTileSummary() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
final Preference preference = new Preference(RuntimeEnvironment.application);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
Preference.DEFAULT_ORDER);
assertThat(preference.getSummary()).isNull();
}
@Test
public void bindPreference_silkyHomeEnabled_shouldBindSubpageTileSummary() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
final Preference preference = new Preference(RuntimeEnvironment.application);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_SYSTEM);
mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
Preference.DEFAULT_ORDER);
assertThat(preference.getSummary()).isEqualTo(
mContext.getText(R.string.about_settings_summary));
}
@Test
@Config(qualifiers = "mcc999")
public void bindPreference_specificHomepageTile_shouldOverridePosition() {

View File

@@ -23,9 +23,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.Build;
import android.provider.Settings.Global;
import android.util.FeatureFlagUtils;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -43,7 +40,6 @@ public class TopLevelAboutDevicePreferenceControllerTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new TopLevelAboutDevicePreferenceController(mContext, "test_key");
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -61,12 +57,4 @@ public class TopLevelAboutDevicePreferenceControllerTest {
Global.putString(mContext.getContentResolver(), Global.DEVICE_NAME, "Test");
assertThat(mController.getSummary().toString()).isEqualTo("Test");
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
Global.putString(mContext.getContentResolver(), Global.DEVICE_NAME, "Test");
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.settings.gestures;
package com.android.settings.display;
import static com.google.common.truth.Truth.assertThat;
@@ -47,18 +47,15 @@ import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
public class PowerMenuPrivacyPreferenceControllerTest {
public class ControlsPrivacyPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private static final String SETTING_KEY = Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT;
private static final String CARDS_AVAILABLE_KEY =
Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
private static final String CARDS_ENABLED_KEY = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
private static final String SETTING_KEY = "lockscreen_show_controls";
private Context mContext;
private ContentResolver mContentResolver;
private ShadowPackageManager mShadowPackageManager;
private PowerMenuPrivacyPreferenceController mController;
private ControlsPrivacyPreferenceController mController;
@Mock
private Preference mPreference;
@@ -77,85 +74,63 @@ public class PowerMenuPrivacyPreferenceControllerTest {
.thenReturn(mLockPatternUtils);
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
mController = new PowerMenuPrivacyPreferenceController(mContext, TEST_KEY);
mController = new ControlsPrivacyPreferenceController(mContext, TEST_KEY);
}
@Test
public void isChecked_POWER_MENU_LOCKED_SHOW_CONTENTIs1_returnTrue() {
public void isChecked_SettingIs1_returnTrue() {
Settings.Secure.putInt(mContentResolver, SETTING_KEY, 1);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_POWER_MENU_LOCKED_SHOW_CONTENTIs0_returnFalse() {
public void isChecked_SettingIs0_returnFalse() {
Settings.Secure.putInt(mContentResolver, SETTING_KEY, 0);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_POWER_MENU_LOCKED_SHOW_CONTENTIsNotSet_returnFalse() {
public void isChecked_SettingIsNotSet_returnFalse() {
Settings.Secure.putString(mContentResolver, SETTING_KEY, null);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void setChecked_true_POWER_MENU_LOCKED_SHOW_CONTENTIsNot0() {
public void setChecked_true_SettingIsNot0() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isNotEqualTo(0);
}
@Test
public void setChecked_false_POWER_MENU_LOCKED_SHOW_CONTENTIs0() {
public void setChecked_false_SettingIs0() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isEqualTo(0);
}
@Test
public void getSummary_notSecureLock_isPower_menu_privacy_not_secureString() {
public void getSummary_notSecureLock_lockscreen_privacy_not_secureString() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.power_menu_privacy_not_secure));
mContext.getText(R.string.lockscreen_privacy_not_secure));
}
@Test
public void getSummary_cardsControlsAvailable_isPower_menu_privacy_showString() {
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
public void getSummary_ControlsAvailable_lockscreen_privacy_showString() {
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.power_menu_privacy_show));
}
@Test
public void
getSummary_cardsUnavailableControlsAvailable_isPower_menu_privacy_show_controlsString() {
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 0);
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.power_menu_privacy_show_controls));
}
@Test
public void
getSummary_cardsAvailableControlsUnavailable_isPower_menu_privacy_show_cardsString() {
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, false);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.power_menu_privacy_show_cards));
mContext.getText(R.string.lockscreen_privacy_controls_summary));
}
@Test
public void updateState_onPreferenceRefreshed_preferenceEnabledAndSummaryChanged() {
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
mController.updateState(mPreference);
@@ -164,12 +139,20 @@ public class PowerMenuPrivacyPreferenceControllerTest {
}
@Test
public void getAvailabilityStatus_allOnNotSecure_returnsDisabled() {
public void getAvailabilityStatus_ControlsOnNotSecure_returnsDisabled() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
Settings.Secure.putInt(mContentResolver, CARDS_ENABLED_KEY, 1);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
}
@Test
public void getAvailabilityStatus_ControlsOffSecure_returnsDisabled() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.DISABLED_DEPENDENT_SETTING);

View File

@@ -31,10 +31,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -65,7 +63,6 @@ public class TopLevelDisplayPreferenceControllerTest {
when(mContext.getString(R.string.config_wallpaper_picker_class)).thenReturn("cls");
mController = new TopLevelDisplayPreferenceController(mContext, "test_key");
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -112,11 +109,4 @@ public class TopLevelDisplayPreferenceControllerTest {
assertThat(mController.getSummary())
.isEqualTo(mContext.getText(R.string.display_dashboard_nowallpaper_summary));
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2020 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.display;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import androidx.preference.Preference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
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 WalletPrivacyPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private static final String SETTING_KEY = "lockscreen_show_wallet";
private Context mContext;
private ContentResolver mContentResolver;
private WalletPrivacyPreferenceController mController;
@Mock
private Preference mPreference;
@Mock
private LockPatternUtils mLockPatternUtils;
@Mock
private QuickAccessWalletClient mClient;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mContentResolver = mContext.getContentResolver();
FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
.thenReturn(mLockPatternUtils);
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
when(mClient.isWalletServiceAvailable()).thenReturn(true);
mController = new WalletPrivacyPreferenceController(mContext, TEST_KEY) {
@Override
QuickAccessWalletClient initWalletClient() {
return mClient;
}
};
}
@Test
public void isChecked_SettingIs1_returnTrue() {
Settings.Secure.putInt(mContentResolver, SETTING_KEY, 1);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_SettingIs0_returnFalse() {
Settings.Secure.putInt(mContentResolver, SETTING_KEY, 0);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_SettingIsNotSet_returnFalse() {
Settings.Secure.putString(mContentResolver, SETTING_KEY, null);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void setChecked_true_SettingIsNot0() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isNotEqualTo(0);
}
@Test
public void setChecked_false_POWER_MENU_LOCKED_SHOW_CONTENTIs0() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isEqualTo(0);
}
@Test
public void getSummary_notSecureLock_lockscreen_privacy_not_secureString() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.lockscreen_privacy_not_secure));
}
@Test
public void getSummary_isSecure_lockscreen_privacy_showString() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.lockscreen_privacy_wallet_summary));
}
@Test
public void updateState_onPreferenceRefreshed_preferenceEnabledAndSummaryChanged() {
mController.updateState(mPreference);
verify(mPreference).setEnabled(anyBoolean());
verify(mPreference, atLeastOnce()).setSummary(mController.getSummary());
}
@Test
public void getAvailabilityStatus_noService_returnsDisabled() {
when(mClient.isWalletServiceAvailable()).thenReturn(false);
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
}
}

View File

@@ -62,6 +62,8 @@ import java.util.TimeZone;
public final class BatteryChartPreferenceControllerTest {
private static final String PREF_KEY = "pref_key";
private static final String PREF_SUMMARY = "fake preference summary";
private static final int DESIRED_HISTORY_SIZE =
BatteryChartPreferenceController.DESIRED_HISTORY_SIZE;
@Mock private InstrumentedPreferenceFragment mFragment;
@Mock private SettingsActivity mSettingsActivity;
@@ -98,7 +100,7 @@ public final class BatteryChartPreferenceControllerTest {
"fakeBatteryDiffEntryKey",
new BatteryEntry.NameAndIcon("fakeName", /*icon=*/ null, /*iconId=*/ 1));
mBatteryChartPreferenceController.setBatteryHistoryMap(
createBatteryHistoryMap(/*size=*/ 5));
createBatteryHistoryMap());
}
@Test
@@ -142,19 +144,19 @@ public final class BatteryChartPreferenceControllerTest {
@Test
public void testSetBatteryHistoryMap_createExpectedKeysAndLevels() {
mBatteryChartPreferenceController.setBatteryHistoryMap(
createBatteryHistoryMap(/*size=*/ 5));
createBatteryHistoryMap());
// Verifies the created battery keys array.
for (int index = 0; index < 25; index++) {
for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) {
assertThat(mBatteryChartPreferenceController.mBatteryHistoryKeys[index])
// These values is are calculated by hand from createBatteryHistoryMap().
.isEqualTo(index < 20 ? 0 : (index - 20 + 1));
.isEqualTo(index + 1);
}
// Verifies the created battery levels array.
for (int index = 0; index < 13; index++) {
assertThat(mBatteryChartPreferenceController.mBatteryHistoryLevels[index])
// These values is are calculated by hand from createBatteryHistoryMap().
.isEqualTo(index < 10 ? 0 : (100 - (index - 10) * 2));
.isEqualTo(100 - index * 2);
}
assertThat(mBatteryChartPreferenceController.mBatteryIndexedMap).hasSize(13);
}
@@ -162,10 +164,10 @@ public final class BatteryChartPreferenceControllerTest {
@Test
public void testSetBatteryHistoryMap_largeSize_createExpectedKeysAndLevels() {
mBatteryChartPreferenceController.setBatteryHistoryMap(
createBatteryHistoryMap(/*size=*/ 25));
createBatteryHistoryMap());
// Verifies the created battery keys array.
for (int index = 0; index < 25; index++) {
for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) {
assertThat(mBatteryChartPreferenceController.mBatteryHistoryKeys[index])
// These values is are calculated by hand from createBatteryHistoryMap().
.isEqualTo(index + 1);
@@ -214,7 +216,7 @@ public final class BatteryChartPreferenceControllerTest {
mBatteryChartPreferenceController.mTrapezoidIndex =
BatteryChartView.SELECTED_INDEX_INVALID;
mBatteryChartPreferenceController.setBatteryHistoryMap(
createBatteryHistoryMap(/*size=*/ 25));
createBatteryHistoryMap());
assertThat(mBatteryChartPreferenceController.mTrapezoidIndex)
.isEqualTo(BatteryChartView.SELECTED_INDEX_ALL);
@@ -426,31 +428,6 @@ public final class BatteryChartPreferenceControllerTest {
.isFalse();
}
@Test
public void testValidateSlotTimestamp_emptyContent_returnTrue() {
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(
new ArrayList<Long>())).isTrue();
}
@Test
public void testValidateSlotTimestamp_returnExpectedResult() {
final ArrayList<Long> slotTimestampList = new ArrayList<Long>(
Arrays.asList(
Long.valueOf(0),
Long.valueOf(DateUtils.HOUR_IN_MILLIS),
Long.valueOf(DateUtils.HOUR_IN_MILLIS * 2 + DateUtils.MINUTE_IN_MILLIS),
Long.valueOf(DateUtils.HOUR_IN_MILLIS * 3 + DateUtils.MINUTE_IN_MILLIS * 2)));
// Verifies the testing data is correct before we added invalid data into it.
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
.isTrue();
// Insert invalid timestamp into the list.
slotTimestampList.add(
Long.valueOf(DateUtils.HOUR_IN_MILLIS * 4 + DateUtils.MINUTE_IN_MILLIS * 6));
assertThat(BatteryChartPreferenceController.validateSlotTimestamp(slotTimestampList))
.isFalse();
}
@Test
public void testOnExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup() {
doReturn(1).when(mAppListGroup).getPreferenceCount();
@@ -582,13 +559,15 @@ public final class BatteryChartPreferenceControllerTest {
.setTimestamps(any());
}
private static Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
for (int index = 0; index < size; index++) {
private static Map<Long, Map<String, BatteryHistEntry>> createBatteryHistoryMap() {
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) {
final ContentValues values = new ContentValues();
values.put("batteryLevel", Integer.valueOf(100 - index));
final BatteryHistEntry entry = new BatteryHistEntry(values);
batteryHistoryMap.put(Long.valueOf(index + 1), Arrays.asList(entry));
final Map<String, BatteryHistEntry> entryMap = new HashMap<>();
entryMap.put("fake_entry_key" + index, entry);
batteryHistoryMap.put(Long.valueOf(index + 1), entryMap);
}
return batteryHistoryMap;
}

View File

@@ -23,7 +23,6 @@ import android.content.Context;
import com.android.settings.testutils.FakeFeatureFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
@@ -51,7 +50,7 @@ public final class BatteryHistoryLoaderTest {
@Test
public void testLoadIBackground_returnsMapFromPowerFeatureProvider() {
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
doReturn(batteryHistoryMap).when(mFeatureFactory.powerUsageFeatureProvider)
.getBatteryHistory(mContext);

View File

@@ -140,45 +140,76 @@ public final class ConvertUtilsTest {
.isEqualTo(ConvertUtils.FAKE_PACKAGE_NAME);
}
@Test
public void testGetIndexedUsageMap_nullOrEmptyHistoryMap_returnEmptyCollection() {
final int timeSlotSize = 2;
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L, 104L, 105L};
assertThat(ConvertUtils.getIndexedUsageMap(
mContext, timeSlotSize, batteryHistoryKeys,
/*batteryHistoryMap=*/ null, /*purgeLowPercentageAndFakeData=*/ true))
.isEmpty();
assertThat(ConvertUtils.getIndexedUsageMap(
mContext, timeSlotSize, batteryHistoryKeys,
new HashMap<Long, Map<String, BatteryHistEntry>>(),
/*purgeLowPercentageAndFakeData=*/ true))
.isEmpty();
}
@Test
public void testGetIndexedUsageMap_returnsExpectedResult() {
// Creates the fake testing data.
final int timeSlotSize = 2;
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L, 104L, 105L};
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
batteryHistoryMap.put(
Long.valueOf(batteryHistoryKeys[0]),
Arrays.asList(
createBatteryHistEntry(
"package1", "label1", 5.0, 1L, 10L, 20L)));
batteryHistoryMap.put(
Long.valueOf(batteryHistoryKeys[1]), new ArrayList<BatteryHistEntry>());
batteryHistoryMap.put(
Long.valueOf(batteryHistoryKeys[2]),
Arrays.asList(
createBatteryHistEntry(
"package2", "label2", 10.0, 2L, 15L, 25L)));
batteryHistoryMap.put(
Long.valueOf(batteryHistoryKeys[3]),
Arrays.asList(
createBatteryHistEntry(
"package2", "label2", 15.0, 2L, 25L, 35L),
createBatteryHistEntry(
"package3", "label3", 5.0, 3L, 5L, 5L)));
batteryHistoryMap.put(
Long.valueOf(batteryHistoryKeys[4]),
Arrays.asList(
createBatteryHistEntry(
"package2", "label2", 30.0, 2L, 30L, 40L),
createBatteryHistEntry(
"package2", "label2", 75.0, 4L, 40L, 50L),
createBatteryHistEntry(
"package3", "label3", 5.0, 3L, 5L, 5L)));
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap =
new HashMap<>();
final BatteryHistEntry fakeEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", 0, 0L, 0L, 0L);
// Adds the index = 0 data.
Map<String, BatteryHistEntry> entryMap = new HashMap<>();
BatteryHistEntry entry = createBatteryHistEntry(
"package1", "label1", 5.0, 1L, 10L, 20L);
entryMap.put(entry.getKey(), entry);
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[0]), entryMap);
// Adds the index = 1 data.
entryMap = new HashMap<>();
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[1]), entryMap);
// Adds the index = 2 data.
entryMap = new HashMap<>();
entry = createBatteryHistEntry(
"package2", "label2", 10.0, 2L, 15L, 25L);
entryMap.put(entry.getKey(), entry);
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[2]), entryMap);
// Adds the index = 3 data.
entryMap = new HashMap<>();
entry = createBatteryHistEntry(
"package2", "label2", 15.0, 2L, 25L, 35L);
entryMap.put(entry.getKey(), entry);
entry = createBatteryHistEntry(
"package3", "label3", 5.0, 3L, 5L, 5L);
entryMap.put(entry.getKey(), entry);
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[3]), entryMap);
// Adds the index = 4 data.
entryMap = new HashMap<>();
entry = createBatteryHistEntry(
"package2", "label2", 30.0, 2L, 30L, 40L);
entryMap.put(entry.getKey(), entry);
entry = createBatteryHistEntry(
"package2", "label2", 75.0, 4L, 40L, 50L);
entryMap.put(entry.getKey(), entry);
entry = createBatteryHistEntry(
"package3", "label3", 5.0, 3L, 5L, 5L);
entryMap.put(entry.getKey(), entry);
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[4]), entryMap);
final Map<Integer, List<BatteryDiffEntry>> resultMap =
ConvertUtils.getIndexedUsageMap(
mContext, timeSlotSize, batteryHistoryKeys, batteryHistoryMap,
/*purgeLowPercentageData=*/ false);
/*purgeLowPercentageAndFakeData=*/ false);
assertThat(resultMap).hasSize(3);
// Verifies the first timestamp result.
@@ -203,7 +234,7 @@ public final class ConvertUtilsTest {
final Map<Integer, List<BatteryDiffEntry>> purgedResultMap =
ConvertUtils.getIndexedUsageMap(
mContext, timeSlotSize, batteryHistoryKeys, batteryHistoryMap,
/*purgeLowPercentageData=*/ true);
/*purgeLowPercentageAndFakeData=*/ true);
assertThat(purgedResultMap).hasSize(3);
// Verifies the first timestamp result.
@@ -215,8 +246,49 @@ public final class ConvertUtilsTest {
assertBatteryDiffEntry(entryList.get(0), 75, 40L, 50L);
// Verifies the last 24 hours aggregate result.
entryList = purgedResultMap.get(Integer.valueOf(-1));
assertThat(entryList).hasSize(2);
// Verifies the fake data is cleared out.
assertThat(entryList.get(0).getPackageName())
.isNotEqualTo(ConvertUtils.FAKE_PACKAGE_NAME);
assertThat(entryList.get(1).getPackageName())
.isNotEqualTo(ConvertUtils.FAKE_PACKAGE_NAME);
}
@Test
public void testGetIndexedUsageMap_usageTimeExceed_returnsExpectedResult() {
final int timeSlotSize = 1;
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L};
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap =
new HashMap<>();
final BatteryHistEntry fakeEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", 0, 0L, 0L, 0L);
// Adds the index = 0 data.
Map<String, BatteryHistEntry> entryMap = new HashMap<>();
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[0]), entryMap);
// Adds the index = 1 data.
entryMap = new HashMap<>();
entryMap.put(fakeEntry.getKey(), fakeEntry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[1]), entryMap);
// Adds the index = 2 data.
entryMap = new HashMap<>();
final BatteryHistEntry entry = createBatteryHistEntry(
"package3", "label3", 500, 5L, 3600000L, 7200000L);
entryMap.put(entry.getKey(), entry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[2]), entryMap);
final Map<Integer, List<BatteryDiffEntry>> purgedResultMap =
ConvertUtils.getIndexedUsageMap(
mContext, timeSlotSize, batteryHistoryKeys, batteryHistoryMap,
/*purgeLowPercentageAndFakeData=*/ true);
assertThat(purgedResultMap).hasSize(2);
final List<BatteryDiffEntry> entryList = purgedResultMap.get(0);
assertThat(entryList).hasSize(1);
assertBatteryDiffEntry(entryList.get(0), 68, 40L, 50L);
// Verifies the clipped usage time.
final BatteryDiffEntry resultEntry = entryList.get(0);
assertThat(resultEntry.mForegroundUsageTimeInMs).isEqualTo(2400000);
assertThat(resultEntry.mBackgroundUsageTimeInMs).isEqualTo(4800000);
}
@Test

View File

@@ -22,10 +22,8 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -43,7 +41,6 @@ public class TopLevelBatteryPreferenceControllerTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new TopLevelBatteryPreferenceController(mContext, "test_key");
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -73,16 +70,8 @@ public class TopLevelBatteryPreferenceControllerTest {
assertThat(mController.getDashboardLabel(mContext, info, true)).isEqualTo("5% - charging");
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
@Test
public void getSummary_batteryNotPresent_shouldShowWarningMessage() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
mController.mIsBatteryPresent = false;
assertThat(mController.getSummary())

View File

@@ -1,86 +0,0 @@
/*
* Copyright (C) 2020 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.gestures;
import static com.google.common.truth.Truth.assertThat;
import android.annotation.StringRes;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.Arrays;
import java.util.Collection;
@RunWith(ParameterizedRobolectricTestRunner.class)
public class PowerMenuPreferenceControllerSummaryTest {
private static final String KEY_GESTURE_POWER_MENU = "gesture_power_menu";
private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
@ParameterizedRobolectricTestRunner.Parameters(
name = "cards available={0}, cards enabled={1}")
public static Collection data() {
return Arrays.asList(new Object[][]{
// cards available, cards enabled, summary
{false, false, R.string.power_menu_none},
{false, true, R.string.power_menu_none},
{true, false, R.string.power_menu_none},
{true, true, R.string.power_menu_cards_passes}
});
}
private Context mContext;
private PowerMenuPreferenceController mController;
private boolean mCardsAvailable;
private boolean mCardsEnabled;
private @StringRes int mSummaryRes;
public PowerMenuPreferenceControllerSummaryTest(
boolean cardsAvailable,
boolean cardsEnabled,
@StringRes int summaryRes) {
mCardsAvailable = cardsAvailable;
mCardsEnabled = cardsEnabled;
mSummaryRes = summaryRes;
}
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new PowerMenuPreferenceController(mContext, KEY_GESTURE_POWER_MENU);
}
@Test
public void getSummary_possiblyAvailableAndEnabled() {
ContentResolver cr = mContext.getContentResolver();
Settings.Secure.putInt(cr, CARDS_AVAILABLE, mCardsAvailable ? 1 : 0);
Settings.Secure.putInt(cr, CARDS_ENABLED, mCardsEnabled ? 1 : 0);
assertThat(mController.getSummary()).isEqualTo(mContext.getText(mSummaryRes));
}
}

View File

@@ -24,7 +24,6 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.provider.Settings;
import com.android.settings.core.BasePreferenceController;
@@ -41,8 +40,6 @@ public class PowerMenuPreferenceControllerTest {
private PowerMenuPreferenceController mController;
private static final String KEY_GESTURE_POWER_MENU = "gesture_power_menu";
private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
@Before
@@ -57,8 +54,7 @@ public class PowerMenuPreferenceControllerTest {
}
@Test
public void getAvailabilityStatus_allAvailable_available() {
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
public void getAvailabilityStatus_assistAvailable_available() {
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(true);
@@ -68,41 +64,7 @@ public class PowerMenuPreferenceControllerTest {
}
@Test
public void getAvailabilityStatus_onlyCardsAvailable_available() {
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_cardsAndAssistAvailable_available() {
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_onlyAssistAvailable_available() {
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_allUnavailable_unavailable() {
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
public void getAvailabilityStatus_assistUnavailable_unavailable() {
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(false);

View File

@@ -1,116 +0,0 @@
/*
* Copyright (C) 2020 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.gestures;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.provider.Settings;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowPackageManager;
import java.util.Arrays;
import java.util.Collection;
@RunWith(ParameterizedRobolectricTestRunner.class)
public class PowerMenuPrivacyPreferenceControllerAvailabilityTest {
private static final String CONTROLS_FEATURE = PackageManager.FEATURE_CONTROLS;
private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
@ParameterizedRobolectricTestRunner.Parameters(
name = "ctrls available={0} cards available={1}, cards enabled={2}")
public static Collection data() {
return Arrays.asList(new Object[][]{
// controls available, cards available, cards enabled, available
{false, false, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
{false, false, true, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
{false, true, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
{false, true, true, BasePreferenceController.AVAILABLE},
{true, false, false, BasePreferenceController.AVAILABLE},
{true, false, true, BasePreferenceController.AVAILABLE},
{true, true, false, BasePreferenceController.AVAILABLE},
{true, true, true, BasePreferenceController.AVAILABLE}
});
}
private Context mContext;
private PowerMenuPrivacyPreferenceController mController;
private ShadowPackageManager mShadowPackageManager;
@Mock
private LockPatternUtils mLockPatternUtils;
private boolean mControlsAvailable;
private boolean mCardsAvailable;
private boolean mCardsEnabled;
private int mAvailable;
public PowerMenuPrivacyPreferenceControllerAvailabilityTest(
boolean controlsAvailable,
boolean cardsAvailable,
boolean cardsEnabled,
int available) {
mControlsAvailable = controlsAvailable;
mCardsAvailable = cardsAvailable;
mCardsEnabled = cardsEnabled;
mAvailable = available;
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
// For these tests we assume the device has a secure lock.
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
.thenReturn(mLockPatternUtils);
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
mController = new PowerMenuPrivacyPreferenceController(mContext, "TEST_KEY");
}
@Test
public void getAvailabilityStatus_possiblyAvailableAndEnabled() {
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, mControlsAvailable);
ContentResolver cr = mContext.getContentResolver();
Settings.Secure.putInt(cr, CARDS_AVAILABLE, mCardsAvailable ? 1 : 0);
Settings.Secure.putInt(cr, CARDS_ENABLED, mCardsEnabled ? 1 : 0);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mAvailable);
}
}

View File

@@ -35,11 +35,11 @@ import android.widget.FrameLayout;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
import org.junit.Before;
import org.junit.Test;
@@ -65,7 +65,7 @@ public class SettingsHomepageActivityTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setIsPageTransitionEnabled(false);
ShadowUtils.setIsPageTransitionEnabled(true);
}
@Test

View File

@@ -20,10 +20,8 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.location.LocationManager;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -43,7 +41,6 @@ public class TopLevelLocationPreferenceControllerTest {
mContext = RuntimeEnvironment.application;
mController = new TopLevelLocationPreferenceController(mContext, PREFERENCE_KEY);
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -86,11 +83,4 @@ public class TopLevelLocationPreferenceControllerTest {
R.plurals.location_settings_summary_location_on,
LOCATION_APP_COUNT, LOCATION_APP_COUNT));
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -24,9 +24,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.UserManager;
import android.util.FeatureFlagUtils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settings.wifi.WifiPrimarySwitchPreferenceController;
@@ -74,7 +72,6 @@ public class TopLevelNetworkEntryPreferenceControllerTest {
mMobileNetworkPreferenceController);
ReflectionHelpers.setField(mController, "mTetherPreferenceController",
mTetherPreferenceController);
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@After
@@ -106,11 +103,4 @@ public class TopLevelNetworkEntryPreferenceControllerTest {
assertThat(mController.getSummary()).isEqualTo("Wi\u2011Fi and data usage");
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -36,8 +36,8 @@ import android.view.WindowManager;
import androidx.fragment.app.FragmentManager;
import com.android.settings.R;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
import org.junit.Before;
import org.junit.Test;

View File

@@ -20,23 +20,31 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordPolicy;
import android.os.UserHandle;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowUserManager;
import org.junit.After;
import org.junit.Before;
@@ -48,10 +56,11 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.Arrays;
import java.util.Set;
import java.util.regex.Pattern;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class)
@Config(shadows = {ShadowUserManager.class, SettingsShadowResources.class})
public class ChooseLockGenericControllerTest {
private ChooseLockGenericController mController;
@@ -68,7 +77,7 @@ public class ChooseLockGenericControllerTest {
when(mLockPatternUtils.hasSecureLockScreen()).thenReturn(true);
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
mController = createController(PASSWORD_COMPLEXITY_NONE);
mController = createBuilder().build();
SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, false);
SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, false);
}
@@ -95,8 +104,8 @@ public class ChooseLockGenericControllerTest {
}
@Test
public void isScreenLockVisible_notCurrentUser_shouldHideInsecure() {
mController = new ChooseLockGenericController(application, 1 /* userId */);
public void isScreenLockVisible_ManagedProfile_shouldHideInsecure() {
ShadowUserManager.getShadow().setManagedProfiles(Set.of(0));
assertWithMessage("SWIPE visible").that(
mController.isScreenLockVisible(ScreenLockType.SWIPE)).isFalse();
assertWithMessage("NONE visible").that(mController.isScreenLockVisible(ScreenLockType.NONE))
@@ -112,62 +121,116 @@ public class ChooseLockGenericControllerTest {
}
@Test
public void isScreenLockEnabled_lowerQuality_shouldReturnFalse() {
for (ScreenLockType lock : ScreenLockType.values()) {
assertWithMessage(lock + " enabled").that(
mController.isScreenLockEnabled(lock, lock.maxQuality + 1)).isFalse();
}
public void isScreenLockEnabled_Default() {
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_equalQuality_shouldReturnTrue() {
for (ScreenLockType lock : ScreenLockType.values()) {
assertWithMessage(lock + " enabled").that(
mController.isScreenLockEnabled(lock, lock.defaultQuality)).isTrue();
}
public void isScreenLockEnabled_QualityUnspecified() {
setDevicePolicyPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_higherQuality_shouldReturnTrue() {
for (ScreenLockType lock : ScreenLockType.values()) {
assertWithMessage(lock + " enabled").that(
mController.isScreenLockEnabled(lock, lock.maxQuality - 1)).isTrue();
}
public void isScreenLockEnabled_QualitySomething() {
setDevicePolicyPasswordQuality(PASSWORD_QUALITY_SOMETHING);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockDisabledByAdmin_lowerQuality_shouldReturnTrue() {
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
for (ScreenLockType lock : ScreenLockType.values()) {
assertWithMessage(lock + " disabledByAdmin").that(
mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality + 1)).isTrue();
}
public void isScreenLockEnabled_QualityNumeric() {
setDevicePolicyPasswordQuality(PASSWORD_QUALITY_NUMERIC);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockDisabledByAdmin_equalQuality_shouldReturnFalse() {
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
for (ScreenLockType lock : ScreenLockType.values()) {
assertWithMessage(lock + " disabledByAdmin").that(
mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality)).isFalse();
}
public void isScreenLockEnabled_QualityNumericComplex() {
setDevicePolicyPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockDisabledByAdmin_higherQuality_shouldReturnFalse() {
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
for (ScreenLockType lock : ScreenLockType.values()) {
assertWithMessage(lock + " disabledByAdmin").that(
mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality - 1)).isFalse();
}
public void isScreenLockEnabled_QualityAlphabetic() {
setDevicePolicyPasswordQuality(PASSWORD_QUALITY_ALPHABETIC);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockDisabledByAdmin_managedNotChoosable_shouldReturnTrue() {
doReturn(false).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
assertWithMessage("MANANGED disabledByAdmin").that(mController.isScreenLockDisabledByAdmin(
ScreenLockType.MANAGED, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isTrue();
public void isScreenLockEnabled_QualityComplex() {
setDevicePolicyPasswordQuality(PASSWORD_QUALITY_COMPLEX);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_NoneComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_NONE);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_lowComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_LOW);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_mediumComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_highComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_HIGH);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
@@ -181,8 +244,8 @@ public class ChooseLockGenericControllerTest {
@Test
public void getVisibleScreenLockTypes_qualitySomething_shouldReturnPatterPinPassword() {
assertThat(mController.getVisibleScreenLockTypes(
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false))
mController = createBuilder().setHideInsecureScreenLockTypes(true).build();
assertThat(mController.getVisibleAndEnabledScreenLockTypes())
.isEqualTo(Arrays.asList(
ScreenLockType.PATTERN,
ScreenLockType.PIN,
@@ -191,8 +254,7 @@ public class ChooseLockGenericControllerTest {
@Test
public void getVisibleScreenLockTypes_showDisabled_shouldReturnAllButManaged() {
assertThat(mController.getVisibleScreenLockTypes(
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, true))
assertThat(mController.getVisibleAndEnabledScreenLockTypes())
.isEqualTo(Arrays.asList(
ScreenLockType.NONE,
ScreenLockType.SWIPE,
@@ -223,31 +285,68 @@ public class ChooseLockGenericControllerTest {
@Test
public void upgradeQuality_complexityHigh_minQualityNumericComplex() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_HIGH)
.build();
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_HIGH);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
assertThat(mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
}
@Test
public void upgradeQuality_complexityMedium_minQualityNumericComplex() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_MEDIUM)
.build();
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
assertThat(mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
}
@Test
public void upgradeQuality_complexityLow_minQualitySomething() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_LOW)
.build();
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_LOW);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
assertThat(mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
}
@Test
public void getAggregatedPasswordComplexity_AppRequest() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_HIGH)
.build();
assertThat(mController.getAggregatedPasswordComplexity())
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
}
@Test
public void getAggregatedPasswordComplexity_DevicePolicy() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_LOW)
.build();
when(mLockPatternUtils.getRequestedPasswordComplexity(eq(UserHandle.myUserId()), eq(false)))
.thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(mController.getAggregatedPasswordComplexity())
.isEqualTo(PASSWORD_COMPLEXITY_MEDIUM);
}
@Test
public void getAggregatedPasswordComplexity_ProfileUnification() {
mController = createBuilder()
.setProfileToUnify(123)
.setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_LOW)
.build();
when(mLockPatternUtils.getRequestedPasswordComplexity(eq(UserHandle.myUserId()), eq(false)))
.thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
when(mLockPatternUtils.getRequestedPasswordComplexity(eq(123)))
.thenReturn(PASSWORD_COMPLEXITY_HIGH);
assertThat(mController.getAggregatedPasswordComplexity())
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
}
private void setDevicePolicyPasswordQuality(int quality) {
PasswordPolicy policy = new PasswordPolicy();
policy.quality = quality;
@@ -256,13 +355,10 @@ public class ChooseLockGenericControllerTest {
.thenReturn(policy.getMinMetrics());
}
private ChooseLockGenericController createController(
@PasswordComplexity int minPasswordComplexity) {
return new ChooseLockGenericController(
private ChooseLockGenericController.Builder createBuilder() {
return new ChooseLockGenericController.Builder(
application,
0 /* userId */,
minPasswordComplexity,
false,
mManagedLockPasswordProvider,
mLockPatternUtils);
}

View File

@@ -30,7 +30,6 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -429,18 +428,6 @@ public class ChooseLockPasswordTest {
"PIN must be at least 8 digits");
}
@Test
public void validateComplexityMergedFromUnificationUserOnCreate() {
ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
ShadowLockPatternUtils.setRequiredPasswordComplexity(123, PASSWORD_COMPLEXITY_HIGH);
Intent intent = createIntentForPasswordValidation(null, PASSWORD_COMPLEXITY_NONE,
PASSWORD_QUALITY_NUMERIC);
intent.putExtra(EXTRA_KEY_UNIFICATION_PROFILE_ID, 123);
assertPasswordValidationResultForIntent(LockscreenCredential.createNone(), intent,
"PIN must be at least 8 digits");
}
private ChooseLockPassword buildChooseLockPasswordActivity(Intent intent) {
return Robolectric.buildActivity(ChooseLockPassword.class, intent).setup().get();
}

View File

@@ -19,8 +19,7 @@ package com.android.settings.password;
import static android.content.pm.PackageManager.FEATURE_FACE;
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE;
@@ -262,12 +261,9 @@ public final class SetNewPasswordControllerTest {
private void compareFingerprintExtras(Bundle actualBundle) {
assertEquals(
"Password quality must be something in order to config fingerprint.",
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
actualBundle.getInt(MINIMUM_QUALITY_KEY));
assertTrue(
"All disabled preference should be removed.",
actualBundle.getBoolean(HIDE_DISABLED_PREFS));
"Insecure options must be disabled in order to config fingerprint.",
true,
actualBundle.getBoolean(HIDE_INSECURE_OPTIONS));
assertTrue(
"Fingerprint enroll must request Gatekeeper Password.",
actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW_HANDLE));
@@ -282,12 +278,9 @@ public final class SetNewPasswordControllerTest {
private void compareFaceExtras(Bundle actualBundle) {
assertEquals(
"Password quality must be something in order to config face.",
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
actualBundle.getInt(MINIMUM_QUALITY_KEY));
assertTrue(
"All disabled preference should be removed.",
actualBundle.getBoolean(HIDE_DISABLED_PREFS));
"Insecure options must be disabled in order to config face.",
true,
actualBundle.getBoolean(HIDE_INSECURE_OPTIONS));
assertTrue(
"Face enroll must request Gatekeeper Password",
actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW_HANDLE));

View File

@@ -198,8 +198,7 @@ public class SetupChooseLockPasswordTest {
@Implements(ChooseLockGenericController.class)
public static class ShadowChooseLockGenericController {
@Implementation
protected List<ScreenLockType> getVisibleScreenLockTypes(int quality,
boolean includeDisabled) {
protected List<ScreenLockType> getVisibleScreenLockTypes() {
return Collections.emptyList();
}
}

View File

@@ -1,143 +0,0 @@
/*
* 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.security;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.util.FeatureFlagUtils;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class TopLevelSecurityEntryPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private FingerprintManager mFingerprintManager;
@Mock
private FaceManager mFaceManager;
private TopLevelSecurityEntryPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
.thenReturn(mFingerprintManager);
when(mContext.getSystemService(Context.FACE_SERVICE))
.thenReturn(mFaceManager);
mController = new TopLevelSecurityEntryPreferenceController(mContext, "test_key");
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
public void geSummary_hasFace_hasStaticSummary() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
.thenReturn(true);
when(mFaceManager.isHardwareDetected()).thenReturn(true);
mController.getSummary();
verify(mContext).getText(R.string.security_dashboard_summary_face);
}
@Test
public void geSummary_hasFingerPrint_hasStaticSummary() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
.thenReturn(false);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(true);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
mController.getSummary();
verify(mContext).getText(R.string.security_dashboard_summary);
}
@Test
public void geSummary_noFpFeature_shouldSetSummaryWithNoBiometrics() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(false);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
.thenReturn(false);
mController.getSummary();
verify(mContext).getText(R.string.security_dashboard_summary_no_fingerprint);
}
@Test
public void geSummary_noFpHardware_shouldSetSummaryWithNoBiometrics() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
.thenReturn(false);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(true);
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
mController.getSummary();
verify(mContext).getText(R.string.security_dashboard_summary_no_fingerprint);
}
@Test
public void geSummary_noFaceFeature_shouldSetSummaryWithNoBiometrics() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(false);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
.thenReturn(false);
mController.getSummary();
verify(mContext).getText(R.string.security_dashboard_summary_no_fingerprint);
}
@Test
public void geSummary_noFaceHardware_shouldSetSummaryWithNoBiometrics() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
.thenReturn(true);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(false);
when(mFaceManager.isHardwareDetected()).thenReturn(false);
mController.getSummary();
verify(mContext).getText(R.string.security_dashboard_summary_no_fingerprint);
}
@Test
public void getSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -16,10 +16,12 @@
package com.android.settings.development;
import static com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin.SECURE_OVERLAY_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
@@ -83,20 +85,16 @@ public class OverlaySettingsPreferenceControllerTest {
@Test
public void isOverlaySettingsEnabled_sharePreferenceSetTrue_shouldReturnTrue() {
final SharedPreferences editor = mContext.getSharedPreferences(
OverlaySettingsPreferenceController.SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(OverlaySettingsPreferenceController.SHARE_PERFS, true).apply();
Settings.Secure.putInt(mContext.getContentResolver(),
SECURE_OVERLAY_SETTINGS, 1);
assertThat(OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isTrue();
}
@Test
public void isOverlaySettingsEnabled_sharePreferenceSetFalse_shouldReturnFalse() {
final SharedPreferences editor = mContext.getSharedPreferences(
OverlaySettingsPreferenceController.SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(OverlaySettingsPreferenceController.SHARE_PERFS, false).apply();
Settings.Secure.putInt(mContext.getContentResolver(),
SECURE_OVERLAY_SETTINGS, 0);
assertThat(
OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isFalse();

View File

@@ -30,13 +30,11 @@ import android.content.Context;
import android.icu.text.NumberFormat;
import android.os.storage.VolumeInfo;
import android.text.format.Formatter;
import android.util.FeatureFlagUtils;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.FeatureFlags;
import com.android.settings.testutils.ResourcesUtils;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
@@ -72,7 +70,6 @@ public class TopLevelStoragePreferenceControllerTest {
when(mStorageManagerVolumeProvider.getVolumes()).thenReturn(mVolumes);
mController = spy(new TopLevelStoragePreferenceController(mContext, "test_key"));
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@Test
@@ -108,11 +105,4 @@ public class TopLevelStoragePreferenceControllerTest {
assertThat(preference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(
mContext, "storage_summary", percentage, freeSpace));
}
@Test
public void refreshSummary_silkyHomeEnabled_shouldBeNull() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
assertThat(mController.getSummary()).isNull();
}
}