diff --git a/res/drawable/ic_android_vd_theme_24.xml b/res/drawable/ic_android_vd_theme_24.xml
new file mode 100644
index 00000000000..65812090007
--- /dev/null
+++ b/res/drawable/ic_android_vd_theme_24.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/res/drawable/ic_database_vd_theme_24.xml b/res/drawable/ic_database_vd_theme_24.xml
new file mode 100644
index 00000000000..713a65e9c57
--- /dev/null
+++ b/res/drawable/ic_database_vd_theme_24.xml
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/res/layout/private_space_pre_finish_delay.xml b/res/layout/private_space_pre_finish_delay.xml
new file mode 100644
index 00000000000..3b620bf256a
--- /dev/null
+++ b/res/layout/private_space_pre_finish_delay.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/navigation/privatespace_main_context_nav.xml b/res/navigation/privatespace_main_context_nav.xml
index 80cd3997c4b..b027d87e556 100644
--- a/res/navigation/privatespace_main_context_nav.xml
+++ b/res/navigation/privatespace_main_context_nav.xml
@@ -46,6 +46,13 @@
android:id="@+id/action_retry_profile_creation"
app:destination="@id/ps_auto_advance_fragment"/>
+
+
+
@@ -64,7 +71,7 @@
android:label="fragment_ps_lock">
+ app:destination="@id/ps_pre_finish_delay_fragment"/>
-
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0f62fc66c39..9fbce465110 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1352,6 +1352,8 @@
Use screen lock
Choose new lock
+
+ Just a sec\u2026
All set!
@@ -1378,12 +1380,6 @@
Set a password for your private space
Set a pattern for your private space
-
- Apps and notifications
-
- Sensitive notifications on lock screen
-
- Show sensitive content when private space is unlocked
Create a Google Account to help keep your data private
@@ -4419,8 +4415,10 @@
Tap to click
-
- Tap dragging
+
+ Tap dragging
+
+ Tap and drag your finger on the touchpad to move objects
Touchpad gestures
@@ -11089,8 +11087,8 @@
]]>
-
- Passwords, passkeys & autofill
+
+ Passwords, passkeys & accounts
diff --git a/res/xml/private_space_settings.xml b/res/xml/private_space_settings.xml
index f9795990903..b1233b9d797 100644
--- a/res/xml/private_space_settings.xml
+++ b/res/xml/private_space_settings.xml
@@ -59,17 +59,6 @@
-
-
-
-
-
-
diff --git a/res/xml/storage_category_fragment.xml b/res/xml/storage_category_fragment.xml
index 2c9588938a2..58bd89138df 100644
--- a/res/xml/storage_category_fragment.xml
+++ b/res/xml/storage_category_fragment.xml
@@ -61,19 +61,31 @@
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
-
-
+ android:order="107"/>
+
+
+
+
+
+ android:order="204" />
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index 7c0f3a6d195..fd866ad8604 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -80,19 +80,31 @@
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
-
-
+ android:order="107"/>
+
+
+
+
+
+ android:order="204" />
diff --git a/res/xml/trackpad_settings.xml b/res/xml/trackpad_settings.xml
index 6601036073f..fcd43a575c9 100644
--- a/res/xml/trackpad_settings.xml
+++ b/res/xml/trackpad_settings.xml
@@ -48,10 +48,10 @@
android:order="30"
settings:keywords="@string/keywords_trackpad_bottom_right_tap"/>
-
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index d44d727390c..e067c730d60 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -54,8 +54,10 @@ import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
+import android.hardware.biometrics.SensorProperties;
import android.hardware.face.Face;
import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.net.ConnectivityManager;
@@ -927,6 +929,23 @@ public final class Utils extends com.android.settingslib.Utils {
return hasFingerprintHardware(context) && hasFaceHardware(context);
}
+ /**
+ * Return true if face is supported as Class 2 biometrics and above on the device, false
+ * otherwise.
+ */
+ public static boolean isFaceNotConvenienceBiometric(@NonNull Context context) {
+ FaceManager faceManager = getFaceManagerOrNull(context);
+ if (faceManager != null) {
+ final List faceProperties =
+ faceManager.getSensorPropertiesInternal();
+ if (!faceProperties.isEmpty()) {
+ final FaceSensorPropertiesInternal props = faceProperties.get(0);
+ return props.sensorStrength != SensorProperties.STRENGTH_CONVENIENCE;
+ }
+ }
+ return false;
+ }
+
/**
* Launches an intent which may optionally have a user id defined.
* @param fragment Fragment to use to launch the activity.
diff --git a/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java b/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
index 479a184752f..44dbac0afb7 100644
--- a/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
+++ b/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
@@ -54,7 +54,12 @@ public class CredentialsPickerActivity extends SettingsActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
- injectFragmentIntoIntent(this, getIntent());
+ final String packageName = getCallingPackage();
+ final Intent intent = getIntent();
+
+ intent.putExtra(DefaultCombinedPicker.EXTRA_PACKAGE_NAME, packageName);
+ injectFragmentIntoIntent(this, intent);
+
super.onCreate(savedInstanceState);
}
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index 197aca03e0b..3398c203c65 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -201,8 +201,9 @@ public class FaceSettings extends DashboardFragment {
}
mRemoveController.setUserId(mUserId);
- // Don't show keyguard controller for work profile settings.
- if (mUserManager.isManagedProfile(mUserId)) {
+ // Don't show keyguard controller for work and private profile settings.
+ if (mUserManager.isManagedProfile(mUserId)
+ || mUserManager.getUserInfo(mUserId).isPrivateProfile()) {
removePreference(FaceSettingsKeyguardPreferenceController.KEY);
removePreference(mLockscreenController.getPreferenceKey());
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index 54935ecf4de..4906cf2d8d8 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -30,8 +30,10 @@ import android.content.pm.UserInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.MediaColumns;
@@ -94,6 +96,7 @@ public class StorageAsyncLoader
media /* queryArgs */);
result.audioSize = getFilesSize(info.id, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
media /* queryArgs */);
+ result.systemSize = getSystemSize();
final Bundle documentsAndOtherQueryArgs = new Bundle();
documentsAndOtherQueryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
@@ -140,6 +143,16 @@ public class StorageAsyncLoader
}
}
+ private long getSystemSize() {
+ try {
+ return mStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
+ - Environment.getDataDirectory().getTotalSpace();
+ } catch (IOException e) {
+ Log.e(TAG, "Exception in calculating System category size", e);
+ return 0;
+ }
+ }
+
private StorageResult getAppsAndGamesSize(int userId) {
Log.d(TAG, "Loading apps");
final List applicationInfos =
@@ -225,6 +238,7 @@ public class StorageAsyncLoader
public long videosSize;
public long documentsAndOtherSize;
public long trashSize;
+ public long systemSize;
public long cacheSize;
public long duplicateCodeSize;
diff --git a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
index e6da454f2f1..50690cb0791 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
@@ -35,6 +35,7 @@ public class StorageCacheHelper {
private static final String DOCUMENTS_AND_OTHER_SIZE_KEY = "documents_and_other_size_key";
private static final String TRASH_SIZE_KEY = "trash_size_key";
private static final String SYSTEM_SIZE_KEY = "system_size_key";
+ private static final String TEMPORARY_FILES_SIZE_KEY = "temporary_files_size_key";
private static final String USED_SIZE_KEY = "used_size_key";
private final SharedPreferences mSharedPreferences;
@@ -66,6 +67,7 @@ public class StorageCacheHelper {
.putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, data.documentsAndOtherSize)
.putLong(TRASH_SIZE_KEY, data.trashSize)
.putLong(SYSTEM_SIZE_KEY, data.systemSize)
+ .putLong(TEMPORARY_FILES_SIZE_KEY, data.temporaryFilesSize)
.apply();
}
@@ -109,6 +111,7 @@ public class StorageCacheHelper {
result.documentsAndOtherSize = mSharedPreferences.getLong(DOCUMENTS_AND_OTHER_SIZE_KEY, 0);
result.trashSize = mSharedPreferences.getLong(TRASH_SIZE_KEY, 0);
result.systemSize = mSharedPreferences.getLong(SYSTEM_SIZE_KEY, 0);
+ result.temporaryFilesSize = mSharedPreferences.getLong(TEMPORARY_FILES_SIZE_KEY, 0);
return result;
}
@@ -126,5 +129,6 @@ public class StorageCacheHelper {
public long documentsAndOtherSize;
public long trashSize;
public long systemSize;
+ public long temporaryFilesSize;
}
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index fd424178f0c..62422ca1ea5 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -27,6 +27,7 @@ import android.content.pm.UserInfo;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -40,6 +41,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -52,6 +54,7 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.deviceinfo.storage.StorageUtils.SystemInfoFragment;
+import com.android.settings.deviceinfo.storage.StorageUtils.TemporaryFilesInfoFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -74,6 +77,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private static final String TAG = "StorageItemPreference";
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
+ private static final String TEMPORARY_FILES_FRAGMENT_TAG = "TemporaryFilesInfo";
@VisibleForTesting
static final String PUBLIC_STORAGE_KEY = "pref_public_storage";
@@ -92,6 +96,10 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@VisibleForTesting
static final String SYSTEM_KEY = "pref_system";
@VisibleForTesting
+ static final String TEMPORARY_FILES_KEY = "temporary_files";
+ @VisibleForTesting
+ static final String CATEGORY_SPLITTER = "storage_category_splitter";
+ @VisibleForTesting
static final String TRASH_KEY = "pref_trash";
@VisibleForTesting
@@ -133,9 +141,13 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@VisibleForTesting
@Nullable StorageItemPreference mDocumentsAndOtherPreference;
@VisibleForTesting
+ @Nullable StorageItemPreference mTrashPreference;
+ @VisibleForTesting
@Nullable StorageItemPreference mSystemPreference;
@VisibleForTesting
- @Nullable StorageItemPreference mTrashPreference;
+ @Nullable StorageItemPreference mTemporaryFilesPreference;
+ @VisibleForTesting
+ @Nullable PreferenceCategory mCategorySplitterPreferenceCategory;
private final int mProfileType;
@@ -220,6 +232,13 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
dialog.setTargetFragment(mFragment, 0);
dialog.show(mFragment.getFragmentManager(), SYSTEM_FRAGMENT_TAG);
return true;
+ case TEMPORARY_FILES_KEY:
+ final TemporaryFilesInfoFragment temporaryFilesDialog =
+ new TemporaryFilesInfoFragment();
+ temporaryFilesDialog.setTargetFragment(mFragment, 0);
+ temporaryFilesDialog.show(mFragment.getFragmentManager(),
+ TEMPORARY_FILES_FRAGMENT_TAG);
+ return true;
case TRASH_KEY:
launchTrashIntent();
return true;
@@ -285,6 +304,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mAppsPreference.setVisible(visible);
mGamesPreference.setVisible(visible);
mSystemPreference.setVisible(visible);
+ mTemporaryFilesPreference.setVisible(visible);
+ mCategorySplitterPreferenceCategory.setVisible(visible);
mTrashPreference.setVisible(visible);
// If we don't have a shared volume for our internal storage (or the shared volume isn't
@@ -315,7 +336,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mPrivateStorageItemPreferences.add(mAppsPreference);
mPrivateStorageItemPreferences.add(mGamesPreference);
mPrivateStorageItemPreferences.add(mDocumentsAndOtherPreference);
- mPrivateStorageItemPreferences.add(mSystemPreference);
mPrivateStorageItemPreferences.add(mTrashPreference);
}
mScreen.removePreference(mImagesPreference);
@@ -324,7 +344,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mScreen.removePreference(mAppsPreference);
mScreen.removePreference(mGamesPreference);
mScreen.removePreference(mDocumentsAndOtherPreference);
- mScreen.removePreference(mSystemPreference);
mScreen.removePreference(mTrashPreference);
// Sort display order by size.
@@ -361,6 +380,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
tintPreference(mGamesPreference);
tintPreference(mDocumentsAndOtherPreference);
tintPreference(mSystemPreference);
+ tintPreference(mTemporaryFilesPreference);
tintPreference(mTrashPreference);
}
@@ -389,7 +409,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mAppsPreference = screen.findPreference(APPS_KEY);
mGamesPreference = screen.findPreference(GAMES_KEY);
mDocumentsAndOtherPreference = screen.findPreference(DOCUMENTS_AND_OTHER_KEY);
+ mCategorySplitterPreferenceCategory = screen.findPreference(CATEGORY_SPLITTER);
mSystemPreference = screen.findPreference(SYSTEM_KEY);
+ mTemporaryFilesPreference = screen.findPreference(TEMPORARY_FILES_KEY);
mTrashPreference = screen.findPreference(TRASH_KEY);
}
@@ -417,6 +439,12 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize, animate);
if (mSystemPreference != null) {
mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
+ mSystemPreference.setTitle(mContext.getString(R.string.storage_os_name,
+ Build.VERSION.RELEASE));
+ }
+ if (mTemporaryFilesPreference != null) {
+ mTemporaryFilesPreference.setStorageSize(storageCache.temporaryFilesSize, mTotalSize,
+ animate);
}
// Cache the size info
if (result != null) {
@@ -445,6 +473,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
storageCache.gamesSize = data.gamesSize;
storageCache.documentsAndOtherSize = data.documentsAndOtherSize;
storageCache.trashSize = data.trashSize;
+ storageCache.systemSize = data.systemSize;
// Everything else that hasn't already been attributed is tracked as
// belonging to system.
long attributedSize = 0;
@@ -460,7 +489,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
+ otherData.allAppsExceptGamesSize;
attributedSize -= otherData.duplicateCodeSize;
}
- storageCache.systemSize = Math.max(DataUnit.GIBIBYTES.toBytes(1),
+ // System size is equal for each user and should be added only once
+ attributedSize += data.systemSize;
+ storageCache.temporaryFilesSize = Math.max(DataUnit.GIBIBYTES.toBytes(1),
mUsedBytes - attributedSize);
return storageCache;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUtils.java b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
index 4b6a2c40fd8..5c4a4b40f2a 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUtils.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
@@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Bundle;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
@@ -34,6 +33,7 @@ import android.text.format.Formatter;
import android.util.Log;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
@@ -206,7 +206,7 @@ public class StorageUtils {
/** Shows information about system storage. */
public static class SystemInfoFragment extends InstrumentedDialogFragment {
/** Shows the fragment. */
- public static void show(Fragment parent) {
+ public static void show(@NonNull Fragment parent) {
if (!parent.isAdded()) return;
final SystemInfoFragment dialog = new SystemInfoFragment();
@@ -222,8 +222,33 @@ public class StorageUtils {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
- .setMessage(getContext().getString(R.string.storage_detail_dialog_system,
- Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY))
+ .setMessage(getContext().getString(R.string.storage_os_detail_dialog_system))
+ .setPositiveButton(android.R.string.ok, null)
+ .create();
+ }
+ }
+
+ /** Shows information about temporary system files. */
+ public static class TemporaryFilesInfoFragment extends InstrumentedDialogFragment {
+ /** Shows the fragment. */
+ public static void show(@NonNull Fragment parent) {
+ if (!parent.isAdded()) return;
+
+ final TemporaryFilesInfoFragment dialog = new TemporaryFilesInfoFragment();
+ dialog.setTargetFragment(parent, 0);
+ dialog.show(parent.getFragmentManager(), "temporaryFilesInfo");
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DIALOG_TEMPORARY_FILES_INFO;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(getContext().getString(
+ R.string.storage_other_files_detail_dialog_system))
.setPositiveButton(android.R.string.ok, null)
.create();
}
diff --git a/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java b/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java
index 7d551eeaf89..14627ecbf25 100644
--- a/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java
+++ b/src/com/android/settings/privatespace/AutoAdvanceSetupFragment.java
@@ -60,7 +60,7 @@ public class AutoAdvanceSetupFragment extends InstrumentedFragment {
private static final int ANIMATION_DURATION_MILLIS = 500;
private static final int HEADER_TEXT_MAX_LINES = 4;
private GlifLayout mRootView;
- private Handler mHandler;
+ private static final Handler sHandler = new Handler(Looper.getMainLooper());
private int mScreenTitleIndex;
private static final List> HEADER_ILLUSTRATION_PAIRS =
ImmutableList.of(
@@ -78,7 +78,7 @@ public class AutoAdvanceSetupFragment extends InstrumentedFragment {
if (getActivity() != null) {
if (++mScreenTitleIndex < HEADER_ILLUSTRATION_PAIRS.size()) {
startFadeOutAnimation();
- mHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
+ sHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
} else if (PrivateSpaceMaintainer.getInstance(getActivity())
.doesPrivateSpaceExist()) {
mMetricsFeatureProvider.action(
@@ -133,8 +133,6 @@ public class AutoAdvanceSetupFragment extends InstrumentedFragment {
mRootView.getHeaderTextView().setBreakStrategy(BREAK_STRATEGY_SIMPLE);
mRootView.getHeaderTextView().setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
updateHeaderAndIllustration();
- mHandler = new Handler(Looper.getMainLooper());
- mHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
OnBackPressedCallback callback =
new OnBackPressedCallback(true /* enabled by default */) {
@Override
@@ -155,12 +153,16 @@ public class AutoAdvanceSetupFragment extends InstrumentedFragment {
@Override
public void onDestroy() {
- if (mHandler != null) {
- mHandler.removeCallbacks(mUpdateScreenResources);
- }
+ sHandler.removeCallbacks(mUpdateScreenResources);
super.onDestroy();
}
+ @Override
+ public void onResume() {
+ sHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS);
+ super.onResume();
+ }
+
@Override
public int getMetricsCategory() {
return SettingsEnums.PRIVATE_SPACE_SETUP_SPACE_CREATION;
diff --git a/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java b/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java
deleted file mode 100644
index 6cb54a1cd89..00000000000
--- a/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsController.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2024 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.privatespace;
-
-import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
-
-import android.content.Context;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-
-import com.android.settings.core.TogglePreferenceController;
-
-import java.util.Objects;
-
-/**
- * A controller object for sensitive notifications in Private Space settings page.
- */
-public class HidePrivateSpaceSensitiveNotificationsController extends TogglePreferenceController {
- private final PrivateSpaceMaintainer mPrivateSpaceMaintainer;
- private final UserHandle mPrivateProfileId;
- public static final int ENABLED = 1;
- public static final int DISABLED = 0;
- private static final int DEVICE_SENSITIVE_NOTIFICATIONS_DEFAULT = ENABLED;
- private static final int DEVICE_LOCK_SCREEN_NOTIFICATIONS_DEFAULT = ENABLED;
- private static final int PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DEFAULT = DISABLED;
-
- public HidePrivateSpaceSensitiveNotificationsController(@NonNull Context context,
- @NonNull String preferenceKey) {
- super(context, preferenceKey);
- mPrivateSpaceMaintainer = PrivateSpaceMaintainer.getInstance(context);
- mPrivateProfileId = Objects.requireNonNull(
- mPrivateSpaceMaintainer.getPrivateProfileHandle());
- }
-
- @Override
- public int getAvailabilityStatus() {
- if (!android.os.Flags.allowPrivateProfile()
- || !android.multiuser.Flags.enablePsSensitiveNotificationsToggle()
- || !android.multiuser.Flags.enablePrivateSpaceFeatures()
- || !mPrivateSpaceMaintainer.doesPrivateSpaceExist()) {
- return UNSUPPORTED_ON_DEVICE;
- }
- if (!getLockscreenNotificationsEnabled(mContext)
- || !getLockscreenSensitiveNotificationsEnabledOnDevice(mContext)) {
- return DISABLED_DEPENDENT_SETTING;
- }
- return AVAILABLE;
- }
-
- @Override
- public boolean isChecked() {
- return Settings.Secure.getIntForUser(mContext.getContentResolver(),
- LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DEFAULT, mPrivateProfileId.getIdentifier())
- != DISABLED;
- }
-
- @Override
- public boolean setChecked(boolean isChecked) {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- isChecked ? ENABLED : DISABLED, mPrivateProfileId.getIdentifier());
- return true;
- }
-
- @Override
- public int getSliceHighlightMenuRes() {
- return 0;
- }
-
- /**
- * If notifications are disabled on the device, the toggle for private space sensitive
- * notifications should be unavailable.
- */
- private static boolean getLockscreenNotificationsEnabled(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- DEVICE_LOCK_SCREEN_NOTIFICATIONS_DEFAULT) != DISABLED;
- }
-
- /**
- * If sensitive notifications are hidden on the device, they should be hidden for private space
- * also.
- */
- private static boolean getLockscreenSensitiveNotificationsEnabledOnDevice(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- DEVICE_SENSITIVE_NOTIFICATIONS_DEFAULT) != DISABLED;
- }
-}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
index a0c4cbecaed..300cbdbb2fb 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
@@ -65,6 +65,8 @@ public class PrivateSpaceMaintainer {
@Settings.Secure.PrivateSpaceAutoLockOption
public static final int PRIVATE_SPACE_AUTO_LOCK_DEFAULT_VAL =
PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART;
+ /** Default value for the hide private space sensitive notifications on lockscreen. */
+ public static final int HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL = 0;
public enum ErrorDeletingPrivateSpace {
DELETE_PS_ERROR_NONE,
@@ -287,6 +289,14 @@ public class PrivateSpaceMaintainer {
}
}
+ /**
+ * Returns true if private profile can be added to the device or if private space already
+ * exists, false otherwise.
+ */
+ public boolean isPrivateSpaceEntryPointEnabled() {
+ return mUserManager.canAddPrivateProfile() || doesPrivateSpaceExist();
+ }
+
/** Returns true if private space exists and is running, otherwise returns false */
@VisibleForTesting
synchronized boolean isPrivateProfileRunning() {
@@ -308,7 +318,7 @@ public class PrivateSpaceMaintainer {
private void setPrivateSpaceSensitiveNotificationsDefaultValue() {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- HidePrivateSpaceSensitiveNotificationsController.DISABLED,
+ HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL,
mUserHandle.getIdentifier());
}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java b/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
index 3272f125756..9a018539b0e 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
@@ -52,9 +52,7 @@ public final class PrivateSpaceSafetySource {
// Do not add the entry point when
// -Private Profile is not present and
// -Private Profile cannot be added.
- if (!privateSpaceMaintainer.doesPrivateSpaceExist()
- && userManager != null
- && !userManager.canAddPrivateProfile()) {
+ if (!privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()) {
Log.i(TAG, "Private Space not allowed for user " + context.getUser());
return;
}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java b/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java
index 399c2c82fbb..11f4bcb74e3 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java
@@ -97,7 +97,7 @@ public class PrivateSpaceSetLockFragment extends InstrumentedFragment {
getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_USE_SCREEN_LOCK);
// Simply Use default screen lock. No need to handle
NavHostFragment.findNavController(PrivateSpaceSetLockFragment.this)
- .navigate(R.id.action_lock_success_fragment);
+ .navigate(R.id.action_pre_finish_delay_fragment);
};
}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java b/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java
index ec7132adf0e..4cbcac74646 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSetupActivity.java
@@ -60,7 +60,7 @@ public class PrivateSpaceSetupActivity extends FragmentActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == SET_LOCK_ACTION && resultCode == RESULT_OK) {
- mNavHostFragment.getNavController().navigate(R.id.action_success_fragment);
+ mNavHostFragment.getNavController().navigate(R.id.action_pre_finish_delay_fragment);
} else if (requestCode == ACCOUNT_LOGIN_ACTION) {
if (resultCode == RESULT_OK) {
mMetricsFeatureProvider.action(
diff --git a/src/com/android/settings/privatespace/SetupPreFinishDelayFragment.java b/src/com/android/settings/privatespace/SetupPreFinishDelayFragment.java
new file mode 100644
index 00000000000..aee8512ec9b
--- /dev/null
+++ b/src/com/android/settings/privatespace/SetupPreFinishDelayFragment.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2024 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.privatespace;
+
+import static android.content.Intent.ACTION_PROFILE_INACCESSIBLE;
+import static android.content.Intent.ACTION_PROFILE_UNAVAILABLE;
+
+import android.app.settings.SettingsEnums;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.activity.OnBackPressedCallback;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.navigation.fragment.NavHostFragment;
+
+import com.android.settings.R;
+import com.android.settings.core.InstrumentedFragment;
+
+import com.google.android.setupdesign.GlifLayout;
+
+public class SetupPreFinishDelayFragment extends InstrumentedFragment {
+ private static final String TAG = "SetupPreFinishDelayFrag";
+ private static final Handler sHandler = new Handler(Looper.getMainLooper());
+ private static final int MAX_DELAY_BEFORE_SETUP_FINISH = 5000;
+ private boolean mActionProfileUnavailable;
+ private boolean mActionProfileInaccessible;
+
+ protected final BroadcastReceiver mBroadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+ String action = intent.getAction();
+ Log.i(TAG, "Received broadcast: " + action);
+ if (ACTION_PROFILE_UNAVAILABLE.equals(action)) {
+ mActionProfileUnavailable = true;
+ } else if (ACTION_PROFILE_INACCESSIBLE.equals(action)) {
+ mActionProfileInaccessible = true;
+ }
+ if (mActionProfileUnavailable && mActionProfileInaccessible) {
+ showSetupSuccessScreen();
+ }
+ }
+ };
+
+ private Runnable mRunnable =
+ () -> {
+ showSetupSuccessScreen();
+ };
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()) {
+ super.onCreate(savedInstanceState);
+ }
+ }
+
+ @NonNull
+ @Override
+ public View onCreateView(
+ @NonNull LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ GlifLayout rootView =
+ (GlifLayout)
+ inflater.inflate(R.layout.private_space_pre_finish_delay, container, false);
+ OnBackPressedCallback callback =
+ new OnBackPressedCallback(true /* enabled by default */) {
+ @Override
+ public void handleOnBackPressed() {
+ // Handle the back button event. We intentionally don't want to allow back
+ // button to work in this screen during the setup flow.
+ }
+ };
+ requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
+ if (savedInstanceState == null) {
+ // TODO(b/307729746): Add a test to verify PS is locked after setup completion.
+ PrivateSpaceMaintainer.getInstance(getActivity()).lockPrivateSpace();
+ }
+ return rootView;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ getActivity().unregisterReceiver(mBroadcastReceiver);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_PROFILE_UNAVAILABLE);
+ intentFilter.addAction(ACTION_PROFILE_INACCESSIBLE);
+ getActivity().registerReceiver(mBroadcastReceiver, intentFilter);
+ sHandler.postDelayed(mRunnable, MAX_DELAY_BEFORE_SETUP_FINISH);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.PRIVATE_SPACE_SETUP_PRE_FINISH;
+ }
+
+ private void showSetupSuccessScreen() {
+ sHandler.removeCallbacks(mRunnable);
+ NavHostFragment.findNavController(SetupPreFinishDelayFragment.this)
+ .navigate(R.id.action_success_fragment);
+ }
+}
diff --git a/src/com/android/settings/privatespace/SetupSuccessFragment.java b/src/com/android/settings/privatespace/SetupSuccessFragment.java
index c0a2cd4d87a..90be48ea9a4 100644
--- a/src/com/android/settings/privatespace/SetupSuccessFragment.java
+++ b/src/com/android/settings/privatespace/SetupSuccessFragment.java
@@ -87,8 +87,6 @@ public class SetupSuccessFragment extends InstrumentedFragment {
if (activity != null) {
mMetricsFeatureProvider.action(
getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_DONE);
- //TODO(b/307729746): Add a test to verify PS is locked after setup completion.
- PrivateSpaceMaintainer.getInstance(activity).lockPrivateSpace();
Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
ResolveInfo resolveInfo =
activity.getPackageManager()
diff --git a/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java b/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java
index 274bb2b184b..6e1f0df96d5 100644
--- a/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java
+++ b/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceController.java
@@ -59,10 +59,9 @@ public class ResetOptionsDeletePrivateSpaceController extends BasePreferenceCont
@Override
public int getAvailabilityStatus() {
- // TODO(b/330396315) : use canAddPrivateProfile() to check if private space is supported
- // on the device
return android.multiuser.Flags.enablePrivateSpaceFeatures()
&& android.multiuser.Flags.deletePrivateSpaceFromReset()
+ && isPrivateSpaceEntryPointEnabled()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -107,6 +106,11 @@ public class ResetOptionsDeletePrivateSpaceController extends BasePreferenceCont
return mHostFragment.getFragmentManager();
}
+ @VisibleForTesting
+ boolean isPrivateSpaceEntryPointEnabled() {
+ return PrivateSpaceMaintainer.getInstance(mContext).isPrivateSpaceEntryPointEnabled();
+ }
+
/* Dialog shown when deleting private space from Reset Options. */
public static class DeletePrivateSpaceDialogFragment extends InstrumentedDialogFragment {
private static final String TAG = "PrivateSpaceResetFrag";
diff --git a/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java b/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java
index 583a093dbc2..6ccaacb4b4d 100644
--- a/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java
+++ b/src/com/android/settings/privatespace/onelock/PrivateSpaceFacePreferenceController.java
@@ -64,8 +64,8 @@ public class PrivateSpaceFacePreferenceController extends BiometricFaceStatusPre
@Override
public int getAvailabilityStatus() {
return android.os.Flags.allowPrivateProfile()
- && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
- && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -87,7 +87,8 @@ public class PrivateSpaceFacePreferenceController extends BiometricFaceStatusPre
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey());
- if (!Utils.isMultipleBiometricsSupported(mContext)) {
+ if (!Utils.isMultipleBiometricsSupported(mContext)
+ && Utils.isFaceNotConvenienceBiometric(mContext)) {
preference.setTitle(R.string.private_space_face_title);
}
}
diff --git a/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java b/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java
index f88c9facccc..dd6518af67c 100644
--- a/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java
+++ b/src/com/android/settings/privatespace/onelock/PrivateSpaceFingerprintPreferenceController.java
@@ -66,8 +66,8 @@ public class PrivateSpaceFingerprintPreferenceController
@Override
public int getAvailabilityStatus() {
return android.os.Flags.allowPrivateProfile()
- && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
- && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -89,7 +89,8 @@ public class PrivateSpaceFingerprintPreferenceController
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey());
- if (!Utils.isMultipleBiometricsSupported(mContext)) {
+ if (!Utils.isMultipleBiometricsSupported(mContext)
+ || !Utils.isFaceNotConvenienceBiometric(mContext)) {
preference.setTitle(R.string.private_space_fingerprint_title);
}
}
diff --git a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
index ce017e31152..bf5748e6e2b 100644
--- a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
+++ b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
@@ -73,13 +73,14 @@ public class UseOneLockSettingsFragment extends DashboardFragment {
final List controllers = new ArrayList<>();
controllers.add(new UseOneLockControllerSwitch(context, this));
controllers.add(new PrivateSpaceLockController(context, this));
- if (Utils.isMultipleBiometricsSupported(context)) {
+ boolean isFaceAuthAllowed = Utils.isFaceNotConvenienceBiometric(context);
+ if (Utils.isMultipleBiometricsSupported(context) && isFaceAuthAllowed) {
controllers.add(new FaceFingerprintUnlockController(context, getSettingsLifecycle()));
} else if (Utils.hasFingerprintHardware(context)) {
controllers.add(
new PrivateSpaceFingerprintPreferenceController(
context, "private_space_biometrics", getSettingsLifecycle()));
- } else if (Utils.hasFaceHardware(context)) {
+ } else if (Utils.hasFaceHardware(context) && isFaceAuthAllowed) {
controllers.add(
new PrivateSpaceFacePreferenceController(
context, "private_space_biometrics", getSettingsLifecycle()));
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index 0c555da2075..0c57b014506 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -16,6 +16,10 @@
package com.android.settings;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_CONVENIENCE;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNull;
@@ -43,6 +47,9 @@ import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.VectorDrawable;
+import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorProperties;
+import android.hardware.face.FaceSensorPropertiesInternal;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -433,6 +440,69 @@ public class UtilsTest {
assertNull(confirmCredentialString);
}
+ @Test
+ public void isFaceNotConvenienceBiometric_faceStrengthStrong_shouldReturnTrue() {
+ FaceManager mockFaceManager = mock(FaceManager.class);
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
+ doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ List props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ STRENGTH_STRONG,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
+
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue();
+ }
+
+ @Test
+ public void isFaceNotConvenienceBiometric_faceStrengthWeak_shouldReturnTrue() {
+ FaceManager mockFaceManager = mock(FaceManager.class);
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
+ doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ List props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ STRENGTH_WEAK,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
+
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue();
+ }
+
+ @Test
+ public void isFaceNotConvenienceBiometric_faceStrengthConvenience_shouldReturnFalse() {
+ FaceManager mockFaceManager = mock(FaceManager.class);
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
+ doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ List props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ STRENGTH_CONVENIENCE,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
+
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse();
+ }
+
+ @Test
+ public void isFaceNotConvenienceBiometric_faceManagerNull_shouldReturnFalse() {
+ when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(null);
+ assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse();
+ }
+
private void setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile) {
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
index 9e20e78c03a..a26ea1dfca2 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
@@ -41,6 +41,7 @@ public class StorageCacheHelperTest {
private static final long FAKE_TOTAL_SIZE = 256000L;
private static final long FAKE_TOTAL_USED_SIZE = 50000L;
private static final long FAKE_USED_SIZE = 6500L;
+ private static final long FAKE_TEMPORARY_FILES_SIZE = 2500L;
private Context mContext;
private StorageCacheHelper mHelper;
@@ -70,6 +71,7 @@ public class StorageCacheHelperTest {
StorageCacheHelper.StorageCache storageCache = mHelper.retrieveCachedSize();
assertThat(storageCache.imagesSize).isEqualTo(FAKE_IMAGES_SIZE);
+ assertThat(storageCache.temporaryFilesSize).isEqualTo(FAKE_TEMPORARY_FILES_SIZE);
assertThat(storageCache.totalSize).isEqualTo(0);
}
@@ -100,6 +102,7 @@ public class StorageCacheHelperTest {
result.gamesSize = FAKE_GAMES_SIZE;
result.videosSize = FAKE_VIDEOS_SIZE;
result.allAppsExceptGamesSize = FAKE_APPS_SIZE;
+ result.temporaryFilesSize = FAKE_TEMPORARY_FILES_SIZE;
return result;
}
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index b61f5ab4ef4..2590f52340f 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -45,6 +45,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -126,7 +127,10 @@ public class StorageItemPreferenceControllerTest {
final StorageItemPreference documentsAndOther = spy(new StorageItemPreference(mContext));
documentsAndOther.setIcon(R.drawable.ic_folder_vd_theme_24);
final StorageItemPreference system = spy(new StorageItemPreference(mContext));
- system.setIcon(com.android.settingslib.R.drawable.ic_system_update);
+ system.setIcon(R.drawable.ic_android_vd_theme_24);
+ final StorageItemPreference temporaryFiles = spy(new StorageItemPreference(mContext));
+ temporaryFiles.setIcon(R.drawable.ic_database_vd_theme_24);
+ final PreferenceCategory categorySplitter = spy(new PreferenceCategory(mContext));
final StorageItemPreference trash = spy(new StorageItemPreference(mContext));
trash.setIcon(R.drawable.ic_trash_can);
@@ -147,6 +151,10 @@ public class StorageItemPreferenceControllerTest {
.thenReturn(documentsAndOther);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
+ when(screen.findPreference(eq(StorageItemPreferenceController.TEMPORARY_FILES_KEY)))
+ .thenReturn(temporaryFiles);
+ when(screen.findPreference(eq(StorageItemPreferenceController.CATEGORY_SPLITTER)))
+ .thenReturn(categorySplitter);
when(screen.findPreference(eq(StorageItemPreferenceController.TRASH_KEY)))
.thenReturn(trash);
@@ -219,6 +227,7 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
+ assertThat(mController.mTemporaryFilesPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
}
@@ -329,6 +338,16 @@ public class StorageItemPreferenceControllerTest {
.add(nullable(StorageUtils.SystemInfoFragment.class), nullable(String.class));
}
+ @Test
+ public void testClickTemporaryFiles() {
+ mPreference.setKey(StorageItemPreferenceController.TEMPORARY_FILES_KEY);
+ assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
+
+ verify(mFragment.getFragmentManager().beginTransaction())
+ .add(nullable(StorageUtils.TemporaryFilesInfoFragment.class),
+ nullable(String.class));
+ }
+
@Test
@Config(shadows = ShadowUserManager.class)
public void testMeasurementCompletedUpdatesPreferences() {
@@ -343,6 +362,7 @@ public class StorageItemPreferenceControllerTest {
result.documentsAndOtherSize = MEGABYTE_IN_BYTES * 50;
result.trashSize = KILOBYTE_IN_BYTES * 100;
result.allAppsExceptGamesSize = MEGABYTE_IN_BYTES * 90;
+ result.systemSize = MEGABYTE_IN_BYTES * 60;
final SparseArray results = new SparseArray<>();
results.put(0, result);
@@ -356,6 +376,8 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mDocumentsAndOtherPreference.getSummary().toString())
.isEqualTo("50 MB");
assertThat(mController.mTrashPreference.getSummary().toString()).isEqualTo("100 kB");
+ assertThat(mController.mSystemPreference.getSummary().toString())
+ .isEqualTo("60 MB");
}
@Test
@@ -373,6 +395,7 @@ public class StorageItemPreferenceControllerTest {
verify(mController.mDocumentsAndOtherPreference, times(2))
.setIcon(nullable(Drawable.class));
verify(mController.mSystemPreference, times(2)).setIcon(nullable(Drawable.class));
+ verify(mController.mTemporaryFilesPreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mTrashPreference, times(2)).setIcon(nullable(Drawable.class));
}
@@ -437,6 +460,7 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
+ assertThat(mController.mTemporaryFilesPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java b/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java
index ebff07a44d3..a17859ad9ae 100644
--- a/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privatespace/delete/ResetOptionsDeletePrivateSpaceControllerTest.java
@@ -103,11 +103,23 @@ public class ResetOptionsDeletePrivateSpaceControllerTest {
}
@Test
- public void getAvailabilityStatus_flagsEnabled_returnsAvailable() {
+ public void getAvailabilityStatus_flagsEnabledCanAddProfile_returnsAvailable() {
mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_DELETE_PRIVATE_SPACE_FROM_RESET);
+ ResetOptionsDeletePrivateSpaceController spyController = spy(mController);
+ doReturn(true).when(spyController).isPrivateSpaceEntryPointEnabled();
- assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ assertThat(spyController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_flagsEnabledCannotAddProfile_returnsUnsupported() {
+ mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_DELETE_PRIVATE_SPACE_FROM_RESET);
+ ResetOptionsDeletePrivateSpaceController spyController = spy(mController);
+ doReturn(false).when(spyController).isPrivateSpaceEntryPointEnabled();
+
+ assertThat(spyController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
diff --git a/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java b/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java
deleted file mode 100644
index 88503a525b6..00000000000
--- a/tests/unit/src/com/android/settings/privatespace/HidePrivateSpaceSensitiveNotificationsControllerTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2024 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.privatespace;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
-import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-import static org.mockito.Mockito.spy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.platform.test.flag.junit.SetFlagsRule;
-import android.provider.Settings;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-/**
- * Tests for HidePrivateSpaceSensitiveNotificationsController.
- * Run as {@code atest SettingsUnitTests:HidePrivateSpaceSensitiveNotificationsControllerTest}
- */
-@RunWith(AndroidJUnit4.class)
-public class HidePrivateSpaceSensitiveNotificationsControllerTest {
- @Rule
- public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
- private Context mContext;
- private HidePrivateSpaceSensitiveNotificationsController
- mHidePrivateSpaceSensitiveNotificationsController;
- @Mock
- private ContentResolver mContentResolver;
- private int mOriginalDeviceSensitiveNotifValue;
- private int mOriginalDeviceNotifValue;
- private int mOriginalPsSensitiveNotifValue;
- private int mPrivateProfileId;
-
- @Before
- public void setUp() {
- mContext = spy(ApplicationProvider.getApplicationContext());
- mContentResolver = mContext.getContentResolver();
- assumeTrue(PrivateSpaceMaintainer.getInstance(mContext).doesPrivateSpaceExist());
-
- mSetFlagsRule.enableFlags(
- android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE);
- mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
- android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
-
- mPrivateProfileId = PrivateSpaceMaintainer.getInstance(
- mContext).getPrivateProfileHandle().getIdentifier();
-
- mOriginalDeviceSensitiveNotifValue = Settings.Secure.getInt(mContentResolver,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
- mOriginalDeviceNotifValue = Settings.Secure.getInt(mContentResolver,
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
- mOriginalPsSensitiveNotifValue = Settings.Secure.getIntForUser(mContentResolver,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mPrivateProfileId);
-
- final String preferenceKey = "private_space_sensitive_notifications";
- mHidePrivateSpaceSensitiveNotificationsController =
- new HidePrivateSpaceSensitiveNotificationsController(mContext, preferenceKey);
- }
-
- @After
- public void tearDown() {
- Settings.Secure.putInt(mContentResolver,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- mOriginalDeviceSensitiveNotifValue
- );
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, mOriginalDeviceNotifValue);
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- mOriginalPsSensitiveNotifValue, mPrivateProfileId);
- }
-
- /**
- * Tests that the controller is unavailable if lockscreen sensitive notifications are disabled
- * on the device.
- */
- @Test
- public void getAvailabilityStatus_lockScreenPrivateNotificationsOff() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(DISABLED_DEPENDENT_SETTING);
- }
-
- /**
- * Tests that the controller is unavailable if lockscreen notifications are disabled on the
- * device.
- */
- @Test
- public void getAvailabilityStatus_lockScreenNotificationsOff() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(DISABLED_DEPENDENT_SETTING);
- }
-
- /**
- * Tests that the controller is available if lockscreen notifications and lockscreen private
- * notifications are enabled on the device.
- */
- @Test
- public void getAvailabilityStatus_returnAvailable() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(AVAILABLE);
- }
-
-
- /**
- * Tests that toggle is not available if the flag for this feature and MVP flag are disabled.
- */
- @Test
- public void getAvailabilityStatus_flagDisabled() {
- mSetFlagsRule.disableFlags(
- android.multiuser.Flags.FLAG_ENABLE_PS_SENSITIVE_NOTIFICATIONS_TOGGLE);
- mSetFlagsRule.disableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
- android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.getAvailabilityStatus())
- .isEqualTo(UNSUPPORTED_ON_DEVICE);
- }
-
- @Test
- public void testSetChecked() {
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.setChecked(true)).isTrue();
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.isChecked()).isEqualTo(true);
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.setChecked(false)).isTrue();
- assertThat(mHidePrivateSpaceSensitiveNotificationsController.isChecked()).isEqualTo(false);
- }
-}
diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
index 50f67d3c55b..6f3cb75820f 100644
--- a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
+++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
@@ -21,16 +21,23 @@ import static android.provider.Settings.Secure.PRIVATE_SPACE_AUTO_LOCK;
import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL;
import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_ENTRY_POINT_ENABLED_VAL;
+import static com.android.settings.privatespace.PrivateSpaceMaintainer.HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL;
import static com.android.settings.privatespace.PrivateSpaceMaintainer.PRIVATE_SPACE_AUTO_LOCK_DEFAULT_VAL;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Flags;
import android.os.RemoteException;
+import android.os.UserManager;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
@@ -72,6 +79,8 @@ public class PrivateSpaceMaintainerTest {
/** Tests that {@link PrivateSpaceMaintainer#deletePrivateSpace()} deletes PS when PS exists. */
@Test
public void deletePrivateSpace_psExists_deletesPS() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -88,6 +97,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void deletePrivateSpace_psDoesNotExist_returnsNoPSError() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
ErrorDeletingPrivateSpace errorDeletingPrivateSpace =
@@ -100,6 +111,8 @@ public class PrivateSpaceMaintainerTest {
/** Tests that {@link PrivateSpaceMaintainer#createPrivateSpace()} when PS exists creates PS. */
@Test
public void createPrivateSpace_psDoesNotExist_createsPS() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.deletePrivateSpace();
@@ -113,6 +126,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void createPrivateSpace_psExists_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.deletePrivateSpace();
@@ -127,6 +142,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void createPrivateSpace_psDoesNotExist_resetsHidePSSettings() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
Settings.Secure.putInt(
@@ -156,7 +173,7 @@ public class PrivateSpaceMaintainerTest {
privateSpaceMaintainer.createPrivateSpace();
assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue();
assertThat(getPsSensitiveNotificationsValue(privateSpaceMaintainer))
- .isEqualTo(HidePrivateSpaceSensitiveNotificationsController.DISABLED);
+ .isEqualTo(HIDE_PRIVATE_SPACE_SENSITIVE_NOTIFICATIONS_DISABLED_VAL);
}
/**
@@ -165,6 +182,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void createPrivateSpace_psExists_doesNotResetHidePSSettings() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -184,6 +203,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void lockPrivateSpace_psExistsAndPrivateProfileRunning_locksCreatedPrivateSpace() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -200,6 +221,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void lockPrivateSpace_psExistsAndPrivateProfileNotRunning_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -220,6 +243,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void lockPrivateSpace_psDoesNotExist_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
@@ -232,6 +257,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void createPrivateSpace_psDoesNotExist_setsUserSetupComplete() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -244,6 +271,8 @@ public class PrivateSpaceMaintainerTest {
*/
@Test
public void createPrivateSpace_pSExists_doesNotChangeUserSetupSetting() {
+ mSetFlagsRule.enableFlags(
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
privateSpaceMaintainer.createPrivateSpace();
@@ -300,6 +329,61 @@ public class PrivateSpaceMaintainerTest {
.isEqualTo(privateSpaceAutLockValue);
}
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psExistCanAddProfileTrue_returnsTrue() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeTrue(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.createPrivateSpace();
+ assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue();
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isTrue();
+ }
+
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psNotExistsCanAddProfileTrue_returnsTrue() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeTrue(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.deletePrivateSpace();
+ assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isTrue();
+ }
+
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psExistsCanAddProfileFalse_returnsTrue() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeFalse(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ spy(PrivateSpaceMaintainer.getInstance(mContext));
+ when(privateSpaceMaintainer.doesPrivateSpaceExist()).thenReturn(true);
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isTrue();
+ }
+
+ @Test
+ public void isPrivateSpaceEntryPointEnabled_psNotExistsCanAddProfileFalse_returnsFalse() {
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ assumeFalse(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(mContext);
+ privateSpaceMaintainer.deletePrivateSpace();
+ assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
+
+ assertThat(privateSpaceMaintainer.isPrivateSpaceEntryPointEnabled()).isFalse();
+ }
+
private int getSecureUserSetupComplete() {
PrivateSpaceMaintainer privateSpaceMaintainer =
PrivateSpaceMaintainer.getInstance(mContext);
@@ -313,7 +397,7 @@ public class PrivateSpaceMaintainerTest {
private int getPsSensitiveNotificationsValue(PrivateSpaceMaintainer privateSpaceMaintainer) {
return Settings.Secure.getIntForUser(mContentResolver,
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- HidePrivateSpaceSensitiveNotificationsController.ENABLED,
+ /* enabled */ 1,
privateSpaceMaintainer.getPrivateProfileHandle().getIdentifier());
}
}