Snap for 9354100 from b79c8c6eb4 to udc-release

Change-Id: I5d92b00041be30e7ade64650cfb8e78f4d21b256
This commit is contained in:
Android Build Coastguard Worker
2022-12-01 02:27:12 +00:00
23 changed files with 307 additions and 166 deletions

View File

@@ -348,7 +348,7 @@
android:exported="true"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter android:priority="1">
<action android:name="android.settings.MEMTAG_SETTINGS"/>
<action android:name="android.settings.ADVANCED_MEMORY_PROTECTION_SETTINGS"/>
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

View File

@@ -105,11 +105,16 @@
<item>1800000</item>
</string-array>
<!-- NOTE: if you change this, you must also add the corresponding scale key and lookup table to
frameworks/base/core/java/android/content/res/FontScaleLookupTableFactory.java -->
<string-array name="entryvalues_font_size" translatable="false">
<item>0.85</item>
<item>1.0</item>
<item>1.15</item>
<item>1.30</item>
<item>1.50</item>
<item>1.80</item>
<item>2.0</item>
</string-array>
<!-- Wi-Fi settings -->

View File

@@ -10492,7 +10492,10 @@
<!-- Title for the button to reboot with MTE enabled. [CHAR LIMIT=NONE] -->
<string name="reboot_with_mte_title">Reboot with MTE</string>
<string name="reboot_with_mte_message">System will reboot and allow to experiment with Memory Tagging Extension (MTE). MTE may negatively impact system performance and stability. Will be reset on next subsequent reboot.</string>
<!-- Subtext for button if MTE is not enabled through Advanced memory protection. -->
<string name="reboot_with_mte_summary">Try MTE for a single boot for app development</string>
<!-- Subtext for button if MTE is already enabled through Advanced memory protection.
The string for "Advanced memory protection" needs to match "memtag_toggle" above -->
<string name="reboot_with_mte_already_enabled">MTE is enabled through Advanced memory protection</string>
<!-- Toast that is shown when the user initiates capturing a heap dump for the system server. [CHAR LIMIT=NONE] -->
<string name="capturing_system_heap_dump_message">Capturing system heap dump</string>

View File

@@ -110,58 +110,57 @@ public class ResetAppsHelper implements DialogInterface.OnClickListener,
@Override
public void onClick(DialogInterface dialog, int which) {
if (mResetDialog != dialog) {
return;
if (mResetDialog == dialog) {
resetApps();
}
AsyncTask.execute(new Runnable() {
@Override
public void run() {
final List<String> allowList = Arrays.asList(
mContext.getResources().getStringArray(
R.array.config_skip_reset_apps_package_name));
for (UserHandle userHandle : mUm.getEnabledProfiles()) {
final int userId = userHandle.getIdentifier();
final List<ApplicationInfo> apps = mPm.getInstalledApplicationsAsUser(
PackageManager.GET_DISABLED_COMPONENTS, userId);
for (int i = 0; i < apps.size(); i++) {
ApplicationInfo app = apps.get(i);
if (allowList.contains(app.packageName)) {
continue;
}
}
/** Resets the app preferences. */
public void resetApps() {
AsyncTask.execute(() -> {
final List<String> allowList = Arrays.asList(
mContext.getResources().getStringArray(
R.array.config_skip_reset_apps_package_name));
for (UserHandle userHandle : mUm.getEnabledProfiles()) {
final int userId = userHandle.getIdentifier();
final List<ApplicationInfo> apps = mPm.getInstalledApplicationsAsUser(
PackageManager.GET_DISABLED_COMPONENTS, userId);
for (ApplicationInfo app : apps) {
if (allowList.contains(app.packageName)) {
continue;
}
try {
mNm.clearData(app.packageName, app.uid, false);
} catch (RemoteException ex) {
}
if (!app.enabled) {
try {
mNm.clearData(app.packageName, app.uid, false);
} catch (android.os.RemoteException ex) {
}
if (!app.enabled) {
try {
if (mIPm.getApplicationEnabledSetting(app.packageName, userId)
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
mIPm.setApplicationEnabledSetting(app.packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
PackageManager.DONT_KILL_APP,
userId,
mContext.getPackageName());
}
} catch (RemoteException e) {
Log.e(TAG, "Error during reset disabled apps.", e);
if (mIPm.getApplicationEnabledSetting(app.packageName, userId)
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
mIPm.setApplicationEnabledSetting(app.packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
PackageManager.DONT_KILL_APP,
userId,
mContext.getPackageName());
}
} catch (RemoteException e) {
Log.e(TAG, "Error during reset disabled apps.", e);
}
}
}
try {
mIPm.resetApplicationPreferences(UserHandle.myUserId());
} catch (RemoteException e) {
}
mAom.resetAllModes();
BatteryOptimizeUtils.resetAppOptimizationMode(mContext, mIPm, mAom);
final int[] restrictedUids = mNpm.getUidsWithPolicy(
POLICY_REJECT_METERED_BACKGROUND);
final int currentUserId = ActivityManager.getCurrentUser();
for (int uid : restrictedUids) {
// Only reset for current user
if (UserHandle.getUserId(uid) == currentUserId) {
mNpm.setUidPolicy(uid, POLICY_NONE);
}
}
try {
mIPm.resetApplicationPreferences(UserHandle.myUserId());
} catch (RemoteException e) {
}
mAom.resetAllModes();
BatteryOptimizeUtils.resetAppOptimizationMode(mContext, mIPm, mAom);
final int[] restrictedUids = mNpm.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
final int currentUserId = ActivityManager.getCurrentUser();
for (int uid : restrictedUids) {
// Only reset for current user
if (UserHandle.getUserId(uid) == currentUserId) {
mNpm.setUidPolicy(uid, POLICY_NONE);
}
}
});

View File

@@ -84,7 +84,7 @@ public class PictureInPictureDetails extends AppInfoWithHeader
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_MANAGE_PICTURE_IN_PICTURE;
return SettingsEnums.SETTINGS_MANAGE_PICTURE_IN_PICTURE_DETAIL;
}
/**

View File

@@ -17,6 +17,7 @@
package com.android.settings.dashboard.profileselector;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
@@ -41,7 +42,6 @@ import com.android.settings.deviceinfo.storage.StorageEntry;
import com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController;
import com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController;
import com.android.settings.deviceinfo.storage.StorageUtils;
import com.android.settingslib.core.instrumentation.Instrumentable;
import java.util.ArrayList;
import java.util.List;
@@ -323,7 +323,7 @@ public class ProfileSelectStorageFragment extends ProfileSelectFragment {
@Override
public int getMetricsCategory() {
return Instrumentable.METRICS_CATEGORY_UNKNOWN;
return SettingsEnums.SETTINGS_STORAGE_PROFILE_SELECTOR;
}
@Override

View File

@@ -64,8 +64,8 @@ public class NonCurrentUserController extends AbstractPreferenceController imple
* Adds the appropriate controllers to a controller list for handling all full non current
* users on a device.
*
* @param context Context for initializing the preference controllers.
* @param userManager UserManagerWrapper for figuring out which controllers to add.
* @param context Context for initializing the preference controllers.
* @param userManager UserManagerWrapper for figuring out which controllers to add.
*/
public static List<NonCurrentUserController> getNonCurrentUserControllers(
Context context, UserManager userManager) {
@@ -73,7 +73,7 @@ public class NonCurrentUserController extends AbstractPreferenceController imple
List<NonCurrentUserController> controllers = new ArrayList<>();
List<UserInfo> infos = userManager.getUsers();
for (UserInfo info : infos) {
if (info.id == currentUserId || info.isProfile()) {
if (info.id == currentUserId || !info.isFull()) {
continue;
}
int[] profiles = userManager.getProfileIds(info.id, false /* enabledOnly */);
@@ -85,8 +85,8 @@ public class NonCurrentUserController extends AbstractPreferenceController imple
/**
* Constructor for a given non-current user.
*
* @param context Context to initialize the underlying {@link AbstractPreferenceController}.
* @param info {@link UserInfo} for the non-current user which these controllers cover.
* @param context Context to initialize the underlying {@link AbstractPreferenceController}.
* @param info {@link UserInfo} for the non-current user which these controllers cover.
* @param profiles list of IDs or user and its profiles
*/
@VisibleForTesting

View File

@@ -33,10 +33,10 @@ import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.UsageView;
import com.android.settingslib.R;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.fuelgauge.EstimateKt;
import com.android.settingslib.utils.PowerUtil;

View File

@@ -602,15 +602,6 @@ public class BatteryUtils {
/*receiver=*/ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
/** Gets the battery level from the intent. */
public static int getBatteryLevel(Intent intent) {
final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
final int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
return scale == 0
? -1 /*invalid battery level*/
: Math.round((level / (float) scale) * 100f);
}
/** Gets the current dock defender mode */
public static int getCurrentDockDefenderMode(Context context, BatteryInfo batteryInfo) {
if (batteryInfo.pluggedStatus == BatteryManager.BATTERY_PLUGGED_DOCK) {

View File

@@ -36,6 +36,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
import com.android.settingslib.fuelgauge.BatteryStatus;
import java.time.Clock;
import java.time.Duration;
@@ -149,7 +150,7 @@ public final class DatabaseUtils {
clearMemory();
return null;
}
final int batteryLevel = BatteryUtils.getBatteryLevel(intent);
final int batteryLevel = BatteryStatus.getBatteryLevel(intent);
final int batteryStatus = intent.getIntExtra(
BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_UNKNOWN);
final int batteryHealth = intent.getIntExtra(

View File

@@ -58,14 +58,15 @@ object AllAppListPageProvider : SettingsPageProvider {
@Composable
private fun AllAppListPage() {
val resetAppDialogPresenter = rememberResetAppDialogPresenter()
AppListPage(
title = stringResource(R.string.all_apps),
listModel = remember { AllAppListModel() },
showInstantApps = true,
) { itemModel ->
moreOptions = { ResetAppPreferences(resetAppDialogPresenter::open) }
) {
AppListItem(
itemModel = itemModel,
onClick = AppInfoSettingsProvider.navigator(app = itemModel.record.app),
onClick = AppInfoSettingsProvider.navigator(app = record.app),
)
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2022 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.spa.app
import android.os.UserHandle
import android.os.UserManager
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settings.applications.manageapplications.ResetAppsHelper
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
import com.android.settingslib.spa.widget.dialog.AlertDialogPresenter
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope
import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
import com.android.settingslib.spaprivileged.template.scaffold.RestrictedMenuItem
@Composable
fun MoreOptionsScope.ResetAppPreferences(onClick: () -> Unit) {
RestrictedMenuItem(
text = stringResource(R.string.reset_app_preferences),
restrictions = remember {
Restrictions(
userId = UserHandle.myUserId(),
keys = listOf(UserManager.DISALLOW_APPS_CONTROL),
)
},
onClick = onClick,
)
}
@Composable
fun rememberResetAppDialogPresenter(): AlertDialogPresenter {
val context = LocalContext.current
return rememberAlertDialogPresenter(
confirmButton = AlertDialogButton(stringResource(R.string.reset_app_preferences_button)) {
ResetAppsHelper(context).resetApps()
},
dismissButton = AlertDialogButton(stringResource(R.string.cancel)),
title = stringResource(R.string.reset_app_preferences_title),
text = { Text(stringResource(R.string.reset_app_preferences_desc)) },
)
}

View File

@@ -37,9 +37,7 @@ object UsageStatsPageProvider : SettingsPageProvider {
title = stringResource(R.string.testing_usage_stats),
listModel = rememberContext(::UsageStatsListModel),
primaryUserOnly = true,
) { itemModel ->
AppListItem(itemModel) {}
}
) { AppListItem {} }
}
@Composable

View File

@@ -46,9 +46,7 @@ object AppListNotificationsPageProvider : SettingsPageProvider {
AppListPage(
title = stringResource(R.string.app_notifications_title),
listModel = rememberContext(::AppNotificationsListModel),
) {
AppNotificationsItem(it)
}
) { AppNotificationsItem() }
}
@Composable
@@ -62,24 +60,21 @@ object AppListNotificationsPageProvider : SettingsPageProvider {
}
@Composable
private fun AppNotificationsItem(
itemModel: AppListItemModel<AppNotificationsRecord>,
) {
private fun AppListItemModel<AppNotificationsRecord>.AppNotificationsItem() {
val appNotificationsRepository = rememberContext(::AppNotificationRepository)
val context = LocalContext.current
AppListSwitchItem(
itemModel = itemModel,
onClick = {
navigateToAppNotificationSettings(
context = context,
app = itemModel.record.app,
app = record.app,
)
},
checked = itemModel.record.controller.isEnabled.observeAsState(),
checked = record.controller.isEnabled.observeAsState(),
changeable = produceState(initialValue = false) {
value = appNotificationsRepository.isChangeable(itemModel.record.app)
value = appNotificationsRepository.isChangeable(record.app)
},
onCheckedChange = itemModel.record.controller::setEnabled,
onCheckedChange = record.controller::setEnabled,
)
}

View File

@@ -52,9 +52,7 @@ object AppLanguagesPageProvider : SettingsPageProvider {
SettingsBody(stringResource(R.string.desc_app_locale_selection_supported))
}
},
) {
AppLanguageItem(it)
}
) { AppLanguageItem() }
}
@Composable
@@ -68,16 +66,13 @@ object AppLanguagesPageProvider : SettingsPageProvider {
}
@Composable
private fun AppLanguageItem(itemModel: AppListItemModel<AppLanguagesRecord>) {
private fun AppListItemModel<AppLanguagesRecord>.AppLanguageItem() {
val context = LocalContext.current
AppListItem(
itemModel = itemModel,
onClick = {
val intent = Intent(context, AppLocalePickerActivity::class.java).apply {
setData(Uri.parse("package:${itemModel.record.app.packageName}"))
putExtra("uid", itemModel.record.app.uid)
}
context.startActivity(intent)
AppListItem {
val intent = Intent(context, AppLocalePickerActivity::class.java).apply {
data = Uri.parse("package:${record.app.packageName}")
putExtra("uid", record.app.uid)
}
)
}
context.startActivity(intent)
}
}

View File

@@ -317,8 +317,12 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
mRemoveUserPref.setTitle(R.string.user_remove_user);
removePreference(KEY_APP_COPYING);
}
// Remove preference KEY_REMOVE_USER if DISALLOW_REMOVE_USER restriction is set
// on the current user or the user selected in user details settings is a main user.
if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())
|| mUserInfo.isMain()) {
removePreference(KEY_REMOVE_USER);
}
@@ -331,7 +335,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
@VisibleForTesting
boolean canDeleteUser() {
if (!mUserManager.isAdminUser()) {
if (!mUserManager.isAdminUser() || mUserInfo.isMain()) {
return false;
}

View File

@@ -97,6 +97,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@@ -240,9 +241,6 @@ public class UserSettings extends SettingsPreferenceFragment
case MESSAGE_UPDATE_LIST:
updateUserList();
break;
case MESSAGE_USER_CREATED:
onUserCreated(msg.arg1);
break;
case MESSAGE_REMOVE_GUEST_ON_EXIT_CONTROLLER_GUEST_REMOVED:
updateUserList();
if (mGuestUserAutoCreated) {
@@ -624,14 +622,13 @@ public class UserSettings extends SettingsPreferenceFragment
}
}
private void onUserCreated(int userId) {
private void onUserCreated(UserInfo userInfo) {
hideUserCreatingDialog();
// prevent crash when config changes during user creation
if (getContext() == null) {
return;
}
mAddingUser = false;
UserInfo userInfo = mUserManager.getUserInfo(userId);
openUserDetails(userInfo, true);
}
@@ -1011,69 +1008,50 @@ public class UserSettings extends SettingsPreferenceFragment
mUserCreatingDialog = new UserCreatingDialog(getActivity());
mUserCreatingDialog.show();
ThreadUtils.postOnBackgroundThread(new AddUserNowImpl(userType, mAddingUserName));
createUser(userType, mAddingUserName);
}
@VisibleForTesting
class AddUserNowImpl implements Runnable{
int mUserType;
String mImplAddUserName;
AddUserNowImpl(final int userType, final String addUserName) {
mUserType = userType;
mImplAddUserName = addUserName;
}
@Override
public void run() {
runAddUser();
Trace.endAsyncSection("UserSettings.addUserNow", 0);
}
private void runAddUser() {
void createUser(final int userType, String userName) {
Future<?> unusedCreateUserFuture = ThreadUtils.postOnBackgroundThread(() -> {
UserInfo user;
String username;
synchronized (mUserLock) {
username = mImplAddUserName;
}
// Could take a few seconds
if (mUserType == USER_TYPE_USER) {
user = mUserManager.createUser(username, 0);
if (userType == USER_TYPE_USER) {
user = mUserManager.createUser(
userName,
mUserManager.USER_TYPE_FULL_SECONDARY,
0);
} else {
user = mUserManager.createRestrictedProfile(username);
user = mUserManager.createRestrictedProfile(userName);
}
synchronized (mUserLock) {
ThreadUtils.postOnMainThread(() -> {
if (user == null) {
mAddingUser = false;
mPendingUserIcon = null;
mPendingUserName = null;
ThreadUtils.postOnMainThread(() -> onUserCreationFailed());
onUserCreationFailed();
return;
}
Drawable newUserIcon = mPendingUserIcon;
if (newUserIcon == null) {
newUserIcon = UserIcons.getDefaultUserIcon(getResources(), user.id, false);
}
mUserManager.setUserIcon(
user.id, UserIcons.convertToBitmapAtUserIconSize(
getResources(), newUserIcon));
if (mUserType == USER_TYPE_USER) {
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
}
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_USER_CREATED, user.id, user.serialNumber));
Future<?> unusedSettingIconFuture = ThreadUtils.postOnBackgroundThread(() -> {
Drawable newUserIcon = mPendingUserIcon;
if (newUserIcon == null) {
newUserIcon = UserIcons.getDefaultUserIcon(getResources(), user.id, false);
}
mUserManager.setUserIcon(
user.id, UserIcons.convertToBitmapAtUserIconSize(
getResources(), newUserIcon));
});
mPendingUserIcon = null;
mPendingUserName = null;
}
}
};
onUserCreated(user);
});
});
}
/**
* Erase the current user (guest) and switch to another user.

View File

@@ -35,7 +35,6 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.settings.Settings;
import com.android.settings.testutils.AdbUtils;
import com.android.settings.testutils.UiUtils;
import com.android.settingslib.utils.ThreadUtils;
import org.junit.After;
import org.junit.Before;
@@ -87,8 +86,7 @@ public class UserSettingsComponentTest {
((FragmentActivity) activity).getSupportFragmentManager().getFragments().get(0);
UserSettings us = (UserSettings) f;
Log.d(TAG, "Start to add user :" + randomUserName);
ThreadUtils.postOnBackgroundThread(
us.new AddUserNowImpl(USER_TYPE_RESTRICTED_PROFILE, randomUserName));
us.createUser(USER_TYPE_RESTRICTED_PROFILE, randomUserName);
});
assertThat(

View File

@@ -80,7 +80,7 @@ public class NonCurrentUserControllerTest {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mPrimaryUser = new UserInfo();
mPrimaryUser.flags = UserInfo.FLAG_PRIMARY;
mPrimaryUser.flags = UserInfo.FLAG_PRIMARY | UserInfo.FLAG_FULL;
mController = new NonCurrentUserController(mContext, mPrimaryUser);
ShadowActivityManager.setService(mActivityService);
@@ -267,6 +267,8 @@ public class NonCurrentUserControllerTest {
secondaryUser.id = 10;
final UserInfo secondaryUser1 = spy(new UserInfo());
secondaryUser1.id = 11;
secondaryUser.flags = UserInfo.FLAG_FULL;
secondaryUser1.flags = UserInfo.FLAG_FULL;
userInfo.add(mPrimaryUser);
userInfo.add(secondaryUser);
userInfo.add(secondaryUser1);

View File

@@ -132,6 +132,7 @@ public final class BatteryUsageBroadcastReceiverTest {
private static Intent getBatteryIntent(int level, int status) {
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.putExtra(BatteryManager.EXTRA_LEVEL, level);
intent.putExtra(BatteryManager.EXTRA_SCALE, 100);
intent.putExtra(BatteryManager.EXTRA_STATUS, status);
return intent;
}

View File

@@ -387,6 +387,16 @@ public class UserDetailsSettingsTest {
verify(mFragment).removePreference(KEY_REMOVE_USER);
}
@Test
public void initialize_onMainUser_shouldNotShowRemovePreference() {
setupSelectedMainUser();
mUserManager.setIsAdminUser(true);
mFragment.initialize(mActivity, mArguments);
verify(mFragment).removePreference(KEY_REMOVE_USER);
}
@Test
public void initialize_disallowRemoveUserRestriction_shouldNotShowRemovePreference() {
setupSelectedUser();
@@ -571,10 +581,22 @@ public class UserDetailsSettingsTest {
assertThat(result).isFalse();
}
@Test
public void canDeleteUser_onMainUser_shouldReturnFalse() {
setupSelectedMainUser();
mUserManager.setIsAdminUser(true);
mFragment.mUserInfo = mUserInfo;
boolean result = mFragment.canDeleteUser();
assertThat(result).isFalse();
}
@Test
public void canDeleteUser_adminSelectsUser_noRestrictions_shouldReturnTrue() {
setupSelectedUser();
mUserManager.setIsAdminUser(true);
mFragment.mUserInfo = mUserInfo;
boolean result = mFragment.canDeleteUser();
@@ -585,6 +607,7 @@ public class UserDetailsSettingsTest {
public void canDeleteUser_adminSelectsUser_hasRemoveRestriction_shouldReturnFalse() {
setupSelectedUser();
mUserManager.setIsAdminUser(true);
mFragment.mUserInfo = mUserInfo;
ComponentName componentName = new ComponentName("test", "test");
ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser(componentName);
ShadowDevicePolicyManager.getShadow().setDeviceOwnerUserId(UserHandle.myUserId());
@@ -611,6 +634,15 @@ public class UserDetailsSettingsTest {
mUserManager.addProfile(mUserInfo);
}
private void setupSelectedMainUser() {
mArguments.putInt("user_id", 11);
mUserInfo = new UserInfo(11, "Jerry", null,
UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MAIN,
UserManager.USER_TYPE_FULL_SECONDARY);
mUserManager.addProfile(mUserInfo);
}
private void setupSelectedGuest() {
mArguments.putInt("user_id", 23);
mUserInfo = new UserInfo(23, "Guest", null,

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2022 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.spa.app
import android.content.Context
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Spy
@RunWith(AndroidJUnit4::class)
class ResetAppPreferencesTest {
@get:Rule
val composeTestRule = createComposeRule()
@Spy
private val context: Context = ApplicationProvider.getApplicationContext()
@Test
fun resetAppPreferences_titleIsDisplayed() {
setResetAppPreferences()
composeTestRule.onNodeWithText(context.getString(R.string.reset_app_preferences))
.assertIsDisplayed()
}
private fun setResetAppPreferences() {
val fakeMoreOptionsScope = object : MoreOptionsScope {
override fun dismiss() {}
}
composeTestRule.setContent {
fakeMoreOptionsScope.ResetAppPreferences {}
}
}
@Test
fun resetAppDialogPresenter_confirmButtonDisplayed() {
setAndOpenDialog()
composeTestRule.onNodeWithText(context.getString(R.string.reset_app_preferences_button))
.assertIsDisplayed()
}
@Test
fun resetAppDialogPresenter_titleDisplayed() {
setAndOpenDialog()
composeTestRule.onNodeWithText(context.getString(R.string.reset_app_preferences_title))
.assertIsDisplayed()
}
@Test
fun resetAppDialogPresenter_textDisplayed() {
setAndOpenDialog()
composeTestRule.onNodeWithText(context.getString(R.string.reset_app_preferences_desc))
.assertIsDisplayed()
}
private fun setAndOpenDialog() {
composeTestRule.setContent {
val dialogPresenter = rememberResetAppDialogPresenter()
LaunchedEffect(Unit) {
dialogPresenter.open()
}
}
}
}

View File

@@ -179,20 +179,8 @@ public class FingerprintStatusUtilsTest {
}
@Test
public void getSettingsClassName_whenNotEnrolled_fingerprintOnly_returnsFingerprintEnrollInduction() {
public void getSettingsClassName_whenNotEnrolled_returnsFingerprintSettings() {
when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFaceManager.isHardwareDetected()).thenReturn(false);
assertThat(mFingerprintStatusUtils.getSettingsClassName())
.isEqualTo(FingerprintEnrollIntroductionInternal.class.getName());
}
@Test
public void getSettingsClassName_whenNotEnrolled_fingerprintNotOnly_returnsFingerprintSettings() {
when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFaceManager.isHardwareDetected()).thenReturn(true);
assertThat(mFingerprintStatusUtils.getSettingsClassName())
.isEqualTo(FingerprintSettings.class.getName());