Snap for 7430067 from 603cd6c44c
to sc-release
Change-Id: I584aac141a0a068870cfa7895d3605d79b323a54
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -16,38 +15,42 @@
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="210dp"
|
||||
android:height="210dp"
|
||||
android:viewportHeight="210.0"
|
||||
android:viewportWidth="210.0">
|
||||
android:width="412dp"
|
||||
android:height="300dp"
|
||||
android:viewportHeight="300"
|
||||
android:viewportWidth="412">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_bar"
|
||||
android:pathData="M73.79,58.17h-7V38.96c0,-15.39 9.16,-29.21 23.34,-35.21l2.73,6.45c-11.58,4.9 -19.06,16.19 -19.06,28.76V58.17z" />
|
||||
android:pathData="M206,45.75a38,38,0,0,0-14.87,3h0A38.16,38.16,0,0,0,167.79,84v19.21h7V84A31.17,31.17,0,0,1,193.86,55.2h0a31.24,31.24,0,0,1,38.43,11.93l5.88-3.78A38.08,38.08,0,0,0,206,45.75Z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_bar"
|
||||
android:pathData="M131.29,22.13C125.51,13.12 115.68,7.75 105,7.75c-4.21,0 -8.3,0.82 -12.15,2.45l-2.73,-6.45c4.71,-1.99 9.72,-3 14.87,-3c13.08,0 25.11,6.58 32.18,17.6L131.29,22.13z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_bar"
|
||||
android:pathData="M143.21,62.11h-7V38.96c0,-5.99 -1.7,-11.81 -4.92,-16.83l5.89,-3.78c3.94,6.15 6.03,13.27 6.03,20.6V62.11z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_bar"
|
||||
android:pathData="M136.21,62.11h7v19.4h-7z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:pathData="M125.03,118.78c-0.28,0 -0.55,-0.07 -0.79,-0.2c-6.61,-3.37 -12.33,-4.79 -19.19,-4.79c-6.82,0 -13.3,1.6 -19.19,4.79c-0.83,0.44 -1.86,0.14 -2.34,-0.68c-0.45,-0.82 -0.14,-1.87 0.69,-2.31c6.41,-3.43 13.44,-5.2 20.84,-5.2c7.34,0 13.75,1.6 20.77,5.17c0.86,0.44 1.17,1.46 0.72,2.28C126.24,118.44 125.65,118.78 125.03,118.78z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:pathData="M75.73,136.63c-0.34,0 -0.69,-0.1 -1,-0.31c-0.79,-0.54 -0.96,-1.6 -0.41,-2.38c3.41,-4.76 7.75,-8.5 12.92,-11.12c10.82,-5.51 24.67,-5.54 35.52,-0.03c5.17,2.62 9.51,6.32 12.92,11.05c0.55,0.75 0.38,1.84 -0.41,2.38c-0.79,0.54 -1.86,0.37 -2.41,-0.41c-3.1,-4.28 -7.03,-7.65 -11.68,-10c-9.89,-5 -22.53,-5 -32.38,0.03c-4.69,2.38 -8.61,5.78 -11.71,10.06C76.8,136.39 76.28,136.63 75.73,136.63z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:pathData="M97.27,177.67c-0.45,0 -0.9,-0.17 -1.21,-0.51c-3,-2.96 -4.62,-4.86 -6.92,-8.98c-2.38,-4.18 -3.62,-9.28 -3.62,-14.76c0,-10.1 8.75,-18.33 19.5,-18.33s19.5,8.23 19.5,18.33c0,0.95 -0.76,1.7 -1.72,1.7s-1.72,-0.75 -1.72,-1.7c0,-8.23 -7.2,-14.93 -16.05,-14.93s-16.05,6.7 -16.05,14.93c0,4.9 1.1,9.42 3.2,13.09c2.2,3.91 3.72,5.58 6.37,8.23c0.65,0.68 0.65,1.73 0,2.41C98.16,177.5 97.71,177.67 97.27,177.67z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:pathData="M121.97,171.38c-4.1,0 -7.72,-1.02 -10.68,-3.03c-5.13,-3.43 -8.2,-9.01 -8.2,-14.93c0,-0.95 0.76,-1.7 1.72,-1.7s1.72,0.75 1.72,1.7c0,4.79 2.48,9.32 6.68,12.1c2.45,1.63 5.31,2.41 8.75,2.41c0.83,0 2.2,-0.1 3.58,-0.34c0.93,-0.17 1.83,0.44 2,1.39c0.17,0.92 -0.45,1.8 -1.41,1.97C124.17,171.34 122.45,171.38 121.97,171.38z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:pathData="M115.04,178.38c-0.14,0 -0.31,-0.03 -0.45,-0.07c-5.48,-1.5 -9.06,-3.5 -12.82,-7.14c-4.82,-4.73 -7.48,-11.02 -7.48,-17.75c0,-5.51 4.75,-10 10.61,-10c5.86,0 10.61,4.49 10.61,10c0,3.64 3.2,6.6 7.17,6.6s7.17,-2.96 7.17,-6.6c0,-12.82 -11.2,-23.22 -24.98,-23.22c-9.78,0 -18.74,5.37 -22.77,13.7c-1.34,2.75 -2.03,5.98 -2.03,9.52c0,2.65 0.24,6.83 2.31,12.27c0.34,0.88 -0.1,1.87 -1,2.18c-0.9,0.34 -1.89,-0.14 -2.2,-0.99c-1.69,-4.45 -2.51,-8.87 -2.51,-13.46c0,-4.08 0.79,-7.79 2.34,-11.02c4.58,-9.49 14.75,-15.64 25.87,-15.64c15.68,0 28.42,11.93 28.42,26.62c0,5.51 -4.75,10 -10.61,10c-5.86,0 -10.61,-4.49 -10.61,-10c0,-3.64 -3.2,-6.6 -7.17,-6.6s-7.17,2.96 -7.17,6.6c0,5.81 2.27,11.25 6.44,15.33c3.27,3.2 6.41,4.96 11.27,6.29c0.93,0.24 1.45,1.19 1.21,2.07C116.49,177.87 115.77,178.38 115.04,178.38z" />
|
||||
android:pathData="M238.18,63.35l-5.89,3.78A31.11,31.11,0,0,1,237.21,84v42.55h7V84A38.11,38.11,0,0,0,238.18,63.35Z" />
|
||||
<path
|
||||
android:fillColor="@color/biometric_enroll_intro_color_outline"
|
||||
android:pathData="M170.77,209.25H39.23c-7.72,0 -14,-6.28 -14,-14V93.51c0,-7.72 6.28,-14 14,-14h131.54c7.72,0 14,6.28 14,14v101.74C184.77,202.97 178.49,209.25 170.77,209.25zM39.23,83.51c-5.51,0 -10,4.49 -10,10v101.74c0,5.51 4.49,10 10,10h131.54c5.51,0 10,-4.49 10,-10V93.51c0,-5.51 -4.49,-10 -10,-10H39.23z" />
|
||||
</vector>
|
||||
android:pathData="M271.77,254.25H140.23a14,14,0,0,1-14-14V138.51a14,14,0,0,1,14-14H271.77a14,14,0,0,1,14,14V240.25A14,14,0,0,1,271.77,254.25ZM140.23,128.51a10,10,0,0,0-10,10V240.25a10,10,0,0,0,10,10H271.77a10,10,0,0,0,10-10V138.51a10,10,0,0,0-10-10Z" />
|
||||
<path
|
||||
android:pathData="M184.93,211.5a27.89,27.89,0,0,1-1.48-8.33c0-11.42,9.71-20.71,22.58-20.71s22.58,9.29,22.58,20.71v0.62a7.71,7.71,0,0,1-7.71,7.71,7.63,7.63,0,0,1-7.13-4.84l-2.58-6.45a7.69,7.69,0,0,0-14.84,2.87,17.57,17.57,0,0,0,6.58,13.71l1.49,1.16"
|
||||
android:strokeColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:strokeWidth="4.93" />
|
||||
<path
|
||||
android:pathData="M186.67,161.49a41.14,41.14,0,0,1,38.72,0"
|
||||
android:strokeColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:strokeWidth="4.93" />
|
||||
<path
|
||||
android:pathData="M180.22,182.46c4.58-7.61,14.42-12.9,25.81-12.9s21.23,5.29,25.81,12.9"
|
||||
android:strokeColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:strokeWidth="4.93" />
|
||||
<path
|
||||
android:pathData="M222.16,221.18a23.39,23.39,0,0,1-32.26,0"
|
||||
android:strokeColor="@color/biometric_enroll_intro_color_icon"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:strokeWidth="4.93" />
|
||||
</vector>
|
@@ -908,8 +908,6 @@
|
||||
<string name="security_settings_fingerprint_enroll_introduction_footer_message_3" product="default">Your phone will occasionally use your recent fingerprint images to create improved fingerprint models.</string>
|
||||
<!-- Introduction detail message shown in fingerprint enrollment dialog, when fingerprint unlock is disabled by device admin [CHAR LIMIT=NONE]-->
|
||||
<string name="security_settings_fingerprint_enroll_introduction_message_unlock_disabled">Use your fingerprint to unlock your phone or approve purchases.\n\nNote: You can\u2019t use your fingerprint to unlock this device. For more information, contact your organization\u2019s admin.</string>
|
||||
<!-- Introduction detail message shown in fingerprint enrollment screen in setup wizard. [CHAR LIMIT=NONE]-->
|
||||
<string name="security_settings_fingerprint_enroll_introduction_message_setup">Use your fingerprint to unlock your phone or approve purchases.\n\nNote: Your fingerprint may be less secure than a strong pattern or PIN.</string>
|
||||
<!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_enroll_introduction_cancel">Cancel</string>
|
||||
<!-- Button text to cancel enrollment [CHAR LIMIT=30] -->
|
||||
|
@@ -369,11 +369,11 @@
|
||||
</style>
|
||||
|
||||
<style name="FingerprintLayoutTheme">
|
||||
<item name="android:icon">@drawable/ic_fingerprint_header</item>
|
||||
<item name="android:icon">@drawable/ic_lock</item>
|
||||
</style>
|
||||
|
||||
<style name="FaceLayoutTheme">
|
||||
<item name="android:icon">@drawable/ic_face_header</item>
|
||||
<item name="android:icon">@drawable/ic_lock</item>
|
||||
</style>
|
||||
|
||||
<style name="PreviewPagerPageIndicator">
|
||||
|
@@ -69,6 +69,10 @@ public class AppDashboardFragment extends DashboardFragment {
|
||||
use(SpecialAppAccessPreferenceController.class).setSession(getSettingsLifecycle());
|
||||
mAppsPreferenceController = use(AppsPreferenceController.class);
|
||||
mAppsPreferenceController.setFragment(this /* fragment */);
|
||||
|
||||
final HibernatedAppsPreferenceController hibernatedAppsPreferenceController =
|
||||
use(HibernatedAppsPreferenceController.class);
|
||||
getSettingsLifecycle().addObserver(hibernatedAppsPreferenceController);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -30,40 +30,111 @@ import android.content.pm.PackageManager;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* A preference controller handling the logic for updating summary of hibernated apps.
|
||||
*/
|
||||
public final class HibernatedAppsPreferenceController extends BasePreferenceController {
|
||||
public final class HibernatedAppsPreferenceController extends BasePreferenceController
|
||||
implements LifecycleObserver {
|
||||
private static final String TAG = "HibernatedAppsPrefController";
|
||||
private static final String PROPERTY_HIBERNATION_UNUSED_THRESHOLD_MILLIS =
|
||||
"auto_revoke_unused_threshold_millis2";
|
||||
private static final long DEFAULT_UNUSED_THRESHOLD_MS = TimeUnit.DAYS.toMillis(90);
|
||||
private PreferenceScreen mScreen;
|
||||
private int mUnusedCount = 0;
|
||||
private boolean mLoadingUnusedApps;
|
||||
private final Executor mBackgroundExecutor;
|
||||
private final Executor mMainExecutor;
|
||||
|
||||
public HibernatedAppsPreferenceController(Context context, String preferenceKey) {
|
||||
this(context, preferenceKey, Executors.newSingleThreadExecutor(),
|
||||
context.getMainExecutor());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
HibernatedAppsPreferenceController(Context context, String preferenceKey,
|
||||
Executor bgExecutor, Executor mainExecutor) {
|
||||
super(context, preferenceKey);
|
||||
mBackgroundExecutor = bgExecutor;
|
||||
mMainExecutor = mainExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return isHibernationEnabled() && getNumHibernated() > 0
|
||||
return isHibernationEnabled() && mUnusedCount > 0
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
final int numHibernated = getNumHibernated();
|
||||
return mContext.getResources().getQuantityString(
|
||||
R.plurals.unused_apps_summary, numHibernated, numHibernated);
|
||||
R.plurals.unused_apps_summary, mUnusedCount, mUnusedCount);
|
||||
}
|
||||
|
||||
private int getNumHibernated() {
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mScreen = screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* On lifecycle resume event.
|
||||
*/
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
public void onResume() {
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
private void updatePreference() {
|
||||
if (mScreen == null) {
|
||||
return;
|
||||
}
|
||||
if (!mLoadingUnusedApps) {
|
||||
loadUnusedCount(unusedCount -> {
|
||||
mUnusedCount = unusedCount;
|
||||
mLoadingUnusedApps = false;
|
||||
mMainExecutor.execute(() -> {
|
||||
super.displayPreference(mScreen);
|
||||
Preference pref = mScreen.findPreference(mPreferenceKey);
|
||||
refreshSummary(pref);
|
||||
});
|
||||
});
|
||||
mLoadingUnusedApps = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously load the count of unused apps.
|
||||
*
|
||||
* @param callback callback to call when the number of unused apps is calculated
|
||||
*/
|
||||
private void loadUnusedCount(@NonNull UnusedCountLoadedCallback callback) {
|
||||
mBackgroundExecutor.execute(() -> {
|
||||
final int unusedCount = getUnusedCount();
|
||||
callback.onUnusedCountLoaded(unusedCount);
|
||||
});
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private int getUnusedCount() {
|
||||
// TODO(b/187465752): Find a way to export this logic from PermissionController module
|
||||
final PackageManager pm = mContext.getPackageManager();
|
||||
final AppHibernationManager ahm = mContext.getSystemService(AppHibernationManager.class);
|
||||
@@ -71,6 +142,7 @@ public final class HibernatedAppsPreferenceController extends BasePreferenceCont
|
||||
int numHibernated = hibernatedPackages.size();
|
||||
|
||||
// Also need to count packages that are auto revoked but not hibernated.
|
||||
int numAutoRevoked = 0;
|
||||
final UsageStatsManager usm = mContext.getSystemService(UsageStatsManager.class);
|
||||
final long now = System.currentTimeMillis();
|
||||
final long unusedThreshold = DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS,
|
||||
@@ -97,17 +169,24 @@ public final class HibernatedAppsPreferenceController extends BasePreferenceCont
|
||||
for (String perm : pi.requestedPermissions) {
|
||||
if ((pm.getPermissionFlags(perm, packageName, mContext.getUser())
|
||||
& PackageManager.FLAG_PERMISSION_AUTO_REVOKED) != 0) {
|
||||
numHibernated++;
|
||||
numAutoRevoked++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return numHibernated;
|
||||
return numHibernated + numAutoRevoked;
|
||||
}
|
||||
|
||||
private static boolean isHibernationEnabled() {
|
||||
return DeviceConfig.getBoolean(
|
||||
NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for when we've determined the number of unused apps.
|
||||
*/
|
||||
private interface UnusedCountLoadedCallback {
|
||||
void onUnusedCountLoaded(int unusedCount);
|
||||
}
|
||||
}
|
||||
|
@@ -82,9 +82,6 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
|
||||
protected void initViews() {
|
||||
super.initViews();
|
||||
|
||||
setDescriptionText(
|
||||
R.string.security_settings_fingerprint_enroll_introduction_message_setup);
|
||||
|
||||
FooterButton nextButton = getNextButton();
|
||||
nextButton.setText(
|
||||
this, R.string.security_settings_fingerprint_enroll_introduction_continue_setup);
|
||||
|
@@ -41,9 +41,13 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
@@ -67,12 +71,16 @@ public class HibernatedAppsPreferenceControllerTest {
|
||||
AppHibernationManager mAppHibernationManager;
|
||||
@Mock
|
||||
IUsageStatsManager mIUsageStatsManager;
|
||||
PreferenceScreen mPreferenceScreen;
|
||||
private static final String KEY = "key";
|
||||
private Context mContext;
|
||||
private HibernatedAppsPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
MockitoAnnotations.initMocks(this);
|
||||
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
|
||||
"true", false);
|
||||
@@ -82,7 +90,15 @@ public class HibernatedAppsPreferenceControllerTest {
|
||||
.thenReturn(mAppHibernationManager);
|
||||
when(mContext.getSystemService(UsageStatsManager.class)).thenReturn(
|
||||
new UsageStatsManager(mContext, mIUsageStatsManager));
|
||||
mController = new HibernatedAppsPreferenceController(mContext, KEY);
|
||||
|
||||
PreferenceManager manager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = manager.createPreferenceScreen(mContext);
|
||||
Preference preference = mock(Preference.class);
|
||||
when(preference.getKey()).thenReturn(KEY);
|
||||
mPreferenceScreen.addPreference(preference);
|
||||
|
||||
mController = new HibernatedAppsPreferenceController(mContext, KEY,
|
||||
command -> command.run(), command -> command.run());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,7 +116,9 @@ public class HibernatedAppsPreferenceControllerTest {
|
||||
Arrays.asList(hibernatedPkg, new PackageInfo()));
|
||||
when(mContext.getResources()).thenReturn(mock(Resources.class));
|
||||
|
||||
mController.getSummary();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
|
||||
verify(mContext.getResources()).getQuantityString(anyInt(), eq(1), eq(1));
|
||||
}
|
||||
|
||||
@@ -111,7 +129,9 @@ public class HibernatedAppsPreferenceControllerTest {
|
||||
Arrays.asList(autoRevokedPkg, new PackageInfo()));
|
||||
when(mContext.getResources()).thenReturn(mock(Resources.class));
|
||||
|
||||
mController.getSummary();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
|
||||
verify(mContext.getResources()).getQuantityString(anyInt(), eq(1), eq(1));
|
||||
}
|
||||
|
||||
@@ -123,7 +143,9 @@ public class HibernatedAppsPreferenceControllerTest {
|
||||
Arrays.asList(usedAutoRevokedPkg, new PackageInfo()));
|
||||
when(mContext.getResources()).thenReturn(mock(Resources.class));
|
||||
|
||||
mController.getSummary();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
|
||||
verify(mContext.getResources()).getQuantityString(anyInt(), eq(0), eq(0));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user