diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4bf615f5166..a3acd49d958 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2517,7 +2517,7 @@ + android:screenOrientation="nosensor"> @@ -2526,12 +2526,12 @@ + android:screenOrientation="nosensor"/> diff --git a/res/drawable/keyboard_review_layout_background.xml b/res/drawable/keyboard_review_layout_background.xml new file mode 100644 index 00000000000..7f93f80b57a --- /dev/null +++ b/res/drawable/keyboard_review_layout_background.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/res/layout/keyboard_layout_picker.xml b/res/layout/keyboard_layout_picker.xml index b25c228bf34..5e62a2c0412 100644 --- a/res/layout/keyboard_layout_picker.xml +++ b/res/layout/keyboard_layout_picker.xml @@ -17,15 +17,33 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginHorizontal="@dimen/keyboard_picker_margin" android:id="@+id/keyboard_layout_picker_container" android:orientation="vertical"> - + android:background="@drawable/keyboard_review_layout_background"> + + + 24dp 24dp + + + 106dp diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 6c03955c1e4..3e0b8d93381 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -165,6 +165,13 @@ 1.0 0dp + + 68dp + 24dp + 16dp + 28dp + 16sp + 40dp 14sp diff --git a/res/values/strings.xml b/res/values/strings.xml index 0b12142f53f..1fd5252449f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1207,7 +1207,7 @@ Private Space - Hide apps in a private folder + Keep private apps locked and hidden Hide apps in a private folder that only you can access @@ -1281,7 +1281,7 @@ Notifications from apps in private space are hidden when it\u2019s locked - Unlock your space to share photos or files from private space apps + Unlock private space to share photos or files from private space apps Some apps are already installed in your private space @@ -1312,6 +1312,12 @@ Choose a lock for your private space You can unlock your private space using your fingerprint. For security, this option requires a backup lock. + + Set a PIN for your private space + + Set a password for your private space + + Set a pattern for your private space @@ -12633,4 +12639,7 @@ + + + Password is now set up diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java index fb78e3eb077..00f06258ee0 100644 --- a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java +++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java @@ -139,7 +139,11 @@ public class ApprovalPreferenceController extends BasePreferenceController { AsyncTask.execute(() -> { if (!mNm.isNotificationPolicyAccessGrantedForPackage( cn.getPackageName())) { - mNm.removeAutomaticZenRules(cn.getPackageName()); + if (android.app.Flags.modesApi()) { + mNm.removeAutomaticZenRules(cn.getPackageName(), /* fromUser= */ true); + } else { + mNm.removeAutomaticZenRules(cn.getPackageName()); + } } }); } diff --git a/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessController.java b/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessController.java index b4a0c88d950..6f4137c224a 100644 --- a/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessController.java +++ b/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessController.java @@ -101,8 +101,12 @@ public class ZenAccessController extends BasePreferenceController { } public static void deleteRules(final Context context, final String pkg) { - final NotificationManager mgr = context.getSystemService(NotificationManager.class); - mgr.removeAutomaticZenRules(pkg); + final NotificationManager mgr = context.getSystemService(NotificationManager.class); + if (android.app.Flags.modesApi()) { + mgr.removeAutomaticZenRules(pkg, /* fromUser= */ true); + } else { + mgr.removeAutomaticZenRules(pkg); + } } @VisibleForTesting diff --git a/src/com/android/settings/datausage/DataUsageList.kt b/src/com/android/settings/datausage/DataUsageList.kt index 6a187d8caf8..3083fb75443 100644 --- a/src/com/android/settings/datausage/DataUsageList.kt +++ b/src/com/android/settings/datausage/DataUsageList.kt @@ -30,6 +30,7 @@ import androidx.annotation.VisibleForTesting import androidx.fragment.app.viewModels import androidx.preference.Preference import com.android.settings.R +import com.android.settings.dashboard.DashboardFragment import com.android.settings.datausage.lib.BillingCycleRepository import com.android.settings.datausage.lib.NetworkUsageData import com.android.settings.network.MobileNetworkRepository @@ -45,43 +46,42 @@ import kotlin.jvm.optionals.getOrNull * to inspect based on usage cycle and control through [NetworkPolicy]. */ @OpenForTesting -open class DataUsageList : DataUsageBaseFragment() { - @JvmField +open class DataUsageList : DashboardFragment() { @VisibleForTesting var template: NetworkTemplate? = null + private set - @JvmField @VisibleForTesting var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID + private set - private lateinit var usageAmount: Preference - private var subscriptionInfoEntity: SubscriptionInfoEntity? = null - private lateinit var dataUsageListAppsController: DataUsageListAppsController - private lateinit var chartDataUsagePreferenceController: ChartDataUsagePreferenceController private lateinit var billingCycleRepository: BillingCycleRepository - private val viewModel: DataUsageListViewModel by viewModels() + private var usageAmount: Preference? = null + private var subscriptionInfoEntity: SubscriptionInfoEntity? = null + private var dataUsageListAppsController: DataUsageListAppsController? = null + private var chartDataUsagePreferenceController: ChartDataUsagePreferenceController? = null + private var dataUsageListHeaderController: DataUsageListHeaderController? = null - @VisibleForTesting - var dataUsageListHeaderController: DataUsageListHeaderController? = null + private val viewModel: DataUsageListViewModel by viewModels() override fun getMetricsCategory() = SettingsEnums.DATA_USAGE_LIST override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + billingCycleRepository = BillingCycleRepository(requireContext()) if (requireContext().userManager.isGuestUser) { Log.e(TAG, "This setting isn't available for guest user") EventLog.writeEvent(0x534e4554, "262741858", -1 /* UID */, "Guest user") finish() return } - billingCycleRepository = createBillingCycleRepository() if (!billingCycleRepository.isBandwidthControlEnabled()) { Log.w(TAG, "No bandwidth control; leaving") finish() return } - usageAmount = findPreference(KEY_USAGE_AMOUNT)!! + usageAmount = findPreference(KEY_USAGE_AMOUNT) processArgument() val template = template if (template == null) { @@ -94,12 +94,9 @@ open class DataUsageList : DataUsageBaseFragment() { init(template) } chartDataUsagePreferenceController = use(ChartDataUsagePreferenceController::class.java) - chartDataUsagePreferenceController.init(template) + .apply { init(template) } } - @VisibleForTesting - open fun createBillingCycleRepository() = BillingCycleRepository(requireContext()) - override fun onViewCreated(v: View, savedInstanceState: Bundle?) { super.onViewCreated(v, savedInstanceState) @@ -117,10 +114,10 @@ open class DataUsageList : DataUsageBaseFragment() { ::updateSelectedCycle, ) viewModel.cyclesFlow.collectLatestWithLifecycle(viewLifecycleOwner) { cycles -> - dataUsageListAppsController.updateCycles(cycles) + dataUsageListAppsController?.updateCycles(cycles) } viewModel.chartDataFlow.collectLatestWithLifecycle(viewLifecycleOwner) { chartData -> - chartDataUsagePreferenceController.update(chartData) + chartDataUsagePreferenceController?.update(chartData) } } @@ -128,7 +125,7 @@ open class DataUsageList : DataUsageBaseFragment() { override fun getLogTag() = TAG - fun processArgument() { + private fun processArgument() { arguments?.let { subId = it.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID) template = it.getParcelable(EXTRA_NETWORK_TEMPLATE, NetworkTemplate::class.java) @@ -145,8 +142,7 @@ open class DataUsageList : DataUsageBaseFragment() { } } - @VisibleForTesting - open fun updateSubscriptionInfoEntity() { + private fun updateSubscriptionInfoEntity() { ThreadUtils.postOnBackgroundThread { subscriptionInfoEntity = MobileNetworkRepository.getInstance(context).getSubInfoById(subId.toString()) @@ -154,19 +150,16 @@ open class DataUsageList : DataUsageBaseFragment() { } /** Update chart sweeps and cycle list to reflect [NetworkPolicy] for current [template]. */ - @VisibleForTesting - fun updatePolicy() { + private fun updatePolicy() { val isBillingCycleModifiable = isBillingCycleModifiable() dataUsageListHeaderController?.setConfigButtonVisible(isBillingCycleModifiable) - chartDataUsagePreferenceController.setBillingCycleModifiable(isBillingCycleModifiable) + chartDataUsagePreferenceController?.setBillingCycleModifiable(isBillingCycleModifiable) } - @VisibleForTesting - open fun isBillingCycleModifiable(): Boolean { - return (billingCycleRepository.isModifiable(subId) && + private fun isBillingCycleModifiable(): Boolean = + billingCycleRepository.isModifiable(subId) && requireContext().getSystemService(SubscriptionManager::class.java)!! - .getActiveSubscriptionInfo(subId) != null) - } + .getActiveSubscriptionInfo(subId) != null /** * Updates the chart and detail data when initial loaded or selected cycle changed. @@ -174,7 +167,7 @@ open class DataUsageList : DataUsageBaseFragment() { private fun updateSelectedCycle(usageData: NetworkUsageData) { Log.d(TAG, "showing cycle $usageData") - usageAmount.title = usageData.getDataUsedString(requireContext()) + usageAmount?.title = usageData.getDataUsedString(requireContext()) viewModel.selectedCycleFlow.value = usageData updateApps(usageData) @@ -182,7 +175,7 @@ open class DataUsageList : DataUsageBaseFragment() { /** Updates applications data usage. */ private fun updateApps(usageData: NetworkUsageData) { - dataUsageListAppsController.update( + dataUsageListAppsController?.update( carrierId = subscriptionInfoEntity?.carrierId, startTime = usageData.startTime, endTime = usageData.endTime, diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index 5a808f2d485..f4217b6bf48 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -144,7 +144,6 @@ public class BatteryUtils { sInstance = null; } - /** Gets the process time */ public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid, int which) { if (uid == null) { @@ -344,6 +343,25 @@ public class BatteryUtils { } } + /** + * Find package uid from package name + * + * @param packageName used to find the uid + * @param userId The user handle identifier to look up the package under + * @return uid for packageName, or {@link #UID_NULL} if exception happens or {@code packageName} + * is null + */ + public int getPackageUidAsUser(String packageName, int userId) { + try { + return packageName == null + ? UID_NULL + : mPackageManager.getPackageUidAsUser( + packageName, PackageManager.GET_META_DATA, userId); + } catch (PackageManager.NameNotFoundException e) { + return UID_NULL; + } + } + /** * Parses proto object from string. * diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java index 2c376e5fcec..5b05e347fdd 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java @@ -324,7 +324,8 @@ public class BatteryDiffEntry { } } - int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName); + int uid = + BatteryUtils.getInstance(mContext).getPackageUidAsUser(packageName, (int) mUserId); synchronized (sPackageNameAndUidCacheLock) { sPackageNameAndUidCache.put(packageName, uid); } @@ -379,8 +380,7 @@ public class BatteryDiffEntry { mAppIcon = nameAndIconForUser.mIcon; mAppLabel = nameAndIconForUser.mName; putResourceCache( - getKey(), - new NameAndIcon(mAppLabel, mAppIcon, /* iconId= */ 0)); + getKey(), new NameAndIcon(mAppLabel, mAppIcon, /* iconId= */ 0)); } break; case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY: @@ -392,8 +392,7 @@ public class BatteryDiffEntry { mAppIconId = nameAndIconForSystem.mIconId; mAppIcon = mContext.getDrawable(nameAndIconForSystem.mIconId); } - putResourceCache( - getKey(), new NameAndIcon(mAppLabel, mAppIcon, mAppIconId)); + putResourceCache(getKey(), new NameAndIcon(mAppLabel, mAppIcon, mAppIconId)); } break; case ConvertUtils.CONSUMER_TYPE_UID_BATTERY: @@ -406,8 +405,7 @@ public class BatteryDiffEntry { mAppIcon = getBadgeIconForUser(mAppIcon); if (mAppLabel != null || mAppIcon != null) { putResourceCache( - getKey(), - new NameAndIcon(mAppLabel, mAppIcon, /* iconId= */ 0)); + getKey(), new NameAndIcon(mAppLabel, mAppIcon, /* iconId= */ 0)); } break; } diff --git a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java index 4d79a013f7f..e69a336edd5 100644 --- a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java +++ b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java @@ -16,6 +16,7 @@ package com.android.settings.homepage.contextualcards.conditional; +import android.app.Flags; import android.app.NotificationManager; import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; @@ -86,7 +87,12 @@ public class DndConditionCardController implements ConditionalCardController { @Override public void onActionClick() { - mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG); + if (Flags.modesApi()) { + mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG, + /* fromUser= */ true); + } else { + mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG); + } } @Override diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java index f583971cf67..85ba5fb3270 100644 --- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java +++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java @@ -26,10 +26,14 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; import androidx.fragment.app.Fragment; +import com.android.hardware.input.Flags; import com.android.settings.R; //TODO: b/316243168 - [Physical Keyboard Setting] Refactor NewKeyboardLayoutPickerFragment @@ -38,19 +42,25 @@ public class NewKeyboardLayoutPickerFragment extends Fragment { private static final int DEFAULT_KEYBOARD_PREVIEW_HEIGHT = 540; private ImageView mKeyboardLayoutPreview; + private TextView mKeyboardLayoutPreviewText; private InputManager mInputManager; private final NewKeyboardLayoutPickerController.KeyboardLayoutSelectedCallback mKeyboardLayoutSelectedCallback = new NewKeyboardLayoutPickerController.KeyboardLayoutSelectedCallback() { @Override public void onSelected(KeyboardLayout keyboardLayout) { - if (mInputManager != null && mKeyboardLayoutPreview != null) { + if (mInputManager != null + && mKeyboardLayoutPreview != null + && mKeyboardLayoutPreviewText != null && keyboardLayout != null) { Drawable previewDrawable = mInputManager.getKeyboardLayoutPreview( keyboardLayout, DEFAULT_KEYBOARD_PREVIEW_WIDTH, DEFAULT_KEYBOARD_PREVIEW_HEIGHT); mKeyboardLayoutPreview.setVisibility( previewDrawable == null ? GONE : VISIBLE); + mKeyboardLayoutPreviewText.setVisibility( + previewDrawable == null ? GONE : VISIBLE); if (previewDrawable != null) { + mKeyboardLayoutPreviewText.setText(keyboardLayout.getLabel()); mKeyboardLayoutPreview.setImageDrawable(previewDrawable); } } @@ -73,6 +83,10 @@ public class NewKeyboardLayoutPickerFragment extends Fragment { ViewGroup fragmentView = (ViewGroup) inflater.inflate( R.layout.keyboard_layout_picker, container, false); mKeyboardLayoutPreview = fragmentView.findViewById(R.id.keyboard_layout_preview); + mKeyboardLayoutPreviewText = fragmentView.findViewById(R.id.keyboard_layout_preview_name); + if (!Flags.keyboardLayoutPreviewFlag()) { + updateViewMarginForPreviewFlagOff(fragmentView); + } getActivity().getSupportFragmentManager() .beginTransaction() .replace(R.id.keyboard_layout_title, new NewKeyboardLayoutPickerTitle()) @@ -87,4 +101,13 @@ public class NewKeyboardLayoutPickerFragment extends Fragment { .commit(); return fragmentView; } + + private void updateViewMarginForPreviewFlagOff(ViewGroup fragmentView) { + LinearLayout previewContainer = fragmentView.findViewById( + R.id.keyboard_layout_picker_container); + FrameLayout.LayoutParams previewContainerLayoutParams = + (FrameLayout.LayoutParams) previewContainer.getLayoutParams(); + previewContainerLayoutParams.setMargins(0, 0, 0, 0); + previewContainer.setLayoutParams(previewContainerLayoutParams); + } } diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java index 10798652e68..c290c83f5d2 100644 --- a/src/com/android/settings/notification/zen/ZenModeBackend.java +++ b/src/com/android/settings/notification/zen/ZenModeBackend.java @@ -56,7 +56,6 @@ public class ZenModeBackend { @VisibleForTesting protected static final String ZEN_MODE_FROM_NONE = "zen_mode_from_none"; protected static final int SOURCE_NONE = -1; - private static List mDefaultRuleIds; private static ZenModeBackend sInstance; @@ -65,7 +64,7 @@ public class ZenModeBackend { protected NotificationManager.Policy mPolicy; private final NotificationManager mNotificationManager; - private String TAG = "ZenModeSettingsBackend"; + private static final String TAG = "ZenModeSettingsBackend"; private final Context mContext; public static ZenModeBackend getInstance(Context context) { @@ -95,19 +94,32 @@ public class ZenModeBackend { } protected boolean updateZenRule(String id, AutomaticZenRule rule) { - return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule); + if (android.app.Flags.modesApi()) { + return mNotificationManager.updateAutomaticZenRule(id, rule, /* fromUser= */ true); + } else { + return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule); + } } protected void setZenMode(int zenMode) { - NotificationManager.from(mContext).setZenMode(zenMode, null, TAG); + if (android.app.Flags.modesApi()) { + mNotificationManager.setZenMode(zenMode, null, TAG, /* fromUser= */ true); + } else { + NotificationManager.from(mContext).setZenMode(zenMode, null, TAG); + } mZenMode = getZenMode(); } protected void setZenModeForDuration(int minutes) { Uri conditionId = ZenModeConfig.toTimeCondition(mContext, minutes, ActivityManager.getCurrentUser(), true).id; - mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, - conditionId, TAG); + if (android.app.Flags.modesApi()) { + mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, + conditionId, TAG, /* fromUser= */ true); + } else { + mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, + conditionId, TAG); + } mZenMode = getZenMode(); } @@ -180,7 +192,11 @@ public class ZenModeBackend { int priorityConversationSenders) { mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders, priorityMessageSenders, suppressedVisualEffects, priorityConversationSenders); - mNotificationManager.setNotificationPolicy(mPolicy); + if (android.app.Flags.modesApi()) { + mNotificationManager.setNotificationPolicy(mPolicy, /* fromUser= */ true); + } else { + mNotificationManager.setNotificationPolicy(mPolicy); + } } @@ -357,7 +373,11 @@ public class ZenModeBackend { } public boolean removeZenRule(String ruleId) { - return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId); + if (android.app.Flags.modesApi()) { + return mNotificationManager.removeAutomaticZenRule(ruleId, /* fromUser= */ true); + } else { + return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId); + } } public NotificationManager.Policy getConsolidatedPolicy() { @@ -366,7 +386,11 @@ public class ZenModeBackend { protected String addZenRule(AutomaticZenRule rule) { try { - return NotificationManager.from(mContext).addAutomaticZenRule(rule); + if (android.app.Flags.modesApi()) { + return mNotificationManager.addAutomaticZenRule(rule, /* fromUser= */ true); + } else { + return NotificationManager.from(mContext).addAutomaticZenRule(rule); + } } catch (Exception e) { return null; } @@ -429,10 +453,7 @@ public class ZenModeBackend { } private static List getDefaultRuleIds() { - if (mDefaultRuleIds == null) { - mDefaultRuleIds = ZenModeConfig.DEFAULT_RULE_IDS; - } - return mDefaultRuleIds; + return ZenModeConfig.DEFAULT_RULE_IDS; } NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) { diff --git a/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java b/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java index 8082bcdc046..4f6f0587b46 100644 --- a/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java +++ b/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java @@ -19,6 +19,7 @@ package com.android.settings.notification.zen; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; import android.annotation.ColorInt; +import android.app.Flags; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.settings.SettingsEnums; @@ -116,7 +117,12 @@ public class ZenModeSliceBuilder { } else { zenMode = Settings.Global.ZEN_MODE_OFF; } - NotificationManager.from(context).setZenMode(zenMode, null /* conditionId */, TAG); + if (Flags.modesApi()) { + NotificationManager.from(context).setZenMode(zenMode, /* conditionId= */ null, TAG, + /* fromUser= */ true); + } else { + NotificationManager.from(context).setZenMode(zenMode, null /* conditionId */, TAG); + } // Do not notifyChange on Uri. The service takes longer to update the current value than it // does for the Slice to check the current value again. Let {@link SliceBroadcastRelay} // handle it. diff --git a/src/com/android/settings/notification/zen/ZenOnboardingActivity.java b/src/com/android/settings/notification/zen/ZenOnboardingActivity.java index 23c388bf5cd..a6e78eb2068 100644 --- a/src/com/android/settings/notification/zen/ZenOnboardingActivity.java +++ b/src/com/android/settings/notification/zen/ZenOnboardingActivity.java @@ -17,6 +17,7 @@ package com.android.settings.notification.zen; import android.app.Activity; +import android.app.Flags; import android.app.NotificationManager; import android.app.NotificationManager.Policy; import android.app.settings.SettingsEnums; @@ -129,7 +130,11 @@ public class ZenOnboardingActivity extends Activity { Policy.PRIORITY_SENDERS_STARRED, policy.priorityMessageSenders, NotificationManager.Policy.getAllSuppressedVisualEffects()); - mNm.setNotificationPolicy(newPolicy); + if (Flags.modesApi()) { + mNm.setNotificationPolicy(newPolicy, /* fromUser= */ true); + } else { + mNm.setNotificationPolicy(newPolicy); + } mMetrics.action(SettingsEnums.ACTION_ZEN_ONBOARDING_OK); } else { mMetrics.action(SettingsEnums.ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS); diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index 800adb063cb..631c735e6d0 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -260,7 +260,6 @@ public class ChooseLockPassword extends SettingsActivity { private LockscreenCredential mFirstPassword; private RecyclerView mPasswordRestrictionView; protected boolean mIsAlphaMode; - protected boolean mIsManagedProfile; protected FooterButton mSkipOrClearButton; private FooterButton mNextButton; private TextView mMessage; @@ -272,6 +271,14 @@ public class ChooseLockPassword extends SettingsActivity { private static final int CONFIRM_EXISTING_REQUEST = 58; static final int RESULT_FINISHED = RESULT_FIRST_USER; + /** Used to store the profile type for which pin/password is being set */ + protected enum ProfileType { + None, + Managed, + Private, + Other + }; + protected ProfileType mProfileType; /** * Keep track internally of where the user is in choosing a pattern. @@ -285,12 +292,14 @@ public class ChooseLockPassword extends SettingsActivity { R.string.lockpassword_choose_your_password_header_for_fingerprint, R.string.lockpassword_choose_your_password_header_for_face, R.string.lockpassword_choose_your_password_header_for_biometrics, + R.string.private_space_choose_your_password_header, // private space password R.string.lockpassword_choose_your_pin_header, // pin SET_WORK_PROFILE_PIN_HEADER, R.string.lockpassword_choose_your_profile_pin_header, R.string.lockpassword_choose_your_pin_header_for_fingerprint, R.string.lockpassword_choose_your_pin_header_for_face, R.string.lockpassword_choose_your_pin_header_for_biometrics, + R.string.private_space_choose_your_pin_header, // private space pin R.string.lock_settings_picker_biometrics_added_security_message, R.string.lock_settings_picker_biometrics_added_security_message, R.string.next_label), @@ -302,12 +311,14 @@ public class ChooseLockPassword extends SettingsActivity { R.string.lockpassword_confirm_your_password_header, R.string.lockpassword_confirm_your_password_header, R.string.lockpassword_confirm_your_password_header, + R.string.lockpassword_confirm_your_password_header, R.string.lockpassword_confirm_your_pin_header, REENTER_WORK_PROFILE_PIN_HEADER, R.string.lockpassword_reenter_your_profile_pin_header, R.string.lockpassword_confirm_your_pin_header, R.string.lockpassword_confirm_your_pin_header, R.string.lockpassword_confirm_your_pin_header, + R.string.lockpassword_confirm_your_pin_header, 0, 0, R.string.lockpassword_confirm_label), @@ -319,12 +330,14 @@ public class ChooseLockPassword extends SettingsActivity { R.string.lockpassword_confirm_passwords_dont_match, R.string.lockpassword_confirm_passwords_dont_match, R.string.lockpassword_confirm_passwords_dont_match, + R.string.lockpassword_confirm_passwords_dont_match, R.string.lockpassword_confirm_pins_dont_match, UNDEFINED, R.string.lockpassword_confirm_pins_dont_match, R.string.lockpassword_confirm_pins_dont_match, R.string.lockpassword_confirm_pins_dont_match, R.string.lockpassword_confirm_pins_dont_match, + R.string.lockpassword_confirm_pins_dont_match, 0, 0, R.string.lockpassword_confirm_label); @@ -335,29 +348,33 @@ public class ChooseLockPassword extends SettingsActivity { int hintInAlphaForFingerprint, int hintInAlphaForFace, int hintInAlphaForBiometrics, + int hintInAlphaForPrivateProfile, int hintInNumeric, String hintOverrideInNumericForProfile, int hintInNumericForProfile, int hintInNumericForFingerprint, int hintInNumericForFace, int hintInNumericForBiometrics, + int hintInNumericForPrivateProfile, int messageInAlphaForBiometrics, int messageInNumericForBiometrics, int nextButtonText) { this.alphaHint = hintInAlpha; this.alphaHintOverrideForProfile = hintOverrideInAlphaForProfile; - this.alphaHintForProfile = hintInAlphaForProfile; + this.alphaHintForManagedProfile = hintInAlphaForProfile; this.alphaHintForFingerprint = hintInAlphaForFingerprint; this.alphaHintForFace = hintInAlphaForFace; this.alphaHintForBiometrics = hintInAlphaForBiometrics; + this.alphaHintForPrivateProfile = hintInAlphaForPrivateProfile; this.numericHint = hintInNumeric; this.numericHintOverrideForProfile = hintOverrideInNumericForProfile; - this.numericHintForProfile = hintInNumericForProfile; + this.numericHintForManagedProfile = hintInNumericForProfile; this.numericHintForFingerprint = hintInNumericForFingerprint; this.numericHintForFace = hintInNumericForFace; this.numericHintForBiometrics = hintInNumericForBiometrics; + this.numericHintForPrivateProfile = hintInNumericForPrivateProfile; this.alphaMessageForBiometrics = messageInAlphaForBiometrics; this.numericMessageForBiometrics = messageInNumericForBiometrics; @@ -372,16 +389,18 @@ public class ChooseLockPassword extends SettingsActivity { // Password header public final int alphaHint; + public final int alphaHintForPrivateProfile; public final String alphaHintOverrideForProfile; - public final int alphaHintForProfile; + public final int alphaHintForManagedProfile; public final int alphaHintForFingerprint; public final int alphaHintForFace; public final int alphaHintForBiometrics; // PIN header public final int numericHint; + public final int numericHintForPrivateProfile; public final String numericHintOverrideForProfile; - public final int numericHintForProfile; + public final int numericHintForManagedProfile; public final int numericHintForFingerprint; public final int numericHintForFace; public final int numericHintForBiometrics; @@ -394,34 +413,40 @@ public class ChooseLockPassword extends SettingsActivity { public final int buttonText; - public String getHint(Context context, boolean isAlpha, int type, boolean isProfile) { + public String getHint(Context context, boolean isAlpha, int type, ProfileType profile) { if (isAlpha) { - if (type == TYPE_FINGERPRINT) { + if (android.os.Flags.allowPrivateProfile() + && profile.equals(ProfileType.Private)) { + return context.getString(alphaHintForPrivateProfile); + } else if (type == TYPE_FINGERPRINT) { return context.getString(alphaHintForFingerprint); } else if (type == TYPE_FACE) { return context.getString(alphaHintForFace); } else if (type == TYPE_BIOMETRIC) { return context.getString(alphaHintForBiometrics); - } else if (isProfile) { + } else if (profile.equals(ProfileType.Managed)) { return context.getSystemService(DevicePolicyManager.class).getResources() .getString(alphaHintOverrideForProfile, - () -> context.getString(alphaHintForProfile)); + () -> context.getString(alphaHintForManagedProfile)); } else { return context.getString(alphaHint); } } else { - if (type == TYPE_FINGERPRINT) { + if (android.os.Flags.allowPrivateProfile() + && profile.equals(ProfileType.Private)) { + return context.getString(numericHintForPrivateProfile); + } else if (type == TYPE_FINGERPRINT) { return context.getString(numericHintForFingerprint); } else if (type == TYPE_FACE) { return context.getString(numericHintForFace); } else if (type == TYPE_BIOMETRIC) { return context.getString(numericHintForBiometrics); - } else if (isProfile) { + } else if (profile.equals(ProfileType.Managed)) { return context.getSystemService(DevicePolicyManager.class).getResources() .getString(numericHintOverrideForProfile, - () -> context.getString(numericHintForProfile)); + () -> context.getString(numericHintForManagedProfile)); } else { - return context.getString(numericHint); + return context.getString(numericHint); } } } @@ -455,7 +480,7 @@ public class ChooseLockPassword extends SettingsActivity { } // Only take this argument into account if it belongs to the current profile. mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras()); - mIsManagedProfile = UserManager.get(getActivity()).isManagedProfile(mUserId); + mProfileType = getProfileType(); mForFingerprint = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); mForFace = intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false); @@ -602,7 +627,7 @@ public class ChooseLockPassword extends SettingsActivity { if (activity instanceof SettingsActivity) { final SettingsActivity sa = (SettingsActivity) activity; String title = Stage.Introduction.getHint( - getContext(), mIsAlphaMode, getStageType(), mIsManagedProfile); + getContext(), mIsAlphaMode, getStageType(), mProfileType); sa.setTitle(title); mLayout.setHeaderText(title); } @@ -938,7 +963,7 @@ public class ChooseLockPassword extends SettingsActivity { // Hide password requirement view when we are just asking user to confirm the pw. mPasswordRestrictionView.setVisibility(View.GONE); setHeaderText(mUiStage.getHint(getContext(), mIsAlphaMode, getStageType(), - mIsManagedProfile)); + mProfileType)); setNextEnabled(canInput && length >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE); mSkipOrClearButton.setVisibility(toVisibility(canInput && length > 0)); @@ -1084,6 +1109,12 @@ public class ChooseLockPassword extends SettingsActivity { startActivity(intent); } } + + if (mLayout != null) { + mLayout.announceForAccessibility( + getString(R.string.accessibility_setup_password_complete)); + } + getActivity().finish(); } @@ -1110,5 +1141,18 @@ public class ChooseLockPassword extends SettingsActivity { } } } + + private ProfileType getProfileType() { + UserManager userManager = getContext().createContextAsUser(UserHandle.of(mUserId), + /*flags=*/0).getSystemService(UserManager.class); + if (userManager.isManagedProfile()) { + return ProfileType.Managed; + } else if (android.os.Flags.allowPrivateProfile() && userManager.isPrivateProfile()) { + return ProfileType.Private; + } else if (userManager.isProfile()) { + return ProfileType.Other; + } + return ProfileType.None; + } } } diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java index 20d1e7d8cd1..b24a27e9c35 100644 --- a/src/com/android/settings/password/ChooseLockPattern.java +++ b/src/com/android/settings/password/ChooseLockPattern.java @@ -478,6 +478,8 @@ public class ChooseLockPattern extends SettingsActivity { .getString(SET_WORK_PROFILE_PATTERN_HEADER, () -> getString( R.string.lockpassword_choose_your_profile_pattern_header)); + } else if (android.os.Flags.allowPrivateProfile() && isPrivateProfile()) { + msg = getString(R.string.private_space_choose_your_pattern_header); } else { msg = getString(R.string.lockpassword_choose_your_pattern_header); } @@ -871,7 +873,19 @@ public class ChooseLockPattern extends SettingsActivity { startActivity(intent); } } + + if (mSudContent != null) { + mSudContent.announceForAccessibility( + getString(R.string.accessibility_setup_password_complete)); + } + getActivity().finish(); } + + private boolean isPrivateProfile() { + UserManager userManager = getContext().createContextAsUser(UserHandle.of(mUserId), + /*flags=*/0).getSystemService(UserManager.class); + return userManager.isPrivateProfile(); + } } } diff --git a/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java b/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java index 8c733646daa..09a1855134a 100644 --- a/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java +++ b/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java @@ -32,6 +32,14 @@ public class HidePrivateSpaceSettings extends DashboardFragment{ } } + @Override + public void onStart() { + super.onStart(); + if (PrivateSpaceMaintainer.getInstance(getContext()).isPrivateSpaceLocked()) { + finish(); + } + } + @Override public int getMetricsCategory() { return SettingsEnums.PRIVATE_SPACE_SETTINGS; diff --git a/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java b/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java index 20298a1c003..efbe9f9200d 100644 --- a/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java +++ b/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java @@ -20,6 +20,7 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSW import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHOOSE_LOCK_SCREEN_TITLE; import android.content.Context; import android.content.Intent; @@ -94,6 +95,7 @@ public class PrivateSpaceLockController extends AbstractPreferenceController { final Bundle extras = new Bundle(); extras.putInt(Intent.EXTRA_USER_ID, mProfileUserId); extras.putBoolean(HIDE_INSECURE_OPTIONS, true); + extras.putInt(EXTRA_KEY_CHOOSE_LOCK_SCREEN_TITLE, R.string.private_space_lock_setup_title); new SubSettingLauncher(mContext) .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName()) .setSourceMetricsCategory(mHost.getMetricsCategory()) diff --git a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java index 459116ace02..181a8d0ea44 100644 --- a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java +++ b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java @@ -25,6 +25,7 @@ import androidx.annotation.Nullable; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.privatespace.PrivateSpaceMaintainer; import com.android.settingslib.core.AbstractPreferenceController; import java.util.ArrayList; @@ -42,6 +43,14 @@ public class UseOneLockSettingsFragment extends DashboardFragment { } } + @Override + public void onStart() { + super.onStart(); + if (PrivateSpaceMaintainer.getInstance(getContext()).isPrivateSpaceLocked()) { + finish(); + } + } + @Override public int getMetricsCategory() { return SettingsEnums.PRIVATE_SPACE_SETTINGS; diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.kt b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.kt deleted file mode 100644 index 39b844680d2..00000000000 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.kt +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2023 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.datausage - -import android.content.Context -import android.content.Intent -import android.net.NetworkTemplate -import android.os.Bundle -import android.os.UserManager -import android.provider.Settings -import androidx.preference.Preference -import androidx.test.core.app.ApplicationProvider -import com.android.settings.datausage.DataUsageListTest.ShadowDataUsageBaseFragment -import com.android.settings.datausage.TemplatePreference.NetworkServices -import com.android.settings.datausage.lib.BillingCycleRepository -import com.android.settings.testutils.FakeFeatureFactory -import com.android.settingslib.NetworkPolicyEditor -import com.android.settingslib.core.AbstractPreferenceController -import com.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.doNothing -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import org.mockito.Mockito.never -import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` -import org.mockito.Spy -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.annotation.Implementation -import org.robolectric.annotation.Implements -import org.robolectric.util.ReflectionHelpers - -@RunWith(RobolectricTestRunner::class) -@Config(shadows = [ShadowDataUsageBaseFragment::class]) -class DataUsageListTest { - @get:Rule - val mockito: MockitoRule = MockitoJUnit.rule() - - @Mock - private lateinit var networkServices: NetworkServices - - @Mock - private lateinit var userManager: UserManager - - @Mock - private lateinit var billingCycleRepository: BillingCycleRepository - - @Mock - private lateinit var dataUsageListHeaderController: DataUsageListHeaderController - - @Spy - private val context: Context = ApplicationProvider.getApplicationContext() - - @Spy - private val dataUsageList = TestDataUsageList() - - @Before - fun setUp() { - FakeFeatureFactory.setupForTest() - networkServices.mPolicyEditor = mock(NetworkPolicyEditor::class.java) - doReturn(context).`when`(dataUsageList).context - doReturn(userManager).`when`(context).getSystemService(UserManager::class.java) - doReturn(false).`when`(userManager).isGuestUser - ReflectionHelpers.setField(dataUsageList, "services", networkServices) - doNothing().`when`(dataUsageList).updateSubscriptionInfoEntity() - `when`(billingCycleRepository.isBandwidthControlEnabled()).thenReturn(true) - dataUsageList.dataUsageListHeaderController = dataUsageListHeaderController - } - - @Test - fun onCreate_isNotGuestUser_shouldNotFinish() { - dataUsageList.template = mock(NetworkTemplate::class.java) - doReturn(false).`when`(userManager).isGuestUser - doNothing().`when`(dataUsageList).processArgument() - dataUsageList.onCreate(null) - verify(dataUsageList, never()).finish() - } - - @Test - fun onCreate_isGuestUser_shouldFinish() { - doReturn(true).`when`(userManager).isGuestUser - dataUsageList.onCreate(null) - verify(dataUsageList).finish() - } - - @Test - fun processArgument_shouldGetTemplateFromArgument() { - val args = Bundle() - args.putParcelable( - DataUsageList.EXTRA_NETWORK_TEMPLATE, mock( - NetworkTemplate::class.java - ) - ) - args.putInt(DataUsageList.EXTRA_SUB_ID, 3) - dataUsageList.arguments = args - dataUsageList.processArgument() - assertThat(dataUsageList.template).isNotNull() - assertThat(dataUsageList.subId).isEqualTo(3) - } - - @Test - fun processArgument_fromIntent_shouldGetTemplateFromIntent() { - val intent = Intent() - intent.putExtra( - Settings.EXTRA_NETWORK_TEMPLATE, mock( - NetworkTemplate::class.java - ) - ) - intent.putExtra(Settings.EXTRA_SUB_ID, 3) - doReturn(intent).`when`(dataUsageList).intent - dataUsageList.processArgument() - assertThat(dataUsageList.template).isNotNull() - assertThat(dataUsageList.subId).isEqualTo(3) - } - - @Test - fun updatePolicy_setConfigButtonVisible() { - dataUsageList.template = mock(NetworkTemplate::class.java) - dataUsageList.onCreate(null) - - dataUsageList.updatePolicy() - - verify(dataUsageListHeaderController).setConfigButtonVisible(true) - } - - @Implements(DataUsageBaseFragment::class) - class ShadowDataUsageBaseFragment { - @Implementation - fun onCreate(@Suppress("UNUSED_PARAMETER") icicle: Bundle?) { - // do nothing - } - } - - open inner class TestDataUsageList : DataUsageList() { - override fun use(clazz: Class): T = mock(clazz) - - @Suppress("UNCHECKED_CAST") - override fun findPreference(key: CharSequence): T = - mock(Preference::class.java) as T - - public override fun getIntent() = Intent() - - override fun createBillingCycleRepository() = billingCycleRepository - - override fun isBillingCycleModifiable() = true - } -} diff --git a/tests/spa_unit/Android.bp b/tests/spa_unit/Android.bp index c3e99f75dcf..4df625420eb 100644 --- a/tests/spa_unit/Android.bp +++ b/tests/spa_unit/Android.bp @@ -34,6 +34,7 @@ android_test { "androidx.compose.runtime_runtime", "androidx.test.ext.junit", "androidx.test.runner", + "androidx.fragment_fragment-testing", "flag-junit", "mockito-target-extended-minus-junit4", ], diff --git a/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt b/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt new file mode 100644 index 00000000000..29ec0eed352 --- /dev/null +++ b/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2023 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.datausage + +import android.content.Context +import android.content.Intent +import android.net.NetworkTemplate +import android.os.UserManager +import android.provider.Settings +import android.telephony.SubscriptionManager +import androidx.core.os.bundleOf +import androidx.fragment.app.testing.launchFragment +import androidx.fragment.app.testing.withFragment +import androidx.lifecycle.Lifecycle +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spaprivileged.framework.common.userManager +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.stub + +private val mockUserManager: UserManager = mock() + +private val mockContext: Context = spy(ApplicationProvider.getApplicationContext()) { + on { userManager } doReturn mockUserManager +} + +private var fakeIntent = Intent() + +@RunWith(AndroidJUnit4::class) +class DataUsageListTest { + + @Before + fun setUp() { + mockUserManager.stub { + on { isGuestUser } doReturn false + } + fakeIntent = Intent() + } + + @Test + fun launchFragment_withoutArguments_finish() { + val scenario = launchFragment(initialState = Lifecycle.State.CREATED) + + scenario.withFragment { + assertThat(template).isNull() + assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID) + assertThat(activity!!.isFinishing).isTrue() + } + } + + @Test + fun launchFragment_isGuestUser_finish() { + mockUserManager.stub { + on { isGuestUser } doReturn true + } + val fragmentArgs = bundleOf( + DataUsageList.EXTRA_NETWORK_TEMPLATE to mock(), + DataUsageList.EXTRA_SUB_ID to 3, + ) + + val scenario = launchFragment( + fragmentArgs = fragmentArgs, + initialState = Lifecycle.State.CREATED, + ) + + scenario.withFragment { + assertThat(activity!!.isFinishing).isTrue() + } + } + + @Test + fun launchFragment_withArguments_getTemplateFromArgument() { + val fragmentArgs = bundleOf( + DataUsageList.EXTRA_NETWORK_TEMPLATE to mock(), + DataUsageList.EXTRA_SUB_ID to 3, + ) + + val scenario = launchFragment( + fragmentArgs = fragmentArgs, + initialState = Lifecycle.State.CREATED, + ) + + scenario.withFragment { + assertThat(template).isNotNull() + assertThat(subId).isEqualTo(3) + assertThat(activity!!.isFinishing).isFalse() + } + } + + @Test + fun launchFragment_withIntent_getTemplateFromIntent() { + fakeIntent = Intent().apply { + putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mock()) + putExtra(Settings.EXTRA_SUB_ID, 2) + } + + val scenario = launchFragment(initialState = Lifecycle.State.CREATED) + + scenario.withFragment { + assertThat(template).isNotNull() + assertThat(subId).isEqualTo(2) + assertThat(activity!!.isFinishing).isFalse() + } + } +} + +class TestDataUsageList : DataUsageList() { + override fun getContext() = mockContext + + override fun getIntent() = fakeIntent +} diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java index 4601a1cfbaa..fa5af6d4f9e 100644 --- a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -27,12 +28,15 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; +import android.app.Flags; import android.app.NotificationManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -42,6 +46,7 @@ import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -50,6 +55,10 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class ApprovalPreferenceControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule( + SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT); + private Context mContext; private FakeFeatureFactory mFeatureFactory; @Mock @@ -80,7 +89,6 @@ public class ApprovalPreferenceControllerTest { mController.setNm(mNm); mController.setParent(mFragment); mController.setPkgInfo(mPkgInfo); - } @Test @@ -165,6 +173,7 @@ public class ApprovalPreferenceControllerTest { } @Test + @EnableFlags(Flags.FLAG_MODES_API) public void disable() { mController.disable(mCn); verify(mFeatureFactory.metricsFeatureProvider).action( @@ -172,6 +181,7 @@ public class ApprovalPreferenceControllerTest { MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW, "a"); + verify(mNm).removeAutomaticZenRules(eq(mCn.getPackageName()), eq(true)); verify(mNm).setNotificationListenerAccessGranted(mCn, false); } }