Snap for 11237490 from a123021e1d to 24Q2-release

Change-Id: I8f4d4cc2830d82889a6a6c811129ad86fc128f3e
This commit is contained in:
Android Build Coastguard Worker
2023-12-20 00:24:32 +00:00
25 changed files with 442 additions and 253 deletions

View File

@@ -2517,7 +2517,7 @@
<activity android:name=".biometrics.face.FaceEnrollIntroduction"
android:exported="true"
android:screenOrientation="portrait">
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.settings.FACE_ENROLL"/>
<category android:name="android.intent.category.DEFAULT"/>
@@ -2526,12 +2526,12 @@
<activity android:name=".biometrics.face.FaceEnrollIntroductionInternal"
android:exported="false"
android:screenOrientation="portrait"
android:screenOrientation="nosensor"
android:taskAffinity="com.android.settings.root" />
<activity android:name=".biometrics.face.FaceEnrollEducation"
android:exported="false"
android:screenOrientation="portrait"/>
android:screenOrientation="nosensor"/>
<activity android:name=".biometrics.face.FaceEnrollEnrolling"
android:exported="false"
@@ -3885,6 +3885,7 @@
android:launchMode="singleTop"
android:taskAffinity=".wifi.NetworkRequestDialogActivity"
android:exported="true"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize|smallestScreenSize|screenLayout"
android:permission="android.permission.NETWORK_SETTINGS">
<intent-filter>
<action android:name="com.android.settings.wifi.action.NETWORK_REQUEST" />

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/settingslib_colorSurface"/>
<corners android:radius="@dimen/keyboard_picker_radius"/>
</shape>

View File

@@ -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">
<ImageView
android:id="@+id/keyboard_layout_preview"
<FrameLayout
android:id="@+id/keyboard_layout_preview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"/>
android:background="@drawable/keyboard_review_layout_background">
<ImageView
android:id="@+id/keyboard_layout_preview"
android:layout_marginTop="@dimen/keyboard_picker_margin_small"
android:layout_marginBottom="@dimen/keyboard_picker_margin_large"
android:layout_marginHorizontal="@dimen/keyboard_picker_margin_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/keyboard_layout_preview_name"
android:layout_width="match_parent"
android:layout_height="@dimen/keyboard_picker_margin_large"
android:textSize="@dimen/keyboard_picker_text_size"
android:textColor="?android:attr/textColorPrimary"
android:layout_gravity="bottom"
android:gravity="center" />
</FrameLayout>
<FrameLayout
android:id="@+id/keyboard_layout_title"

View File

@@ -27,4 +27,7 @@
<dimen name="text_reading_preview_layout_padding_horizontal_min_suw">24dp</dimen>
<dimen name="text_reading_preview_background_padding_horizontal_min_suw">24dp</dimen>
<!-- Keyboard -->
<dimen name="keyboard_picker_margin">106dp</dimen>
</resources>

View File

@@ -165,6 +165,13 @@
<item name="face_preview_scale" format="float" type="dimen">1.0</item>
<dimen name="face_enroll_intro_illustration_margin_bottom">0dp</dimen>
<!-- Keyboard -->
<dimen name="keyboard_picker_margin_large">68dp</dimen>
<dimen name="keyboard_picker_margin">24dp</dimen>
<dimen name="keyboard_picker_margin_small">16dp</dimen>
<dimen name="keyboard_picker_radius">28dp</dimen>
<dimen name="keyboard_picker_text_size">16sp</dimen>
<!-- RemoteAuth-->
<dimen name="remoteauth_fragment_padding_horizontal">40dp</dimen>
<dimen name="remoteauth_fragment_subtitle_text_size">14sp</dimen>

View File

@@ -1207,7 +1207,7 @@
<!-- Title for the Private Space page. [CHAR LIMIT=60] -->
<string name="private_space_title">Private Space</string>
<!-- Summary for the Private Space page. [CHAR LIMIT=NONE] -->
<string name="private_space_summary">Hide apps in a private folder</string>
<string name="private_space_summary">Keep private apps locked and hidden</string>
<!-- Description for the Private Space page. [CHAR LIMIT=NONE] -->
<string name="private_space_description">Hide apps in a private folder that only you can access</string>
<!-- Title for the Private Space one lock preference. [CHAR LIMIT=60] -->
@@ -1281,7 +1281,7 @@
<!-- Title for private space setup in auto advancing screen informing private space notifications are hidden when locked. [CHAR LIMIT=NONE] -->
<string name="private_space_notifications_hidden_title">Notifications from apps in private space are hidden when it\u2019s locked</string>
<!-- Title for private space setup in auto advancing screen informing photos/files from private space can be shared when unlocked. [CHAR LIMIT=NONE] -->
<string name="private_space_share_photos_title">Unlock your space to share photos or files from private space apps</string>
<string name="private_space_share_photos_title">Unlock private space to share photos or files from private space apps</string>
<!-- Title for private space setup in auto advancing screen informing some system apps are already installed in private space. [CHAR LIMIT=NONE] -->
<string name="private_space_apps_installed_title">Some apps are already installed in your private space</string>
<!-- Title for private space creation error screen. [CHAR LIMIT=60] -->
@@ -1312,6 +1312,12 @@
<string name="private_space_lock_setup_title">Choose a lock for your private space</string>
<!-- private space lock setup screen description [CHAR LIMIT=NONE] -->
<string name="private_space_lock_setup_description">You can unlock your private space using your fingerprint. For security, this option requires a backup lock.</string>
<!-- Header for private space choose your PIN screen [CHAR LIMIT=40] -->
<string name="private_space_choose_your_pin_header">Set a PIN for your private space</string>
<!-- Header for private space choose your password screen [CHAR LIMIT=40] -->
<string name="private_space_choose_your_password_header">Set a password for your private space</string>
<!-- Header for private space choose your pattern screen [CHAR LIMIT=40] -->
<string name="private_space_choose_your_pattern_header">Set a pattern for your private space</string>
<!-- TODO(b/309950257): Remove below strings once QSTIle fulfillment is complete. -->
<!-- Header in hide Private Space settings page to unhide Private Space. [CHAR LIMIT=90] -->
@@ -12633,4 +12639,7 @@
<string name="content_protection_preference_subpage_summary"></string>
<!-- Default information at the bottom of the subpage of content protection settings. Will be overlaid by OEM. -->
<string name="content_protection_preference_subpage_info"></string>
<!-- Content description for setting password complete-->
<string name="accessibility_setup_password_complete">Password is now set up</string>
</resources>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<String> 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<String> getDefaultRuleIds() {
if (mDefaultRuleIds == null) {
mDefaultRuleIds = ZenModeConfig.DEFAULT_RULE_IDS;
}
return mDefaultRuleIds;
return ZenModeConfig.DEFAULT_RULE_IDS;
}
NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>(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 <T : AbstractPreferenceController?> use(clazz: Class<T>): T = mock(clazz)
@Suppress("UNCHECKED_CAST")
override fun <T : Preference?> findPreference(key: CharSequence): T =
mock(Preference::class.java) as T
public override fun getIntent() = Intent()
override fun createBillingCycleRepository() = billingCycleRepository
override fun isBillingCycleModifiable() = true
}
}

View File

@@ -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",
],

View File

@@ -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<UserManager>()
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<TestDataUsageList>(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<NetworkTemplate>(),
DataUsageList.EXTRA_SUB_ID to 3,
)
val scenario = launchFragment<TestDataUsageList>(
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<NetworkTemplate>(),
DataUsageList.EXTRA_SUB_ID to 3,
)
val scenario = launchFragment<TestDataUsageList>(
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<NetworkTemplate>())
putExtra(Settings.EXTRA_SUB_ID, 2)
}
val scenario = launchFragment<TestDataUsageList>(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
}

View File

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