diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8791c920067..eb69f6e9ea9 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -348,7 +348,7 @@ android:exported="true" android:configChanges="orientation|keyboardHidden|screenSize"> - + diff --git a/res/values/arrays.xml b/res/values/arrays.xml index d5aa26705f7..46114cbe11d 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -105,11 +105,16 @@ 1800000 + 0.85 1.0 1.15 1.30 + 1.50 + 1.80 + 2.0 diff --git a/res/values/strings.xml b/res/values/strings.xml index 28378c48969..d91cb88c499 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10492,7 +10492,10 @@ Reboot with MTE 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. + Try MTE for a single boot for app development + MTE is enabled through Advanced memory protection Capturing system heap dump diff --git a/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java b/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java index 708f8b7004d..6da3e529065 100644 --- a/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java +++ b/src/com/android/settings/applications/manageapplications/ResetAppsHelper.java @@ -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 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 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 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 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); } } }); diff --git a/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureDetails.java b/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureDetails.java index 3dd428b2e18..1c322ff6c49 100644 --- a/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureDetails.java +++ b/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureDetails.java @@ -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; } /** diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java index c99b169ea2d..5babf30c185 100644 --- a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java +++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java @@ -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 diff --git a/src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java b/src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java index fe7fa7c5d71..b631e353ba5 100644 --- a/src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java +++ b/src/com/android/settings/deviceinfo/storage/NonCurrentUserController.java @@ -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 getNonCurrentUserControllers( Context context, UserManager userManager) { @@ -73,7 +73,7 @@ public class NonCurrentUserController extends AbstractPreferenceController imple List controllers = new ArrayList<>(); List 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 diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java index cfa537b31f5..ce441c841c9 100644 --- a/src/com/android/settings/fuelgauge/BatteryInfo.java +++ b/src/com/android/settings/fuelgauge/BatteryInfo.java @@ -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; diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index 19d0727c19f..8bf5e166460 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -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) { diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java index c7dbebbc701..fdcbb4a52a2 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java @@ -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( diff --git a/src/com/android/settings/spa/app/AllAppList.kt b/src/com/android/settings/spa/app/AllAppList.kt index 90e5a6b8b4e..f8c5c0f63e9 100644 --- a/src/com/android/settings/spa/app/AllAppList.kt +++ b/src/com/android/settings/spa/app/AllAppList.kt @@ -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), ) } } diff --git a/src/com/android/settings/spa/app/ResetAppPreferences.kt b/src/com/android/settings/spa/app/ResetAppPreferences.kt new file mode 100644 index 00000000000..12dd7090ea1 --- /dev/null +++ b/src/com/android/settings/spa/app/ResetAppPreferences.kt @@ -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)) }, + ) +} diff --git a/src/com/android/settings/spa/development/UsageStats.kt b/src/com/android/settings/spa/development/UsageStats.kt index 302f2010b31..d98ef599f9c 100644 --- a/src/com/android/settings/spa/development/UsageStats.kt +++ b/src/com/android/settings/spa/development/UsageStats.kt @@ -37,9 +37,7 @@ object UsageStatsPageProvider : SettingsPageProvider { title = stringResource(R.string.testing_usage_stats), listModel = rememberContext(::UsageStatsListModel), primaryUserOnly = true, - ) { itemModel -> - AppListItem(itemModel) {} - } + ) { AppListItem {} } } @Composable diff --git a/src/com/android/settings/spa/notification/AppListNotifications.kt b/src/com/android/settings/spa/notification/AppListNotifications.kt index da4ebb5dc21..0e6c5e2d6da 100644 --- a/src/com/android/settings/spa/notification/AppListNotifications.kt +++ b/src/com/android/settings/spa/notification/AppListNotifications.kt @@ -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, -) { +private fun AppListItemModel.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, ) } diff --git a/src/com/android/settings/spa/system/AppLanguages.kt b/src/com/android/settings/spa/system/AppLanguages.kt index db34cd595f1..bcb65352a27 100644 --- a/src/com/android/settings/spa/system/AppLanguages.kt +++ b/src/com/android/settings/spa/system/AppLanguages.kt @@ -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) { +private fun AppListItemModel.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) } - ) -} \ No newline at end of file + context.startActivity(intent) + } +} diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java index dc6fbd4a50b..44b41d09c1a 100644 --- a/src/com/android/settings/users/UserDetailsSettings.java +++ b/src/com/android/settings/users/UserDetailsSettings.java @@ -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; } diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java index 0ca60c90b29..d8835873db8 100644 --- a/src/com/android/settings/users/UserSettings.java +++ b/src/com/android/settings/users/UserSettings.java @@ -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. diff --git a/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java b/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java index b0735fb726b..d8bbc3187c6 100644 --- a/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java +++ b/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java @@ -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( diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java index 684128c436f..61d3bed91c7 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/NonCurrentUserControllerTest.java @@ -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); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java index 513dfdfed83..addfd9bfdb9 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java @@ -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; } diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java index fad30aa01d4..ff57ebca443 100644 --- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java +++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java @@ -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, diff --git a/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt new file mode 100644 index 00000000000..b144ad6eecf --- /dev/null +++ b/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt @@ -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() + } + } + } +} diff --git a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java index a5d74a03500..69e5e2f485b 100644 --- a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java +++ b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java @@ -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());