diff --git a/res/drawable/ic_event.xml b/res/drawable/ic_event.xml index a82d7544985..1bc8f2c4579 100644 --- a/res/drawable/ic_event.xml +++ b/res/drawable/ic_event.xml @@ -30,5 +30,5 @@ Copyright (C) 2018 The Android Open Source Project android:height="@dimen/dashboard_tile_foreground_image_size" android:start="@dimen/dashboard_tile_foreground_image_inset" android:top="@dimen/dashboard_tile_foreground_image_inset" - android:drawable="@drawable/ic_event_white" /> + android:drawable="@drawable/ic_event_shape" /> diff --git a/res/drawable/ic_event_white.xml b/res/drawable/ic_event_shape.xml similarity index 95% rename from res/drawable/ic_event_white.xml rename to res/drawable/ic_event_shape.xml index d80429b7ec0..25a8ded136e 100644 --- a/res/drawable/ic_event_white.xml +++ b/res/drawable/ic_event_shape.xml @@ -20,6 +20,6 @@ Copyright (C) 2018 The Android Open Source Project android:viewportHeight="24.0"> diff --git a/res/drawable/ic_timelapse.xml b/res/drawable/ic_timelapse.xml index ba97bae8c90..8bf148845d8 100644 --- a/res/drawable/ic_timelapse.xml +++ b/res/drawable/ic_timelapse.xml @@ -30,5 +30,5 @@ Copyright (C) 2018 The Android Open Source Project android:height="@dimen/dashboard_tile_foreground_image_size" android:start="@dimen/dashboard_tile_foreground_image_inset" android:top="@dimen/dashboard_tile_foreground_image_inset" - android:drawable="@drawable/ic_timelapse_white" /> + android:drawable="@drawable/ic_timelapse_shape" /> diff --git a/res/drawable/ic_timelapse_white.xml b/res/drawable/ic_timelapse_shape.xml similarity index 95% rename from res/drawable/ic_timelapse_white.xml rename to res/drawable/ic_timelapse_shape.xml index f287747d2bc..6475e0bdc25 100644 --- a/res/drawable/ic_timelapse_white.xml +++ b/res/drawable/ic_timelapse_shape.xml @@ -20,6 +20,6 @@ Copyright (C) 2018 The Android Open Source Project android:viewportHeight="24.0"> diff --git a/res/layout/setup_choose_lock_generic_biometrics_header.xml b/res/layout/setup_choose_lock_generic_biometrics_header.xml deleted file mode 100644 index daeeedd845d..00000000000 --- a/res/layout/setup_choose_lock_generic_biometrics_header.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - diff --git a/res/layout/setup_choose_lock_generic_header.xml b/res/layout/setup_choose_lock_generic_header.xml deleted file mode 100644 index 7ec16d2c420..00000000000 --- a/res/layout/setup_choose_lock_generic_header.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 2538245311a..5ab4a77b7bb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -147,7 +147,7 @@ Audio during calls Media - + Notifications and other system sounds By default, audio output is determined by individual apps diff --git a/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java b/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java index d58607fa66f..f1a6d363b20 100644 --- a/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java @@ -28,7 +28,6 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.applications.AppInfoBase; import com.android.settings.applications.AppLocaleUtil; import com.android.settings.localepicker.AppLocalePickerActivity; @@ -72,7 +71,6 @@ public class AppLocalePreferenceController extends AppInfoPreferenceControllerBa if (mParent != null) { Intent intent = new Intent(mContext, AppLocalePickerActivity.class); intent.setData(Uri.parse("package:" + mParent.getAppEntry().info.packageName)); - intent.putExtra(AppInfoBase.ARG_PACKAGE_UID, mParent.getAppEntry().info.uid); mContext.startActivity(intent); return true; } else { diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index cb1009a941d..0fbbf18f0a5 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -709,8 +709,8 @@ public class ManageApplications extends InstrumentedFragment case LIST_TYPE_APPS_LOCALE: Intent intent = new Intent(getContext(), AppLocalePickerActivity.class); intent.setData(Uri.parse("package:" + mCurrentPkgName)); - intent.putExtra(AppInfoBase.ARG_PACKAGE_UID, mCurrentUid); - startActivity(intent); + getContext().startActivityAsUser(intent, + UserHandle.getUserHandleForUid(mCurrentUid)); break; case LIST_TYPE_BATTERY_OPTIMIZATION: AdvancedPowerUsageDetail.startBatteryDetailPage( diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index 7c5c77b5350..a19138e2673 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -185,7 +185,9 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase mUserManager = getUserManager(); updatePasswordQuality(); - if (!mConfirmingCredentials) { + // Check isFinishing() because FaceEnrollIntroduction may finish self to launch + // FaceSettings during onCreate() + if (!mConfirmingCredentials && !isFinishing()) { if (!mHasPassword) { // No password registered, launch into enrollment wizard. mConfirmingCredentials = true; diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java index 46c392ed408..f434a67f485 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java @@ -28,6 +28,7 @@ import android.hardware.SensorPrivacyManager; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.face.FaceManager; import android.os.Bundle; +import android.os.UserHandle; import android.text.Html; import android.text.method.LinkMovementMethod; import android.util.Log; @@ -42,6 +43,7 @@ import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; import com.android.settings.R; +import com.android.settings.Settings; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollActivity; import com.android.settings.biometrics.BiometricEnrollIntroduction; @@ -110,8 +112,26 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { @Override protected void onCreate(Bundle savedInstanceState) { + mFaceManager = getFaceManager(); + + if (savedInstanceState == null + && !WizardManagerHelper.isAnySetupWizard(getIntent()) + && !getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false) + && maxFacesEnrolled()) { + // from tips && maxEnrolled + Log.d(TAG, "launch face settings"); + launchFaceSettingsActivity(); + finish(); + } + super.onCreate(savedInstanceState); + // Wait super::onCreated() then return because SuperNotCalledExceptio will be thrown + // if we don't wait for it. + if (isFinishing()) { + return; + } + // Apply extracted theme color to icons. final ImageView iconGlasses = findViewById(R.id.icon_glasses); final ImageView iconLooking = findViewById(R.id.icon_looking); @@ -152,8 +172,6 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { infoMessageRequireEyes.setText(getInfoMessageRequireEyes()); } - mFaceManager = getFaceManager(); - // This path is an entry point for SetNewPasswordController, e.g. // adb shell am start -a android.app.action.SET_NEW_PASSWORD if (mToken == null && BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) { @@ -191,6 +209,24 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { Log.v(TAG, "cameraPrivacyEnabled : " + cameraPrivacyEnabled); } + private void launchFaceSettingsActivity() { + final Intent intent = new Intent(this, Settings.FaceSettingsInternalActivity.class); + final byte[] token = getIntent().getByteArrayExtra( + ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); + if (token != null) { + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); + } + final int userId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); + if (userId != UserHandle.USER_NULL) { + intent.putExtra(Intent.EXTRA_USER_ID, userId); + } + BiometricUtils.copyMultiBiometricExtras(getIntent(), intent); + intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true); + intent.putExtra(EXTRA_KEY_CHALLENGE, getIntent().getLongExtra(EXTRA_KEY_CHALLENGE, -1L)); + intent.putExtra(EXTRA_KEY_SENSOR_ID, getIntent().getIntExtra(EXTRA_KEY_SENSOR_ID, -1)); + startActivity(intent); + } + @VisibleForTesting @Nullable protected FaceManager getFaceManager() { @@ -232,6 +268,15 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { @Override protected void onStart() { super.onStart(); + listenFoldEventForPostureGuidance(); + } + + private void listenFoldEventForPostureGuidance() { + if (maxFacesEnrolled()) { + Log.d(TAG, "Device has enrolled face, do not show posture guidance"); + return; + } + if (getPostureGuidanceIntent() == null) { Log.d(TAG, "Device do not support posture guidance"); return; diff --git a/src/com/android/settings/localepicker/AppLocalePickerActivity.java b/src/com/android/settings/localepicker/AppLocalePickerActivity.java index 6dab5cf8bdc..9efaf63c687 100644 --- a/src/com/android/settings/localepicker/AppLocalePickerActivity.java +++ b/src/com/android/settings/localepicker/AppLocalePickerActivity.java @@ -18,12 +18,10 @@ package com.android.settings.localepicker; import android.app.FragmentTransaction; import android.app.LocaleManager; -import android.content.Context; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.LocaleList; -import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.view.MenuItem; @@ -34,7 +32,6 @@ import android.widget.ListView; import com.android.internal.app.LocalePickerWithRegion; import com.android.internal.app.LocaleStore; import com.android.settings.R; -import com.android.settings.applications.AppInfoBase; import com.android.settings.applications.AppLocaleUtil; import com.android.settings.applications.appinfo.AppLocaleDetails; import com.android.settings.core.SettingsBaseActivity; @@ -46,7 +43,6 @@ public class AppLocalePickerActivity extends SettingsBaseActivity private String mPackageName; private LocalePickerWithRegion mLocalePickerWithRegion; private AppLocaleDetails mAppLocaleDetails; - private Context mContextAsUser; private View mAppLocaleDetailContainer; @Override @@ -64,16 +60,8 @@ public class AppLocalePickerActivity extends SettingsBaseActivity finish(); return; } - mContextAsUser = this; - if (getIntent().hasExtra(AppInfoBase.ARG_PACKAGE_UID)) { - int uid = getIntent().getIntExtra(AppInfoBase.ARG_PACKAGE_UID, -1); - if (uid != -1) { - UserHandle userHandle = UserHandle.getUserHandleForUid(uid); - mContextAsUser = createContextAsUser(userHandle, 0); - } - } - if (!canDisplayLocaleUi() || mContextAsUser.getUserId() != UserHandle.myUserId()) { + if (!canDisplayLocaleUi()) { Log.w(TAG, "Not allow to display Locale Settings UI."); finish(); return; @@ -83,13 +71,13 @@ public class AppLocalePickerActivity extends SettingsBaseActivity getActionBar().setDisplayHomeAsUpEnabled(true); mLocalePickerWithRegion = LocalePickerWithRegion.createLanguagePicker( - mContextAsUser, + this, this, false /* translate only */, null, mPackageName, this); - mAppLocaleDetails = AppLocaleDetails.newInstance(mPackageName, mContextAsUser.getUserId()); + mAppLocaleDetails = AppLocaleDetails.newInstance(mPackageName, getUserId()); mAppLocaleDetailContainer = launchAppLocaleDetailsPage(); // Launch Locale picker part. launchLocalePickerPage(); @@ -129,7 +117,7 @@ public class AppLocalePickerActivity extends SettingsBaseActivity /** Sets the app's locale to the supplied language tag */ private void setAppDefaultLocale(String languageTag) { Log.d(TAG, "setAppDefaultLocale: " + languageTag); - LocaleManager localeManager = mContextAsUser.getSystemService(LocaleManager.class); + LocaleManager localeManager = getSystemService(LocaleManager.class); if (localeManager == null) { Log.w(TAG, "LocaleManager is null, cannot set default app locale"); return; @@ -172,8 +160,8 @@ public class AppLocalePickerActivity extends SettingsBaseActivity private boolean canDisplayLocaleUi() { try { - PackageManager packageManager = mContextAsUser.getPackageManager(); - return AppLocaleUtil.canDisplayLocaleUi(mContextAsUser, + PackageManager packageManager = getPackageManager(); + return AppLocaleUtil.canDisplayLocaleUi(this, packageManager.getApplicationInfo(mPackageName, 0), packageManager.queryIntentActivities(AppLocaleUtil.LAUNCHER_ENTRY_INTENT, PackageManager.GET_META_DATA)); diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java index 797f1eb0ace..17d83b30b88 100644 --- a/src/com/android/settings/password/SetupChooseLockGeneric.java +++ b/src/com/android/settings/password/SetupChooseLockGeneric.java @@ -108,6 +108,7 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric { super.onViewCreated(view, savedInstanceState); GlifPreferenceLayout layout = (GlifPreferenceLayout) view; + layout.setDescriptionText(loadDescriptionText()); layout.setDividerItemDecoration(new SettingsDividerItemDecoration(getContext())); layout.setDividerInset(getContext().getResources().getDimensionPixelSize( R.dimen.sud_items_glif_text_divider_inset)); @@ -128,11 +129,9 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric { @Override protected void addHeaderView() { - if (isForBiometric()) { - setHeaderView(R.layout.setup_choose_lock_generic_biometrics_header); - } else { - setHeaderView(R.layout.setup_choose_lock_generic_header); - } + // The original logic has been moved to onViewCreated and + // uses GlifLayout#setDescriptionText instead, + // keep empty body here since we won't call super method. } @Override @@ -229,6 +228,12 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric { private boolean isForBiometric() { return mForFingerprint || mForFace || mForBiometrics; } + + String loadDescriptionText() { + return getString(isForBiometric() + ? R.string.lock_settings_picker_biometrics_added_security_message + : R.string.setup_lock_settings_picker_message); + } } public static class InternalActivity extends ChooseLockGeneric.InternalActivity { diff --git a/src/com/android/settings/spa/system/AppLanguagesListModel.kt b/src/com/android/settings/spa/system/AppLanguagesListModel.kt index 4aa4c7a5700..3141d68c94f 100644 --- a/src/com/android/settings/spa/system/AppLanguagesListModel.kt +++ b/src/com/android/settings/spa/system/AppLanguagesListModel.kt @@ -21,6 +21,7 @@ import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.net.Uri +import android.os.UserHandle import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.remember @@ -94,9 +95,9 @@ class AppLanguagesListModel(private val context: Context) : AppListModel controller = - initActivityController(true); - controller.create(); - - assertThat(controller.get().isFinishing()).isTrue(); - } - @Test public void launchAppLocalePickerActivity_intentWithoutPackageName_failed() { ActivityController controller = @@ -292,17 +279,4 @@ public class AppLocalePickerActivityTest { sDisAllowPackage = disAllowPackage; } } - - @Implements(UserHandle.class) - public static class ShadowUserHandle { - private static int sUserId = 0; - private static void setUserId(int userId) { - sUserId = userId; - } - - @Implementation - public static int getUserId(int userId) { - return sUserId; - } - } } diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java index cd79f58ee31..494d3f0671b 100644 --- a/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java @@ -23,15 +23,20 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_R import static com.google.common.truth.Truth.assertThat; -import static org.robolectric.Shadows.shadowOf; - import android.content.Intent; +import android.text.TextUtils; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowPasswordUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; +import com.google.android.setupdesign.GlifPreferenceLayout; + import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,6 +46,8 @@ import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowActivity; +import java.util.List; + @RunWith(RobolectricTestRunner.class) @Config(shadows = { ShadowUserManager.class, @@ -78,4 +85,43 @@ public class SetupChooseLockGenericTest { ShadowActivity shadowActivity = Shadows.shadowOf(activity); assertThat(shadowActivity.isFinishing()).isFalse(); } + + @Test + public void setupChooseLockGenericUsingDescriptionTextOfGlifLayout() { + SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(false); + GlifPreferenceLayout view = getViewOfSetupChooseLockGenericFragment(fragment); + assertThat(TextUtils.isEmpty(view.getDescriptionText())).isFalse(); + assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText()); + } + + @Test + public void setupChooseLockGenericUsingDescriptionTextOfGlifLayoutForBiometric() { + SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true); + GlifPreferenceLayout view = getViewOfSetupChooseLockGenericFragment(fragment); + assertThat(TextUtils.isEmpty(view.getDescriptionText())).isFalse(); + assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText()); + } + + private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric(boolean biometric) { + ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY); + Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN"); + intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, biometric); + SetupChooseLockGeneric activity = + Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).setup().get(); + + List fragments = activity.getSupportFragmentManager().getFragments(); + assertThat(fragments).isNotNull(); + assertThat(fragments.size()).isEqualTo(1); + assertThat(fragments.get(0)).isInstanceOf(SetupChooseLockGenericFragment.class); + + return (SetupChooseLockGenericFragment) fragments.get(0); + } + private GlifPreferenceLayout getViewOfSetupChooseLockGenericFragment( + @NonNull SetupChooseLockGenericFragment fragment) { + assertThat(fragment.getView()).isNotNull(); + assertThat(fragment.getView()).isInstanceOf(GlifPreferenceLayout.class); + + return (GlifPreferenceLayout) fragment.getView(); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java index c6c6c556818..f24b2957724 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java @@ -40,6 +40,7 @@ import java.util.Map; public class ShadowLockPatternUtils { private static boolean sDeviceEncryptionEnabled; + private static Map sUserToActivePasswordQualityMap = new HashMap<>(); private static Map sUserToComplexityMap = new HashMap<>(); private static Map sUserToProfileComplexityMap = new HashMap<>(); private static Map sUserToMetricsMap = new HashMap<>(); @@ -54,6 +55,7 @@ public class ShadowLockPatternUtils { @Resetter public static void reset() { + sUserToActivePasswordQualityMap.clear(); sUserToComplexityMap.clear(); sUserToProfileComplexityMap.clear(); sUserToMetricsMap.clear(); @@ -87,7 +89,11 @@ public class ShadowLockPatternUtils { @Implementation protected int getActivePasswordQuality(int userId) { - return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + final Integer activePasswordQuality = sUserToActivePasswordQualityMap.get(userId); + if (activePasswordQuality == null) { + return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + } + return activePasswordQuality; } @Implementation @@ -227,6 +233,10 @@ public class ShadowLockPatternUtils { sUserToProfileMetricsMap.put(UserHandle.myUserId(), metrics); } + public static void setActivePasswordQuality(int quality) { + sUserToActivePasswordQualityMap.put(UserHandle.myUserId(), quality); + } + @Implementation public boolean isLockScreenDisabled(int userId) { return false;