diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a6a354e1dca..100a071483e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1358,7 +1358,7 @@ diff --git a/OWNERS b/OWNERS index 8938b643aeb..6d4f95f0de4 100644 --- a/OWNERS +++ b/OWNERS @@ -2,22 +2,18 @@ android-settings-core-eng+gerrit@google.com # People who can approve changes for submission -arcwang@google.com cantol@google.com chaohuiw@google.com chiujason@google.com -cyl@google.com +dswliu@google.com edgarwang@google.com -llz@google.com millchen@google.com songchenxi@google.com -stanleytfwang@google.com sunnyshao@google.com yantingyang@google.com ykhung@google.com # Emergency only -lijun@google.com wangqi@google.com yanglu@google.com diff --git a/color-check-baseline.xml b/color-check-baseline.xml index 2fd63fc8307..509d9ae0e5a 100644 --- a/color-check-baseline.xml +++ b/color-check-baseline.xml @@ -4429,6 +4429,22 @@ column="13"/> + + + + Allow your child to use their face to unlock their device + Allow your child to use their face to unlock their phone or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more. + + Allow your child to use their face to unlock their tablet or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more. + + Allow your child to use their face to unlock their device or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more. + Using your child\u2019s face to unlock their phone may be less secure than a strong pattern or PIN. Using your child\u2019s face to unlock their tablet may be less secure than a strong pattern or PIN. diff --git a/res/drawable/ic_check_24dp.xml b/res/drawable/ic_check_24dp.xml index 9ac80215bb0..0ed6b3253d7 100644 --- a/res/drawable/ic_check_24dp.xml +++ b/res/drawable/ic_check_24dp.xml @@ -18,8 +18,8 @@ android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?androidprv:attr/materialColorPrimaryContainer"> + android:tint="?androidprv:attr/colorAccent"> - \ No newline at end of file + diff --git a/res/drawable/ic_screen_rotation.xml b/res/drawable/ic_screen_rotation.xml new file mode 100644 index 00000000000..f1bde27453d --- /dev/null +++ b/res/drawable/ic_screen_rotation.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 505aac0f6d5..95e476c0877 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11904,6 +11904,12 @@ Disable restrictions on the system resource usage of the app child processes + + Force enable Notes role + + Enable note-taking system integrations via the Notes role. If the Notes role is already enabled, does nothing. + + Broadcast diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 9e1dbad8ba3..e7aac3e7528 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -713,6 +713,11 @@ android:title="@string/disable_phantom_process_monitor_title" android:summary="@string/disable_phantom_process_monitor_summary" /> + + DISABLE_PACKAGE_LIST = new ArrayList<>(); static { - DISABLE_PACKAGE_LIST.add("com.android.systemui"); + DISABLE_PACKAGE_LIST.add(Utils.SYSTEMUI_PACKAGE_NAME); } public OverlayState(PermissionState permissionState) { diff --git a/src/com/android/settings/applications/RecentAppStatsMixin.java b/src/com/android/settings/applications/RecentAppStatsMixin.java index 6705b256e64..4e8f795d8c2 100644 --- a/src/com/android/settings/applications/RecentAppStatsMixin.java +++ b/src/com/android/settings/applications/RecentAppStatsMixin.java @@ -17,6 +17,7 @@ package com.android.settings.applications; import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; +import static com.android.settings.Utils.SYSTEMUI_PACKAGE_NAME; import android.app.Application; import android.app.usage.UsageStats; @@ -76,7 +77,7 @@ public class RecentAppStatsMixin implements LifecycleObserver, OnStart { "android", "com.android.phone", SETTINGS_PACKAGE_NAME, - "com.android.systemui", + SYSTEMUI_PACKAGE_NAME, "com.android.providers.calendar", "com.android.providers.media" )); diff --git a/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java b/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java index d794de69475..3c90bf358c0 100644 --- a/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java +++ b/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java @@ -38,6 +38,7 @@ import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.EmptyTextSettings; @@ -57,7 +58,7 @@ public class PictureInPictureSettings extends EmptyTextSettings { static final List IGNORE_PACKAGE_LIST = new ArrayList<>(); static { - IGNORE_PACKAGE_LIST.add("com.android.systemui"); + IGNORE_PACKAGE_LIST.add(Utils.SYSTEMUI_PACKAGE_NAME); } /** diff --git a/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java b/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java index 014971adf19..742831e4716 100644 --- a/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java +++ b/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java @@ -37,6 +37,7 @@ import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.EmptyTextSettings; @@ -58,7 +59,7 @@ public class TurnScreenOnSettings extends EmptyTextSettings { static final List IGNORE_PACKAGE_LIST = new ArrayList<>(); static { - IGNORE_PACKAGE_LIST.add("com.android.systemui"); + IGNORE_PACKAGE_LIST.add(Utils.SYSTEMUI_PACKAGE_NAME); } /** diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java index 3e8c45852d7..efd9753a2a2 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java @@ -592,6 +592,10 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { return data; } + protected boolean isFaceStrong() { + return mIsFaceStrong; + } + private void onFaceStrengthChanged() { // Set up and show the "less secure" info section if necessary. if (!mIsFaceStrong && getResources().getBoolean( diff --git a/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java b/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java index a3a745d698b..aabbf6f9316 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java @@ -47,13 +47,14 @@ public class FaceEnrollParentalConsent extends FaceEnrollIntroduction { R.string.security_settings_face_enroll_introduction_control_consent_title, R.string.security_settings_face_enroll_introduction_control_consent_message, R.string.security_settings_face_enroll_introduction_consent_message_0, + R.string.security_settings_face_enroll_introduction_consent_message_0_class3, R.string.security_settings_face_enroll_introduction_info_consent_less_secure }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setDescriptionText(R.string.security_settings_face_enroll_introduction_consent_message_0); + updateDescriptionText(); } @Override @@ -144,4 +145,16 @@ public class FaceEnrollParentalConsent extends FaceEnrollIntroduction { public int getMetricsCategory() { return SettingsEnums.FACE_PARENTAL_CONSENT; } + + @Override + protected void updateDescriptionText() { + super.updateDescriptionText(); + if (isFaceStrong()) { + setDescriptionText(getString( + R.string.security_settings_face_enroll_introduction_consent_message_0_class3)); + } else { + setDescriptionText( + R.string.security_settings_face_enroll_introduction_consent_message_0); + } + } } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java index c33ae175a09..7f4142def5c 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java @@ -131,4 +131,12 @@ public class FingerprintEnrollParentalConsent extends FingerprintEnrollIntroduct public int getMetricsCategory() { return SettingsEnums.FINGERPRINT_PARENTAL_CONSENT; } + + + @Override + protected void updateDescriptionText() { + super.updateDescriptionText(); + setDescriptionText( + R.string.security_settings_fingerprint_enroll_introduction_consent_message); + } } diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingIconTouchDialog.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingIconTouchDialog.java index e86d755526e..f4fe7ff9b87 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingIconTouchDialog.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingIconTouchDialog.java @@ -18,14 +18,11 @@ package com.android.settings.biometrics2.ui.view; import android.app.Dialog; import android.app.settings.SettingsEnums; -import android.content.Context; import android.os.Bundle; import androidx.appcompat.app.AlertDialog; -import androidx.lifecycle.ViewModelProvider; import com.android.settings.R; -import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; /** @@ -33,15 +30,6 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment; */ public class FingerprintEnrollEnrollingIconTouchDialog extends InstrumentedDialogFragment { - private FingerprintEnrollEnrollingViewModel mViewModel; - - @Override - public void onAttach(Context context) { - mViewModel = new ViewModelProvider(getActivity()).get( - FingerprintEnrollEnrollingViewModel.class); - super.onAttach(context); - } - @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), @@ -50,10 +38,7 @@ public class FingerprintEnrollEnrollingIconTouchDialog extends InstrumentedDialo .setMessage(R.string.security_settings_fingerprint_enroll_touch_dialog_message) .setPositiveButton( R.string.security_settings_fingerprint_enroll_dialog_ok, - (dialog, which) -> { - dialog.dismiss(); - mViewModel.onIconTouchDialogDismiss(); - }); + (dialog, which) -> dialog.dismiss()); return builder.create(); } diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java index 62928af9700..d84ce6146b5 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java @@ -27,7 +27,6 @@ import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewMo import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE; import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData; -import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED; @@ -518,10 +517,6 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { SKIP_SETUP_FIND_FPS_DIALOG_TAG); break; } - case FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG: { - onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null)); - break; - } case FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED: { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { getSupportFragmentManager().popBackStack(); diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java index 025c58bca95..12584ee9d96 100644 --- a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java +++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java @@ -60,25 +60,19 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { */ public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG = 1; - /** - * Icon touch dialog dismiss - */ - public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG = 2; - /** * Has got latest cancelled event due to user skip */ - public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP = 3; + public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP = 2; /** * Has got latest cancelled event due to back key */ - public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED = 4; + public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED = 3; @IntDef(prefix = { "FINGERPRINT_ENROLL_ENROLLING_ACTION_" }, value = { FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE, FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG, - FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG, FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP, FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED }) @@ -116,7 +110,6 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { private final Vibrator mVibrator; private final MutableLiveData mActionLiveData = new MutableLiveData<>(); - private final MutableLiveData mIconTouchDialogLiveData = new MutableLiveData<>(); private final MutableLiveData mErrorDialogLiveData = new MutableLiveData<>(); private final MutableLiveData mErrorDialogActionLiveData = new MutableLiveData<>(); @@ -233,17 +226,6 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { mActionLiveData.postValue(action); } - /** - * Icon touch dialog dismiss - */ - public void onIconTouchDialogDismiss() { - final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG; - if (DEBUG) { - Log.d(TAG, "onIconTouchDialogDismiss, post action " + action); - } - mActionLiveData.postValue(action); - } - /** * get enroll stage threshold */ diff --git a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java index b30aee4d216..66f2f1b8f31 100644 --- a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java @@ -25,6 +25,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.Utils; import com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController; import com.android.settings.bluetooth.BluetoothSwitchPreferenceController; import com.android.settings.dashboard.DashboardFragment; @@ -45,8 +46,6 @@ public class BluetoothDashboardFragment extends DashboardFragment { private static final String TAG = "BluetoothDashboardFrag"; private static final String KEY_BLUETOOTH_SCREEN_FOOTER = "bluetooth_screen_footer"; - private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; - private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; private static final String SLICE_ACTION = "com.android.settings.SEARCH_RESULT_TRAMPOLINE"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -112,8 +111,8 @@ public class BluetoothDashboardFragment extends DashboardFragment { @VisibleForTesting boolean isAlwaysDiscoverable(String callingAppPackageName, String action) { return TextUtils.equals(SLICE_ACTION, action) ? false - : TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) - || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName); + : TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(Utils.SYSTEMUI_PACKAGE_NAME, callingAppPackageName); } /** diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index 3c6077e3c24..9286b8164cc 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -28,6 +28,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.Utils; import com.android.settings.core.SettingsUIDeviceConfig; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; @@ -38,7 +39,6 @@ import com.android.settingslib.search.SearchIndexable; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; - private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final String SLICE_ACTION = "com.android.settings.SEARCH_RESULT_TRAMPOLINE"; @@ -92,8 +92,8 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { @VisibleForTesting boolean isAlwaysDiscoverable(String callingAppPackageName, String action) { return TextUtils.equals(SLICE_ACTION, action) ? false - : TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) - || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName); + : TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(Utils.SYSTEMUI_PACKAGE_NAME, callingAppPackageName); } /** diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index acc0e7c40fc..65d3be05432 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -733,6 +733,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new PhantomProcessPreferenceController(context)); controllers.add(new ContrastPreferenceController( context, context.getSystemService(UiModeManager.class))); + controllers.add(new ForceEnableNotesRolePreferenceController(context)); return controllers; } diff --git a/src/com/android/settings/development/ForceEnableNotesRolePreferenceController.java b/src/com/android/settings/development/ForceEnableNotesRolePreferenceController.java new file mode 100644 index 00000000000..7821beca15a --- /dev/null +++ b/src/com/android/settings/development/ForceEnableNotesRolePreferenceController.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2023 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. + */ +/* + * Copyright (C) 2023 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.development; + +import static android.os.UserHandle.USER_CURRENT; + +import android.content.Context; +import android.content.om.IOverlayManager; +import android.os.RemoteException; +import android.os.ServiceManager; + +import androidx.preference.Preference; +import androidx.preference.SwitchPreference; + +import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +public class ForceEnableNotesRolePreferenceController + extends DeveloperOptionsPreferenceController + implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { + + private static final String NOTES_ROLE_ENABLED_KEY = + "force_enable_notes_role"; + + private static final String OVERLAY_PACKAGE_NAME = + "com.android.role.notes.enabled"; + + private final IOverlayManager mOverlayManager; + + public ForceEnableNotesRolePreferenceController(Context context) { + super(context); + mOverlayManager = IOverlayManager.Stub.asInterface( + ServiceManager.getService(Context.OVERLAY_SERVICE)); + } + + @Override + public String getPreferenceKey() { + return NOTES_ROLE_ENABLED_KEY; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + setEnabled((boolean) newValue); + return true; + } + + @Override + public void updateState(Preference preference) { + ((SwitchPreference) mPreference).setChecked(isEnabled()); + } + + @Override + protected void onDeveloperOptionsSwitchDisabled() { + super.onDeveloperOptionsSwitchDisabled(); + ((SwitchPreference) mPreference).setChecked(false); + setEnabled(false); + } + + @VisibleForTesting + protected boolean isEnabled() { + return mContext.getResources().getBoolean(R.bool.config_enableDefaultNotes); + } + + @VisibleForTesting + protected void setEnabled(boolean enabled) { + try { + mOverlayManager.setEnabled(OVERLAY_PACKAGE_NAME, enabled, USER_CURRENT); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } +} diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java index ac72ceda387..496cfabe734 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java +++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java @@ -16,6 +16,8 @@ package com.android.settings.fuelgauge; +import static com.android.settings.Utils.SYSTEMUI_PACKAGE_NAME; + import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -35,9 +37,8 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider private static final String PACKAGE_CALENDAR_PROVIDER = "com.android.providers.calendar"; private static final String PACKAGE_MEDIA_PROVIDER = "com.android.providers.media"; - private static final String PACKAGE_SYSTEMUI = "com.android.systemui"; private static final String[] PACKAGES_SYSTEM = {PACKAGE_MEDIA_PROVIDER, - PACKAGE_CALENDAR_PROVIDER, PACKAGE_SYSTEMUI}; + PACKAGE_CALENDAR_PROVIDER, SYSTEMUI_PACKAGE_NAME}; protected PackageManager mPackageManager; protected Context mContext; diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java index b17ccaa9065..445a5d12966 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java @@ -16,6 +16,7 @@ package com.android.settings.fuelgauge.batteryusage; import static com.android.settings.Utils.formatPercentage; +import static com.android.settings.fuelgauge.batteryusage.BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS; import static java.lang.Math.round; import static java.util.Objects.requireNonNull; @@ -29,6 +30,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.os.Bundle; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.view.HapticFeedbackConstants; @@ -52,13 +54,13 @@ import com.android.settingslib.Utils; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Set; /** A widget component to draw chart graph. */ public class BatteryChartView extends AppCompatImageView implements View.OnClickListener { private static final String TAG = "BatteryChartView"; private static final int DIVIDER_COLOR = Color.parseColor("#CDCCC5"); - private static final long UPDATE_STATE_DELAYED_TIME = 500L; /** A callback listener for selected group index is updated. */ public interface OnSelectListener { @@ -70,6 +72,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private final Rect mIndent = new Rect(); private final Rect[] mPercentageBounds = new Rect[]{new Rect(), new Rect(), new Rect()}; private final List mAxisLabelsBounds = new ArrayList<>(); + private final Set mLabelDrawnIndexes = new ArraySet<>(); private BatteryChartViewModel mViewModel; private int mHoveredIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID; @@ -80,6 +83,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private int mTrapezoidColor; private int mTrapezoidSolidColor; private int mTrapezoidHoverColor; + private int mDefaultTextColor; private int mTextPadding; private Paint mDividerPaint; private Paint mTrapezoidPaint; @@ -134,6 +138,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick // Pre-draws the view first to load style atttributions into paint. textView.draw(new Canvas()); mTextPaint = textView.getPaint(); + mDefaultTextColor = mTextPaint.getColor(); } else { mTextPaint = null; } @@ -332,6 +337,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick final int height = getHeight() - mIndent.top - mIndent.bottom; // Draws the top divider line for 100% curve. float offsetY = mIndent.top + mDividerWidth * .5f; + mDividerPaint.setColor(DIVIDER_COLOR); canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint); drawPercentage(canvas, /*index=*/ 0, offsetY); @@ -351,6 +357,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private void drawPercentage(Canvas canvas, int index, float offsetY) { if (mTextPaint != null) { mTextPaint.setTextAlign(Paint.Align.RIGHT); + mTextPaint.setColor(mDefaultTextColor); canvas.drawText( mPercentages[index], getWidth(), @@ -367,18 +374,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick final float bottomY = getHeight() - mIndent.bottom; final float startY = bottomY - mDividerHeight; final float trapezoidSlotOffset = mTrapezoidHOffset + mDividerWidth * .5f; - // Draws each vertical dividers. - float startX = mDividerWidth * .5f; - for (int index = 0; index < dividerCount; index++) { - canvas.drawLine(startX, startY, startX, bottomY, mDividerPaint); - final float nextX = startX + mDividerWidth + unitWidth; - // Updates the trapezoid slots for drawing. - if (index < mTrapezoidSlots.length) { - mTrapezoidSlots[index].mLeft = round(startX + trapezoidSlotOffset); - mTrapezoidSlots[index].mRight = round(nextX - trapezoidSlotOffset); - } - startX = nextX; - } // Draws the axis label slot information. if (mViewModel != null) { final float baselineY = getHeight() - mTextPadding; @@ -404,6 +399,26 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick } drawAxisLabels(canvas, axisLabelDisplayAreas, baselineY); } + // Draws each vertical dividers. + float startX = mDividerWidth * .5f; + for (int index = 0; index < dividerCount; index++) { + float dividerY = bottomY; + if (mViewModel.axisLabelPosition() == BETWEEN_TRAPEZOIDS + && mLabelDrawnIndexes.contains(index)) { + mDividerPaint.setColor(mTrapezoidSolidColor); + dividerY += mDividerHeight / 4f; + } else { + mDividerPaint.setColor(DIVIDER_COLOR); + } + canvas.drawLine(startX, startY, startX, dividerY, mDividerPaint); + final float nextX = startX + mDividerWidth + unitWidth; + // Updates the trapezoid slots for drawing. + if (index < mTrapezoidSlots.length) { + mTrapezoidSlots[index].mLeft = round(startX + trapezoidSlotOffset); + mTrapezoidSlots[index].mRight = round(nextX - trapezoidSlotOffset); + } + startX = nextX; + } } /** Gets all the axis label texts displaying area positions if they are shown. */ @@ -432,9 +447,12 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private void drawAxisLabels(Canvas canvas, final Rect[] displayAreas, final float baselineY) { final int lastIndex = displayAreas.length - 1; + mLabelDrawnIndexes.clear(); // Suppose first and last labels are always able to draw. drawAxisLabelText(canvas, 0, displayAreas[0], baselineY); + mLabelDrawnIndexes.add(0); drawAxisLabelText(canvas, lastIndex, displayAreas[lastIndex], baselineY); + mLabelDrawnIndexes.add(lastIndex); drawAxisLabelsBetweenStartIndexAndEndIndex(canvas, displayAreas, 0, lastIndex, baselineY); } @@ -458,6 +476,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick return; } drawAxisLabelText(canvas, middleIndex, displayAreas[middleIndex], baselineY); + mLabelDrawnIndexes.add(middleIndex); drawAxisLabelsBetweenStartIndexAndEndIndex( canvas, displayAreas, startIndex, middleIndex, baselineY); drawAxisLabelsBetweenStartIndexAndEndIndex( @@ -471,7 +490,9 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick return; } drawAxisLabelText(canvas, middleIndex1, displayAreas[middleIndex1], baselineY); + mLabelDrawnIndexes.add(middleIndex1); drawAxisLabelText(canvas, middleIndex2, displayAreas[middleIndex2], baselineY); + mLabelDrawnIndexes.add(middleIndex2); drawAxisLabelsBetweenStartIndexAndEndIndex( canvas, displayAreas, startIndex, middleIndex1, baselineY); drawAxisLabelsBetweenStartIndexAndEndIndex( @@ -488,12 +509,14 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private void drawAxisLabelText( Canvas canvas, final int index, final Rect displayArea, final float baselineY) { + mTextPaint.setColor(mTrapezoidSolidColor); mTextPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText( mViewModel.getText(index), displayArea.centerX(), baselineY, mTextPaint); + mLabelDrawnIndexes.add(index); } private void drawTrapezoids(Canvas canvas) { diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java index 2121c60218b..cd1bdefc92d 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java @@ -313,11 +313,8 @@ public class BatteryUsageBreakdownController extends BasePreferenceController @VisibleForTesting void removeAndCacheAllUnusedPreferences() { List entries = getBatteryDiffEntries(); - Set entryKeySet = new ArraySet<>(); - for (BatteryDiffEntry entry : entries) { - entryKeySet.add(entry.getKey()); - } - + Set entryKeySet = new ArraySet<>(entries.size()); + entries.forEach(entry -> entryKeySet.add(entry.getKey())); final int prefsCount = mAppListPreferenceGroup.getPreferenceCount(); for (int index = prefsCount - 1; index >= 0; index--) { final Preference pref = mAppListPreferenceGroup.getPreference(index); diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java index ec1a4be0fae..24571cd0a60 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java @@ -725,9 +725,9 @@ public final class DataProcessor { @VisibleForTesting @Nullable static Map>> buildAppUsagePeriodList( - final List allAppUsageEvents, final List batteryEventList, + final List appUsageEvents, final List batteryEventList, final long startTime, final long endTime) { - if (allAppUsageEvents.isEmpty()) { + if (appUsageEvents.isEmpty()) { return null; } @@ -735,7 +735,7 @@ public final class DataProcessor { // use. final List deviceEvents = new ArrayList<>(); final ArrayMap> usageEventsByInstanceId = new ArrayMap<>(); - for (final AppUsageEvent event : allAppUsageEvents) { + for (final AppUsageEvent event : appUsageEvents) { final AppUsageEventType eventType = event.getType(); if (eventType == AppUsageEventType.ACTIVITY_RESUMED || eventType == AppUsageEventType.ACTIVITY_STOPPED) { @@ -852,9 +852,11 @@ public final class DataProcessor { final List usagePeriodList, final List batteryEventList) { final List resultList = new ArrayList<>(); + int index = 0; for (AppUsagePeriod inputPeriod : usagePeriodList) { long lastStartTime = inputPeriod.getStartTime(); - for (BatteryEvent batteryEvent : batteryEventList) { + while (index < batteryEventList.size()) { + BatteryEvent batteryEvent = batteryEventList.get(index); if (batteryEvent.getTimestamp() < inputPeriod.getStartTime()) { // Because the batteryEventList has been sorted, here is to mark the power // connection state when the usage period starts. If power is connected when @@ -865,6 +867,7 @@ public final class DataProcessor { } else if (batteryEvent.getType() == BatteryEventType.POWER_DISCONNECTED) { lastStartTime = inputPeriod.getStartTime(); } + index++; continue; } if (batteryEvent.getTimestamp() > inputPeriod.getEndTime()) { @@ -883,6 +886,7 @@ public final class DataProcessor { } else if (batteryEvent.getType() == BatteryEventType.POWER_DISCONNECTED) { lastStartTime = batteryEvent.getTimestamp(); } + index++; } if (lastStartTime != 0) { resultList.add(AppUsagePeriod.newBuilder() diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java index 84a39bb811f..0435e451e82 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java @@ -110,13 +110,7 @@ public final class DatabaseUtils { // For testing only. @VisibleForTesting - static Supplier sFakeBatteryStateSupplier; - @VisibleForTesting - static Supplier sFakeAppUsageEventSupplier; - @VisibleForTesting - static Supplier sFakeAppUsageLatestTimestampSupplier; - @VisibleForTesting - static Supplier sFakeBatteryEventSupplier; + static Supplier sFakeSupplier; private DatabaseUtils() { } @@ -340,7 +334,7 @@ public final class DatabaseUtils { resolver.insert(BATTERY_EVENT_URI, contentValues); Log.d(TAG, "insert() battery event data into database: " + batteryEvent.toString()); } catch (Exception e) { - Log.e(TAG, "insert() battery event data into database error:\n" + e); + Log.e(TAG, "insert() battery event data into database error:", e); } Log.d(TAG, String.format("sendBatteryEventData() in %d/ms", (System.currentTimeMillis() - startTime))); @@ -487,8 +481,8 @@ public final class DatabaseUtils { Context context, final Uri appUsageLatestTimestampUri) { // We have already make sure the context here is with profile parent's user identity. Don't // need to check whether current user is work profile. - try (Cursor cursor = sFakeAppUsageLatestTimestampSupplier != null - ? sFakeAppUsageLatestTimestampSupplier.get() + try (Cursor cursor = sFakeSupplier != null + ? sFakeSupplier.get() : context.getContentResolver().query( appUsageLatestTimestampUri, null, null, null)) { if (cursor == null || cursor.getCount() == 0) { @@ -514,8 +508,8 @@ public final class DatabaseUtils { if (context == null) { return appUsageEventList; } - try (Cursor cursor = sFakeAppUsageEventSupplier != null - ? sFakeAppUsageEventSupplier.get() + try (Cursor cursor = sFakeSupplier != null + ? sFakeSupplier.get() : context.getContentResolver().query(appUsageEventUri, null, null, null)) { if (cursor == null || cursor.getCount() == 0) { return appUsageEventList; @@ -540,8 +534,8 @@ public final class DatabaseUtils { if (context == null) { return batteryEventList; } - try (Cursor cursor = sFakeBatteryEventSupplier != null - ? sFakeBatteryEventSupplier.get() + try (Cursor cursor = sFakeSupplier != null + ? sFakeSupplier.get() : context.getContentResolver().query(batteryEventUri, null, null, null)) { if (cursor == null || cursor.getCount() == 0) { return batteryEventList; @@ -566,7 +560,7 @@ public final class DatabaseUtils { return null; } final Map> resultMap = new HashMap(); - try (Cursor cursor = sFakeBatteryStateSupplier != null ? sFakeBatteryStateSupplier.get() : + try (Cursor cursor = sFakeSupplier != null ? sFakeSupplier.get() : context.getContentResolver().query(batteryStateUri, null, null, null)) { if (cursor == null || cursor.getCount() == 0) { return resultMap; diff --git a/src/com/android/settings/panel/PanelFeatureProviderImpl.java b/src/com/android/settings/panel/PanelFeatureProviderImpl.java index 57a1ab0324a..71711f9228e 100644 --- a/src/com/android/settings/panel/PanelFeatureProviderImpl.java +++ b/src/com/android/settings/panel/PanelFeatureProviderImpl.java @@ -22,9 +22,9 @@ import android.os.Bundle; import android.provider.Settings; import android.util.FeatureFlagUtils; -public class PanelFeatureProviderImpl implements PanelFeatureProvider { +import com.android.settings.Utils; - private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; +public class PanelFeatureProviderImpl implements PanelFeatureProvider { @Override public PanelContent getPanel(Context context, Bundle bundle) { @@ -42,7 +42,7 @@ public class PanelFeatureProviderImpl implements PanelFeatureProvider { // Redirect to the internet dialog in SystemUI. Intent intent = new Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND) - .setPackage(SYSTEMUI_PACKAGE_NAME); + .setPackage(Utils.SYSTEMUI_PACKAGE_NAME); context.sendBroadcast(intent); return null; case Settings.Panel.ACTION_NFC: @@ -55,7 +55,7 @@ public class PanelFeatureProviderImpl implements PanelFeatureProvider { // Redirect to the volume panel in SystemUI. Intent volumeIntent = new Intent(Settings.Panel.ACTION_VOLUME); volumeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND).setPackage( - SYSTEMUI_PACKAGE_NAME); + Utils.SYSTEMUI_PACKAGE_NAME); context.sendBroadcast(volumeIntent); return null; } else { diff --git a/src/com/android/settings/spa/system/AppLanguagesListModel.kt b/src/com/android/settings/spa/system/AppLanguagesListModel.kt index 3141d68c94f..942bcc4b794 100644 --- a/src/com/android/settings/spa/system/AppLanguagesListModel.kt +++ b/src/com/android/settings/spa/system/AppLanguagesListModel.kt @@ -33,8 +33,10 @@ import com.android.settings.applications.AppLocaleUtil import com.android.settings.applications.appinfo.AppLocaleDetails import com.android.settings.localepicker.AppLocalePickerActivity import com.android.settingslib.spa.framework.util.filterItem +import com.android.settingslib.spaprivileged.framework.common.asUser import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.model.app.userHandle import com.android.settingslib.spaprivileged.template.app.AppListItem import com.android.settingslib.spaprivileged.template.app.AppListItemModel import kotlinx.coroutines.Dispatchers @@ -54,17 +56,18 @@ class AppLanguagesListModel(private val context: Context) : AppListModel, appListFlow: Flow>) = userIdFlow.map { userId -> - packageManager.queryIntentActivitiesAsUser( + userId to packageManager.queryIntentActivitiesAsUser( AppLocaleUtil.LAUNCHER_ENTRY_INTENT, PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA.toLong()), userId, ) - }.combine(appListFlow) { resolveInfos, appList -> + }.combine(appListFlow) { (userId, resolveInfos), appList -> + val userContext = context.asUser(UserHandle.of(userId)) appList.map { app -> AppLanguagesRecord( app = app, isAppLocaleSupported = AppLocaleUtil.canDisplayLocaleUi( - context, app, resolveInfos + userContext, app, resolveInfos ), ) } @@ -86,9 +89,7 @@ class AppLanguagesListModel(private val context: Context) : AppListModel.AppItem() { @@ -96,8 +97,7 @@ class AppLanguagesListModel(private val context: Context) : AppListModel cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; doReturn(true).when(mUserManager).isUserUnlocked(anyInt()); mDataProcessManager.start(); @@ -171,7 +171,7 @@ public final class DataProcessManagerTest { cursor.addRow(new Object[] { AppUsageEventType.ACTIVITY_STOPPED.getNumber(), /*timestamp=*/ 6, /*userId=*/ 1, /*instanceId=*/ 2, packageName}); - DatabaseUtils.sFakeAppUsageEventSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; final DataProcessManager dataProcessManager = new DataProcessManager( mContext, /*handler=*/ null, /*rawStartTimestamp=*/ 2L, /*callbackFunction=*/ null, @@ -240,7 +240,7 @@ public final class DataProcessManagerTest { AppUsageEventEntity.KEY_TIMESTAMP}); // Adds fake data into the cursor. cursor.addRow(new Object[] {101L, "app name1", 1001L}); - DatabaseUtils.sFakeAppUsageEventSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; mDataProcessManager.start(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java index 20799d403d3..efce44e600f 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java @@ -261,7 +261,7 @@ public final class DatabaseUtilsTest { public void getAppUsageStartTimestampOfUser_emptyCursorContent_returnEarliestTimestamp() { final MatrixCursor cursor = new MatrixCursor(new String[] {AppUsageEventEntity.KEY_TIMESTAMP}); - DatabaseUtils.sFakeAppUsageLatestTimestampSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; final long earliestTimestamp = 10001L; assertThat(DatabaseUtils.getAppUsageStartTimestampOfUser( @@ -270,7 +270,7 @@ public final class DatabaseUtilsTest { @Test public void getAppUsageStartTimestampOfUser_nullCursor_returnEarliestTimestamp() { - DatabaseUtils.sFakeAppUsageLatestTimestampSupplier = () -> null; + DatabaseUtils.sFakeSupplier = () -> null; final long earliestTimestamp = 10001L; assertThat(DatabaseUtils.getAppUsageStartTimestampOfUser( mContext, /*userId=*/ 0, earliestTimestamp)).isEqualTo(earliestTimestamp); @@ -283,7 +283,7 @@ public final class DatabaseUtilsTest { new MatrixCursor(new String[] {AppUsageEventEntity.KEY_TIMESTAMP}); // Adds fake data into the cursor. cursor.addRow(new Object[] {returnedTimestamp}); - DatabaseUtils.sFakeAppUsageLatestTimestampSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; final long earliestTimestamp1 = 1001L; assertThat(DatabaseUtils.getAppUsageStartTimestampOfUser( @@ -302,7 +302,7 @@ public final class DatabaseUtilsTest { AppUsageEventEntity.KEY_PACKAGE_NAME, AppUsageEventEntity.KEY_TIMESTAMP, AppUsageEventEntity.KEY_APP_USAGE_EVENT_TYPE}); - DatabaseUtils.sFakeAppUsageEventSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; assertThat(DatabaseUtils.getAppUsageEventForUsers( mContext, @@ -313,7 +313,7 @@ public final class DatabaseUtilsTest { @Test public void getAppUsageEventForUsers_nullCursor_returnEmptyMap() { - DatabaseUtils.sFakeAppUsageEventSupplier = () -> null; + DatabaseUtils.sFakeSupplier = () -> null; assertThat(DatabaseUtils.getAppUsageEventForUsers( mContext, /*calendar=*/ null, @@ -335,7 +335,7 @@ public final class DatabaseUtilsTest { cursor.addRow(new Object[] {101L, "app name2", timestamp2}); cursor.addRow(new Object[] {101L, "app name3", timestamp2}); cursor.addRow(new Object[] {101L, "app name4", timestamp2}); - DatabaseUtils.sFakeAppUsageEventSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; final List appUsageEventList = DatabaseUtils.getAppUsageEventForUsers( mContext, @@ -356,7 +356,7 @@ public final class DatabaseUtilsTest { BatteryHistEntry.KEY_UID, BatteryHistEntry.KEY_USER_ID, BatteryHistEntry.KEY_TIMESTAMP}); - DatabaseUtils.sFakeBatteryStateSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; assertThat(DatabaseUtils.getHistoryMapSinceLastFullCharge( mContext, /*calendar=*/ null)).isEmpty(); @@ -364,7 +364,7 @@ public final class DatabaseUtilsTest { @Test public void getHistoryMapSinceLastFullCharge_nullCursor_returnEmptyMap() { - DatabaseUtils.sFakeBatteryStateSupplier = () -> null; + DatabaseUtils.sFakeSupplier = () -> null; assertThat(DatabaseUtils.getHistoryMapSinceLastFullCharge( mContext, /*calendar=*/ null)).isEmpty(); } @@ -383,7 +383,7 @@ public final class DatabaseUtilsTest { "app name3", timestamp2, 3, ConvertUtils.CONSUMER_TYPE_UID_BATTERY}); cursor.addRow(new Object[] { "app name4", timestamp2, 4, ConvertUtils.CONSUMER_TYPE_UID_BATTERY}); - DatabaseUtils.sFakeBatteryStateSupplier = () -> cursor; + DatabaseUtils.sFakeSupplier = () -> cursor; final Map> batteryHistMap = DatabaseUtils.getHistoryMapSinceLastFullCharge( @@ -413,7 +413,7 @@ public final class DatabaseUtilsTest { doReturn(true).when(mUserManager).isManagedProfile(); doReturn(UserHandle.SYSTEM).when(mUserManager).getProfileParent(UserHandle.CURRENT); - DatabaseUtils.sFakeBatteryStateSupplier = () -> getMatrixCursor(); + DatabaseUtils.sFakeSupplier = () -> getMatrixCursor(); final Map> batteryHistMap = DatabaseUtils.getHistoryMapSinceLastFullCharge( diff --git a/tests/robotests/src/com/android/settings/support/SupportDashboardActivityTest.java b/tests/robotests/src/com/android/settings/support/SupportDashboardActivityTest.java index 0124551740e..f5109944626 100644 --- a/tests/robotests/src/com/android/settings/support/SupportDashboardActivityTest.java +++ b/tests/robotests/src/com/android/settings/support/SupportDashboardActivityTest.java @@ -16,6 +16,8 @@ package com.android.settings.support; +import static com.android.settings.support.SupportDashboardActivity.ACTION_SUPPORT_SETTINGS; + import static com.google.common.truth.Truth.assertThat; import android.content.Context; @@ -59,7 +61,7 @@ public class SupportDashboardActivityTest { mContext.getString(R.string.page_tab_title_support)); assertThat(value.intentTargetPackage).isEqualTo(mContext.getPackageName()); assertThat(value.intentTargetClass).isEqualTo(SupportDashboardActivity.class.getName()); - assertThat(value.intentAction).isEqualTo(Intent.ACTION_MAIN); + assertThat(value.intentAction).isEqualTo(ACTION_SUPPORT_SETTINGS); } @Test diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java index ad086b7dce8..faaa0fa917f 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java @@ -470,7 +470,7 @@ public class WifiConfigController2Test { private void checkSavedMacRandomizedValue(int macRandomizedValue) { when(mWifiEntry.isSaved()).thenReturn(true); - final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); + final WifiConfiguration mockWifiConfig = spy(new WifiConfiguration()); when(mockWifiConfig.getIpConfiguration()).thenReturn(mock(IpConfiguration.class)); when(mWifiEntry.getWifiConfiguration()).thenReturn(mockWifiConfig); mockWifiConfig.macRandomizationSetting = macRandomizedValue; @@ -809,9 +809,10 @@ public class WifiConfigController2Test { private void setUpModifyingSavedPeapConfigController() { when(mWifiEntry.isSaved()).thenReturn(true); when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); - final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); + final WifiConfiguration mockWifiConfig = spy(new WifiConfiguration()); + mockWifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); when(mockWifiConfig.getIpConfiguration()).thenReturn(mock(IpConfiguration.class)); - final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class); + final WifiEnterpriseConfig mockWifiEnterpriseConfig = spy(new WifiEnterpriseConfig()); when(mockWifiEnterpriseConfig.getEapMethod()).thenReturn(Eap.PEAP); mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig; when(mWifiEntry.getWifiConfiguration()).thenReturn(mockWifiConfig); @@ -980,8 +981,8 @@ public class WifiConfigController2Test { private void setUpModifyingSavedCertificateConfigController(String savedCaCertificate, String savedUserCertificate) { - final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); - final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class); + final WifiConfiguration mockWifiConfig = spy(new WifiConfiguration()); + final WifiEnterpriseConfig mockWifiEnterpriseConfig = spy(new WifiEnterpriseConfig()); mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig; when(mWifiEntry.isSaved()).thenReturn(true); diff --git a/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java b/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java index cffc452f407..ae32651cdcf 100644 --- a/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java +++ b/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java @@ -33,6 +33,7 @@ import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; +import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -54,18 +55,25 @@ public class FingerprintEnrollmentActivityTest { private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; private static final String ACTIVITY_CLASS_NAME = "com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity"; - public static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow"; + private static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow"; + private static final String EXTRA_SKIP_FIND_SENSOR = "skip_find_sensor"; private static final String EXTRA_FROM_SETTINGS_SUMMARY = "from_settings_summary"; private static final String EXTRA_PAGE_TRANSITION_TYPE = "page_transition_type"; private static final String EXTRA_KEY_GK_PW_HANDLE = "gk_pw_handle"; private static final String TEST_PIN = "1234"; + private static final String UDFPS_ENROLLING_TITLE = "Touch & hold the fingerprint sensor"; + private static final String SFPS_ENROLLING_TITLE = + "Lift, then touch. Move your finger slightly each time."; + private static final String RFPS_ENROLLING_TITLE = "Lift, then touch again"; + private UiDevice mDevice; private byte[] mToken = new byte[]{}; private Context mContext; private boolean mFingerprintPropCallbackLaunched; private boolean mCanAssumeUdfps; private boolean mCanAssumeSfps; + private String mEnrollingTitle; private static final int IDLE_TIMEOUT = 10000; @@ -94,6 +102,13 @@ public class FingerprintEnrollmentActivityTest { final FingerprintSensorPropertiesInternal prop = list.get(0); mCanAssumeUdfps = prop.isAnyUdfpsType(); mCanAssumeSfps = prop.isAnySidefpsType(); + if (mCanAssumeUdfps) { + mEnrollingTitle = UDFPS_ENROLLING_TITLE; + } else if (mCanAssumeSfps) { + mEnrollingTitle = SFPS_ENROLLING_TITLE; + } else { + mEnrollingTitle = RFPS_ENROLLING_TITLE; + } } }); @@ -106,8 +121,9 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchChooseLock() { - launchFingerprintEnrollActivity(false, null); + public void testIntroChooseLock() { + final Intent intent = newActivityIntent(); + mContext.startActivity(intent); assertThat(mDevice.wait(Until.hasObject(By.text("Choose your backup screen lock method")), IDLE_TIMEOUT)).isTrue(); } @@ -135,12 +151,12 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchWithGkPwHandle_withUdfps_clickStart() { + public void testIntroWithGkPwHandle_withUdfps_clickStart() { assumeTrue(mCanAssumeUdfps); LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(false); + launchIntroWithGkPwHandle(false); // Intro page verifyIntroPage(); @@ -159,17 +175,16 @@ public class FingerprintEnrollmentActivityTest { startBtn.click(); // Enrolling page - assertThat(mDevice.wait(Until.hasObject(By.text("Touch & hold the fingerprint sensor")), - IDLE_TIMEOUT)).isTrue(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); } @Test - public void testLaunchWithGkPwHandle_withUdfps_clickLottie() { + public void testIntroWithGkPwHandle_withUdfps_clickLottie() { assumeTrue(mCanAssumeUdfps); LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(false); + launchIntroWithGkPwHandle(false); // Intro page verifyIntroPage(); @@ -188,17 +203,16 @@ public class FingerprintEnrollmentActivityTest { lottie.click(); // Enrolling page - assertThat(mDevice.wait(Until.hasObject(By.text("Touch & hold the fingerprint sensor")), - IDLE_TIMEOUT)).isTrue(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); } @Test - public void testLaunchWithGkPwHandle_withSfps() { + public void testIntroWithGkPwHandle_withSfps() { assumeTrue(mCanAssumeSfps); LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(false); + launchIntroWithGkPwHandle(false); // Intro page verifyIntroPage(); @@ -216,12 +230,12 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchWithGkPwHandle_withRfps() { + public void testIntroWithGkPwHandle_withRfps() { assumeFalse(mCanAssumeUdfps || mCanAssumeSfps); LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(false); + launchIntroWithGkPwHandle(false); // Intro page verifyIntroPage(); @@ -241,10 +255,10 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchWithGkPwHandle_clickNoThanksInIntroPage() { + public void testIntroWithGkPwHandle_clickNoThanksInIntroPage() { LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(false); + launchIntroWithGkPwHandle(false); // Intro page verifyIntroPage(); @@ -258,10 +272,10 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchWithGkPwHandle_clickSkipInFindSensor() { + public void testIntroWithGkPwHandle_clickSkipInFindSensor() { LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(false); + launchIntroWithGkPwHandle(false); // Intro page verifyIntroPage(); @@ -282,10 +296,10 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw() { + public void testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw() { LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(true); + launchIntroWithGkPwHandle(true); // Intro page verifyIntroPage(); @@ -315,10 +329,10 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw() { + public void testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw() { LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivityWithGkPwHandle(true); + launchIntroWithGkPwHandle(true); // Intro page verifyIntroPage(); @@ -346,43 +360,138 @@ public class FingerprintEnrollmentActivityTest { } @Test - public void testLaunchCheckPin() { + public void testIntroCheckPin() { LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); - launchFingerprintEnrollActivity(false, null); + final Intent intent = newActivityIntent(); + mContext.startActivity(intent); assertThat(mDevice.wait(Until.hasObject(By.text("Enter your device PIN to continue")), IDLE_TIMEOUT)).isTrue(); } + @Test + public void testEnrollingWithGkPwHandle() { + LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); + + launchEnrollingWithGkPwHandle(); + + // Enrolling screen + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); + } + + @Test + public void testEnrollingIconTouchDialog_withSfps() { + assumeTrue(mCanAssumeSfps); + + LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); + + launchEnrollingWithGkPwHandle(); + + // Enrolling screen + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); + + final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME, + "illustration_lottie")); + assertThat(lottie).isNotNull(); + + lottie.click(); + lottie.click(); + lottie.click(); + + // IconTouchDialog + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text("Touch the sensor instead")), IDLE_TIMEOUT)) + .isTrue(); + final UiObject2 okButton = mDevice.findObject(By.text("OK")); + assertThat(okButton).isNotNull(); + + okButton.click(); + + // Enrolling screen again + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); + } + + @Test + public void testEnrollingIconTouchDialog_withRfps() { + assumeFalse(mCanAssumeUdfps || mCanAssumeSfps); + + LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true); + + launchEnrollingWithGkPwHandle(); + + // Enrolling screen + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); + + final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME, + "fingerprint_progress_bar")); + assertThat(lottie).isNotNull(); + + lottie.click(); + lottie.click(); + lottie.click(); + + // IconTouchDialog + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text("Whoops, that\u2019s not the sensor")), + IDLE_TIMEOUT)).isTrue(); + final UiObject2 okButton = mDevice.findObject(By.text("OK")); + assertThat(okButton).isNotNull(); + + okButton.click(); + + // Enrolling screen again + mDevice.waitForIdle(); + assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue(); + } + @After public void tearDown() throws Exception { LockScreenUtil.resetLockscreen(TEST_PIN); mDevice.pressHome(); } - private void launchFingerprintEnrollActivityWithGkPwHandle(boolean isSuw) { + private void launchIntroWithGkPwHandle(boolean isSuw) { LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); final LockscreenCredential lockscreenCredential = LockscreenCredential.createPin(TEST_PIN); final int userId = UserHandle.myUserId(); final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> { - launchFingerprintEnrollActivity(isSuw, response.getGatekeeperPasswordHandle()); + final Intent intent = newActivityIntent(); + if (isSuw) { + intent.putExtra(EXTRA_IS_SETUP_FLOW, true); + } + intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.getGatekeeperPasswordHandle()); + mContext.startActivity(intent); }; LockPatternChecker.verifyCredential(lockPatternUtils, lockscreenCredential, userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback); } - private void launchFingerprintEnrollActivity(boolean isSuw, Long gkPwHandle) { + private void launchEnrollingWithGkPwHandle() { + LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); + final LockscreenCredential lockscreenCredential = LockscreenCredential.createPin(TEST_PIN); + final int userId = UserHandle.myUserId(); + final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> { + final Intent intent = newActivityIntent(); + intent.putExtra(EXTRA_SKIP_FIND_SENSOR, true); + intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.getGatekeeperPasswordHandle()); + mContext.startActivity(intent); + }; + LockPatternChecker.verifyCredential(lockPatternUtils, lockscreenCredential, + userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback); + } + + @NonNull + private Intent newActivityIntent() { Intent intent = new Intent(); intent.setClassName(SETTINGS_PACKAGE_NAME, ACTIVITY_CLASS_NAME); - if (isSuw) { - intent.putExtra(EXTRA_IS_SETUP_FLOW, true); - } intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true); intent.putExtra(EXTRA_PAGE_TRANSITION_TYPE, 1); intent.putExtra(Intent.EXTRA_USER_ID, mContext.getUserId()); - if (gkPwHandle != null) { - intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle); - } intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); + return intent; + } } diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java index 4de1057436a..fb0937eed37 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java @@ -21,7 +21,6 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFP import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData; -import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP; @@ -103,10 +102,6 @@ public class FingerprintEnrollEnrollingViewModelTest { mViewModel.showIconTouchDialog(); assertThat(actionLiveData.getValue()).isEqualTo( FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG); - - mViewModel.onIconTouchDialogDismiss(); - assertThat(actionLiveData.getValue()).isEqualTo( - FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG); } @Test