Snap for 11672362 from 0882f3c105 to 24Q3-release

Change-Id: I1e4779aaecdbc5e1b5f074a67a91d39f22ed13f1
This commit is contained in:
Android Build Coastguard Worker
2024-04-04 23:21:18 +00:00
34 changed files with 624 additions and 353 deletions

View File

@@ -0,0 +1,26 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M40,720Q49,613 105.5,523Q162,433 256,380L182,252Q176,243 179,233Q182,223 192,218Q200,213 210,216Q220,219 226,228L300,356Q386,320 480,320Q574,320 660,356L734,228Q740,219 750,216Q760,213 768,218Q778,223 781,233Q784,243 778,252L704,380Q798,433 854.5,523Q911,613 920,720L40,720ZM280,610Q301,610 315.5,595.5Q330,581 330,560Q330,539 315.5,524.5Q301,510 280,510Q259,510 244.5,524.5Q230,539 230,560Q230,581 244.5,595.5Q259,610 280,610ZM680,610Q701,610 715.5,595.5Q730,581 730,560Q730,539 715.5,524.5Q701,510 680,510Q659,510 644.5,524.5Q630,539 630,560Q630,581 644.5,595.5Q659,610 680,610Z"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M480,440Q630,440 735,393Q840,346 840,280Q840,214 735,167Q630,120 480,120Q330,120 225,167Q120,214 120,280Q120,346 225,393Q330,440 480,440ZM480,540Q521,540 582.5,531.5Q644,523 701,504Q758,485 799,454.5Q840,424 840,380L840,480Q840,524 799,554.5Q758,585 701,604Q644,623 582.5,631.5Q521,640 480,640Q439,640 377.5,631.5Q316,623 259,604Q202,585 161,554.5Q120,524 120,480L120,380Q120,424 161,454.5Q202,485 259,504Q316,523 377.5,531.5Q439,540 480,540ZM480,740Q521,740 582.5,731.5Q644,723 701,704Q758,685 799,654.5Q840,624 840,580L840,680Q840,724 799,754.5Q758,785 701,804Q644,823 582.5,831.5Q521,840 480,840Q439,840 377.5,831.5Q316,823 259,804Q202,785 161,754.5Q120,724 120,680L120,580Q120,624 161,654.5Q202,685 259,704Q316,723 377.5,731.5Q439,740 480,740Z"/>
</vector>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<com.google.android.setupdesign.GlifLoadingLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/private_space_pre_finish"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:icon="@drawable/ic_private_space_icon"
app:sudUsePartnerHeavyTheme="true"
app:sudIllustrationType="default"
app:sucHeaderText="@string/private_space_pre_finish_title">
</com.google.android.setupdesign.GlifLoadingLayout>

View File

@@ -46,6 +46,13 @@
android:id="@+id/action_retry_profile_creation"
app:destination="@id/ps_auto_advance_fragment"/>
</fragment>
<fragment android:id="@+id/ps_pre_finish_delay_fragment"
android:name="com.android.settings.privatespace.SetupPreFinishDelayFragment"
android:label="fragment_ps_pre_finish">
<action
android:id="@+id/action_success_fragment"
app:destination="@id/ps_profile_success_fragment"/>
</fragment>
<fragment android:id="@+id/ps_profile_success_fragment"
android:name="com.android.settings.privatespace.SetupSuccessFragment"
android:label="fragment_ps_success"/>
@@ -64,7 +71,7 @@
android:label="fragment_ps_lock">
<action
android:id="@+id/action_lock_success_fragment"
app:destination="@id/ps_profile_success_fragment"/>
app:destination="@id/ps_pre_finish_delay_fragment"/>
</fragment>
<fragment android:id="@+id/ps_account_intro_fragment"
android:name="com.android.settings.privatespace.PrivateSpaceGaiaEducationFragment"
@@ -76,6 +83,6 @@
android:id="@+id/action_advance_login_error"
app:destination="@id/ps_account_error_fragment"/>
</fragment>
<action android:id="@+id/action_success_fragment"
app:destination="@id/ps_profile_success_fragment"/>
<action android:id="@+id/action_pre_finish_delay_fragment"
app:destination="@id/ps_pre_finish_delay_fragment"/>
</navigation>

View File

@@ -1352,6 +1352,8 @@
<string name="private_space_use_screenlock_label">Use screen lock</string>
<!-- Label for private space lock setup button to choose a new lock. [CHAR LIMIT=50] -->
<string name="private_space_set_lock_label">Choose new lock</string>
<!-- Title for private space setup pre completion screen to add a delay. [CHAR LIMIT=30] -->
<string name="private_space_pre_finish_title">Just a sec\u2026</string>
<!-- Title for private space setup success screen. [CHAR LIMIT=30] -->
<string name="private_space_success_title">All set!</string>
<!-- Summary for the private space setup success screen. [CHAR LIMIT=NONE] -->
@@ -1378,12 +1380,6 @@
<string name="private_space_choose_your_password_header">Set a password for your private space</string>
<!-- Header for private space choose your pattern screen [CHAR LIMIT=40] -->
<string name="private_space_choose_your_pattern_header">Set a pattern for your private space</string>
<!-- Header for private space apps and notifications section [CHAR LIMIT=40] -->
<string name="private_space_apps_and_notifications_header">Apps and notifications</string>
<!-- Title for private space sensitive notifications toggle [CHAR LIMIT=80] -->
<string name="private_space_notifications_title">Sensitive notifications on lock screen</string>
<!-- Summary description for private space sensitive notifications toggle [CHAR LIMIT=200] -->
<string name="private_space_sensitive_notifications_description">Show sensitive content when private space is unlocked</string>
<!-- Title for private space GAIA education screen [CHAR LIMIT=90] -->
<string name="private_space_gaia_education_title">Create a Google Account to help keep your data private</string>
<!-- Description for private space GAIA education screen [CHAR LIMIT=120] -->
@@ -4419,8 +4415,10 @@
<!-- Title text for 'Tap to click'. [CHAR LIMIT=35] -->
<string name="trackpad_tap_to_click">Tap to click</string>
<!-- TODO(b/321978150): mark as translatable once we have finalized text from UX. -->
<string name="trackpad_tap_dragging" translatable="false">Tap dragging</string>
<!-- Title text for 'Tap dragging', a touchpad setting which allows dragging of UI elements by tapping the touchpad with a single finger and then moving it. [CHAR LIMIT=35] -->
<string name="trackpad_tap_dragging_title">Tap dragging</string>
<!-- Summary text for 'Tap dragging', a touchpad setting which allows dragging of UI elements by tapping the touchpad with a single finger and then moving it. [CHAR LIMIT=60] -->
<string name="trackpad_tap_dragging_summary">Tap and drag your finger on the touchpad to move objects</string>
<!-- Title text for 'Touchpad gestures' [CHAR LIMIT=35] -->
<string name="trackpad_touchpad_gesture_title">Touchpad gestures</string>
<!-- Summary text for 'Touchpad gestures' [CHAR LIMIT=60] -->
@@ -11089,8 +11087,8 @@
]]>
</string>
<!-- Title for setting tile leading to saved autofill passwords, passkeys, autofill, and account settings [CHAR LIMIT=40]-->
<string name="account_dashboard_title_with_passkeys">Passwords, passkeys &amp; autofill</string>
<!-- Title for setting tile leading to saved autofill passwords, passkeys, and account settings [CHAR LIMIT=40]-->
<string name="account_dashboard_title_with_passkeys">Passwords, passkeys &amp; accounts</string>
<!-- Message of the warning dialog for disabling the credential provider (new strings for 24Q3). [CHAR_LIMIT=NONE] -->
<string name="credman_confirmation_message_new_ui">

View File

@@ -59,17 +59,6 @@
</PreferenceCategory>
<PreferenceCategory
android:title="@string/private_space_apps_and_notifications_header">
<com.android.settingslib.RestrictedSwitchPreference
android:key="private_space_sensitive_notifications"
android:title="@string/private_space_notifications_title"
android:summary="@string/private_space_sensitive_notifications_description"
settings:controller="com.android.settings.privatespace.HidePrivateSpaceSensitiveNotificationsController" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/private_space_category_system">

View File

@@ -61,19 +61,31 @@
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system"
android:title="@string/storage_system"
android:icon="@drawable/ic_system_update"
android:order="107"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_trash"
android:title="@string/storage_trash"
android:icon="@drawable/ic_trash_can"
android:order="108"/>
<!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
android:order="107"/>
<!-- Preference order 100~200 are 'ONLY' for storage category
preferences that are sorted by size. -->
<PreferenceCategory
android:key="storage_category_splitter"
android:title="@string/storage_system_label"
android:order="201"
settings:searchable="false">
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system"
android:title="@string/storage_os_name"
android:icon="@drawable/ic_android_vd_theme_24"
android:order="202"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="temporary_files"
android:title="@string/storage_temporary_files"
android:icon="@drawable/ic_database_vd_theme_24"
android:order="203"/>
</PreferenceCategory>
<PreferenceCategory
android:key="pref_non_current_users"
android:title="@string/storage_other_users"
android:order="201" />
android:order="204" />
</PreferenceScreen>

View File

@@ -80,19 +80,31 @@
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system"
android:title="@string/storage_system"
android:icon="@drawable/ic_system_update"
android:order="107"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_trash"
android:title="@string/storage_trash"
android:icon="@drawable/ic_trash_can"
android:order="108"/>
<!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
android:order="107"/>
<!-- Preference order 100~200 are 'ONLY' for storage category
preferences that are sorted by size. -->
<PreferenceCategory
android:key="storage_category_splitter"
android:title="@string/storage_system_label"
android:order="201"
settings:searchable="false">
<com.android.settings.deviceinfo.StorageItemPreference
android:key="pref_system"
android:title="@string/storage_os_name"
android:icon="@drawable/ic_android_vd_theme_24"
android:order="202"/>
<com.android.settings.deviceinfo.StorageItemPreference
android:key="temporary_files"
android:title="@string/storage_temporary_files"
android:icon="@drawable/ic_database_vd_theme_24"
android:order="203"/>
</PreferenceCategory>
<PreferenceCategory
android:key="pref_non_current_users"
android:title="@string/storage_other_users"
android:order="201" />
android:order="204" />
</PreferenceScreen>

View File

@@ -48,10 +48,10 @@
android:order="30"
settings:keywords="@string/keywords_trackpad_bottom_right_tap"/>
<!-- TODO(b/321978150): add a summary line once we have finalized text from UX. -->
<SwitchPreferenceCompat
android:key="trackpad_tap_dragging"
android:title="@string/trackpad_tap_dragging"
android:title="@string/trackpad_tap_dragging_title"
android:summary="@string/trackpad_tap_dragging_summary"
settings:controller="com.android.settings.inputmethod.TrackpadTapDraggingPreferenceController"
android:order="35"/>

View File

@@ -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<FaceSensorPropertiesInternal> 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.

View File

@@ -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);
}

View File

@@ -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());
}

View File

@@ -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<ApplicationInfo> 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;

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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<Pair<Integer, Integer>> 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;

View File

@@ -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;
}
}

View File

@@ -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());
}

View File

@@ -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;
}

View File

@@ -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);
};
}

View File

@@ -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(

View File

@@ -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);
}
}

View File

@@ -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()

View File

@@ -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";

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -73,13 +73,14 @@ public class UseOneLockSettingsFragment extends DashboardFragment {
final List<AbstractPreferenceController> 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()));

View File

@@ -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<FaceSensorPropertiesInternal> 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<FaceSensorPropertiesInternal> 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<FaceSensorPropertiesInternal> 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);

View File

@@ -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;
}
}

View File

@@ -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<StorageAsyncLoader.StorageResult> 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();
}

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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());
}
}