Merge changes from topic "cherrypick-volume-gar-chain-" into udc-qpr-dev
* changes:
Trigger talkback for notification volume change
Add content description to volume title in settings.
diff --git a/res/layout/preference_check_icon.xml b/res/layout/preference_check_icon.xml
index 1b759fc..bd0dd79 100644
--- a/res/layout/preference_check_icon.xml
+++ b/res/layout/preference_check_icon.xml
@@ -20,4 +20,5 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:layout_marginHorizontal="16dp"/>
\ No newline at end of file
+ android:layout_marginHorizontal="16dp"
+ android:contentDescription="@*android:string/checked"/>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3a46343..897d76a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1526,8 +1526,6 @@
<string name="bluetooth_companion_app_remove_association_dialog_title">Disconnect App?</string>
<!-- Bluetooth device details companion apps. The body of confirmation dialog for remove association. [CHAR LIMIT=60] -->
<string name="bluetooth_companion_app_body"><xliff:g id="app_name" example="App Name">%1$s</xliff:g> app will no longer connect to your <xliff:g id="device_name" example="Device Name">%2$s</xliff:g></string>
- <!-- Summary of Bluetooth LE Audio toggle in Device Details. [CHAR LIMIT=40] -->
- <string name="device_details_leaudio_toggle_summary">Experimental. Improves audio quality.</string>
<!-- Bluetooth device details. In the confirmation dialog for unpairing a paired device, this is the label on the button that will complete the unpairing action. -->
<string name="bluetooth_unpair_dialog_forget_confirm_button">Forget device</string>
@@ -6431,7 +6429,7 @@
<!-- Search keywords for the "Delete Guest Activity" section in Multiple Users Screen. [CHAR LIMIT=NONE] -->
<string name="remove_guest_on_exit_keywords">delete, guest, activity, remove, data, visitor, erase</string>
<!-- Title of preference to enable guest calling[CHAR LIMIT=40] -->
- <string name="enable_guest_calling">Allow guest to use phone</string>
+ <string name="enable_guest_calling">Allow guest to make phone calls</string>
<!-- Summary of preference to enable guest calling [CHAR LIMIT=NONE] -->
<string name="enable_guest_calling_summary">Call history will be shared with guest user</string>
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
index 0767e65..6bee62c 100644
--- a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
@@ -81,6 +81,8 @@
final RestrictedSwitchPreference preference =
(RestrictedSwitchPreference) pref;
final CharSequence label = mPkgInfo.applicationInfo.loadLabel(mPm);
+ final boolean isAllowedCn = mCn.flattenToShortString().length()
+ <= NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH;
final boolean isEnabled = isServiceEnabled(mCn);
preference.setChecked(isEnabled);
preference.setOnPreferenceChangeListener((p, newValue) -> {
@@ -105,7 +107,8 @@
return false;
}
});
- preference.updateState(mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isEnabled);
+ preference.updateState(
+ mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isAllowedCn, isEnabled);
}
public void disable(final ComponentName cn) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 701967b..00f18e8 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -116,10 +116,6 @@
pref.setTitle(profile.getNameResource(mCachedDevice.getDevice()));
pref.setOnPreferenceClickListener(this);
pref.setOrder(profile.getOrdinal());
-
- if (profile instanceof LeAudioProfile) {
- pref.setSummary(R.string.device_details_leaudio_toggle_summary);
- }
return pref;
}
diff --git a/src/com/android/settings/localepicker/LocaleDialogFragment.java b/src/com/android/settings/localepicker/LocaleDialogFragment.java
index ad9e10f..f54446a 100644
--- a/src/com/android/settings/localepicker/LocaleDialogFragment.java
+++ b/src/com/android/settings/localepicker/LocaleDialogFragment.java
@@ -164,15 +164,18 @@
public void onClick(DialogInterface dialog, int which) {
if (mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
int result = Activity.RESULT_CANCELED;
+ boolean changed = false;
if (which == DialogInterface.BUTTON_POSITIVE) {
result = Activity.RESULT_OK;
+ changed = true;
}
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
intent.putExtras(bundle);
mParent.onActivityResult(DIALOG_CONFIRM_SYSTEM_DEFAULT, result, intent);
- mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CHANGE_LANGUAGE);
+ mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CHANGE_LANGUAGE,
+ changed);
}
mShouldKeepDialog = false;
}
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
index edd3026..3d7976a 100644
--- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -16,6 +16,7 @@
package com.android.settings.localepicker;
+import android.app.settings.SettingsEnums;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
@@ -37,6 +38,7 @@
import com.android.internal.app.LocalePicker;
import com.android.internal.app.LocaleStore;
import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.shortcut.ShortcutsUpdateTask;
import java.text.NumberFormat;
@@ -210,6 +212,13 @@
Log.e(TAG, String.format(Locale.US,
"Negative position in onItemMove %d -> %d", fromPosition, toPosition));
}
+
+ if (fromPosition != toPosition) {
+ FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
+ .action(mContext, SettingsEnums.ACTION_REORDER_LANGUAGE,
+ mDragLocale.getLocale().toLanguageTag() + " move to " + toPosition);
+ }
+
notifyItemChanged(fromPosition); // to update the numbers
notifyItemChanged(toPosition);
notifyItemMoved(fromPosition, toPosition);
@@ -244,8 +253,13 @@
void removeChecked() {
int itemCount = mFeedItemList.size();
+ LocaleStore.LocaleInfo localeInfo;
for (int i = itemCount - 1; i >= 0; i--) {
- if (mFeedItemList.get(i).getChecked()) {
+ localeInfo = mFeedItemList.get(i);
+ if (localeInfo.getChecked()) {
+ FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
+ .action(mContext, SettingsEnums.ACTION_REMOVE_LANGUAGE,
+ localeInfo.getLocale().toLanguageTag());
mFeedItemList.remove(i);
}
}
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index 55cff3b..dfdb942 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -199,9 +199,11 @@
localeInfo = (LocaleStore.LocaleInfo) data.getSerializableExtra(INTENT_LOCALE_KEY);
String preferencesTags = Settings.System.getString(
getContext().getContentResolver(), Settings.System.LOCALE_PREFERENCES);
-
- mAdapter.addLocale(mayAppendUnicodeTags(localeInfo, preferencesTags));
+ localeInfo = mayAppendUnicodeTags(localeInfo, preferencesTags);
+ mAdapter.addLocale(localeInfo);
updateVisibilityOfRemoveMenu();
+ mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_ADD_LANGUAGE,
+ localeInfo.getLocale().toLanguageTag());
} else if (requestCode == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
localeInfo = mAdapter.getFeedItemList().get(0);
if (resultCode == Activity.RESULT_OK) {
@@ -214,6 +216,9 @@
LocaleDialogFragment localeDialogFragment = LocaleDialogFragment.newInstance();
localeDialogFragment.setArguments(args);
localeDialogFragment.show(mFragmentManager, TAG_DIALOG_NOT_AVAILABLE);
+ mMetricsFeatureProvider.action(getContext(),
+ SettingsEnums.ACTION_NOT_SUPPORTED_SYSTEM_LANGUAGE,
+ localeInfo.getLocale().toLanguageTag());
}
} else {
mAdapter.notifyListChanged(localeInfo);
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 9d953bf..0cd12fe 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.content.Context;
+import android.content.SharedPreferences;
import android.os.ParcelUuid;
import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
@@ -61,6 +62,10 @@
public class SubscriptionUtil {
private static final String TAG = "SubscriptionUtil";
private static final String PROFILE_GENERIC_DISPLAY_NAME = "CARD";
+ @VisibleForTesting
+ static final String SUB_ID = "sub_id";
+ @VisibleForTesting
+ static final String KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME = "unique_subscription_displayName";
private static List<SubscriptionInfo> sAvailableResultsForTesting;
private static List<SubscriptionInfo> sActiveResultsForTesting;
@@ -265,20 +270,21 @@
// Map of SubscriptionId to DisplayName
final Supplier<Stream<DisplayInfo>> originalInfos =
() -> getAvailableSubscriptions(context)
- .stream()
- .filter(i -> {
- // Filter out null values.
- return (i != null && i.getDisplayName() != null);
- })
- .map(i -> {
- DisplayInfo info = new DisplayInfo();
- info.subscriptionInfo = i;
- String displayName = i.getDisplayName().toString();
- info.originalName = TextUtils.equals(displayName, PROFILE_GENERIC_DISPLAY_NAME)
- ? context.getResources().getString(R.string.sim_card)
- : displayName.trim();
- return info;
- });
+ .stream()
+ .filter(i -> {
+ // Filter out null values.
+ return (i != null && i.getDisplayName() != null);
+ })
+ .map(i -> {
+ DisplayInfo info = new DisplayInfo();
+ info.subscriptionInfo = i;
+ String displayName = i.getDisplayName().toString();
+ info.originalName =
+ TextUtils.equals(displayName, PROFILE_GENERIC_DISPLAY_NAME)
+ ? context.getResources().getString(R.string.sim_card)
+ : displayName.trim();
+ return info;
+ });
// TODO(goldmanj) consider using a map of DisplayName to SubscriptionInfos.
// A Unique set of display names
@@ -292,6 +298,14 @@
// If a display name is duplicate, append the final 4 digits of the phone number.
// Creates a mapping of Subscription id to original display name + phone number display name
final Supplier<Stream<DisplayInfo>> uniqueInfos = () -> originalInfos.get().map(info -> {
+ String cachedDisplayName = getDisplayNameFromSharedPreference(
+ context, info.subscriptionInfo.getSubscriptionId());
+ if (!TextUtils.isEmpty(cachedDisplayName)) {
+ Log.d(TAG, "use cached display name : " + cachedDisplayName);
+ info.uniqueName = cachedDisplayName;
+ return info;
+ }
+
if (duplicateOriginalNames.contains(info.originalName)) {
// This may return null, if the user cannot view the phone number itself.
final String phoneNumber = getBidiFormattedPhoneNumber(context,
@@ -299,15 +313,17 @@
String lastFourDigits = "";
if (phoneNumber != null) {
lastFourDigits = (phoneNumber.length() > 4)
- ? phoneNumber.substring(phoneNumber.length() - 4) : phoneNumber;
+ ? phoneNumber.substring(phoneNumber.length() - 4) : phoneNumber;
}
-
if (TextUtils.isEmpty(lastFourDigits)) {
info.uniqueName = info.originalName;
} else {
info.uniqueName = info.originalName + " " + lastFourDigits;
+ Log.d(TAG, "Cache display name [" + info.uniqueName + "] for sub id "
+ + info.subscriptionInfo.getSubscriptionId());
+ saveDisplayNameToSharedPreference(
+ context, info.subscriptionInfo.getSubscriptionId(), info.uniqueName);
}
-
} else {
info.uniqueName = info.originalName;
}
@@ -371,6 +387,27 @@
return getUniqueSubscriptionDisplayName(info.getSubscriptionId(), context);
}
+
+ private static SharedPreferences getDisplayNameSharedPreferences(Context context) {
+ return context.getSharedPreferences(
+ KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME, Context.MODE_PRIVATE);
+ }
+
+ private static SharedPreferences.Editor getDisplayNameSharedPreferenceEditor(Context context) {
+ return getDisplayNameSharedPreferences(context).edit();
+ }
+
+ private static void saveDisplayNameToSharedPreference(
+ Context context, int subId, CharSequence displayName) {
+ getDisplayNameSharedPreferenceEditor(context)
+ .putString(SUB_ID + subId, String.valueOf(displayName))
+ .apply();
+ }
+
+ private static String getDisplayNameFromSharedPreference(Context context, int subid) {
+ return getDisplayNameSharedPreferences(context).getString(SUB_ID + subid, "");
+ }
+
public static String getDisplayName(SubscriptionInfo info) {
final CharSequence name = info.getDisplayName();
if (name != null) {
diff --git a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
index dfe6df2..a6b565a 100644
--- a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
+++ b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
@@ -67,7 +67,9 @@
mUserId = getIntent().getIntExtra(EXTRA_USER_ID, UserHandle.USER_NULL);
CharSequence mAppLabel;
- if (mComponentName == null || mComponentName.getPackageName() == null) {
+ if (mComponentName == null || mComponentName.getPackageName() == null
+ || mComponentName.flattenToString().length()
+ > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
finish();
return;
}
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index 369c4f6..e2ef0dd 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -66,7 +66,6 @@
private static final String TAG = "NotifAccessSettings";
static final String ALLOWED_KEY = "allowed";
static final String NOT_ALLOWED_KEY = "not_allowed";
- private static final int MAX_CN_LENGTH = 500;
private static final ManagedServiceSettings.Config CONFIG =
new ManagedServiceSettings.Config.Builder()
@@ -150,7 +149,8 @@
for (ServiceInfo service : services) {
final ComponentName cn = new ComponentName(service.packageName, service.name);
boolean isAllowed = mNm.isNotificationListenerAccessGranted(cn);
- if (!isAllowed && cn.flattenToString().length() > MAX_CN_LENGTH) {
+ if (!isAllowed && cn.flattenToString().length()
+ > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
continue;
}
diff --git a/src/com/android/settings/password/SetupChooseLockPattern.java b/src/com/android/settings/password/SetupChooseLockPattern.java
index 2cad181..4424b4f 100644
--- a/src/com/android/settings/password/SetupChooseLockPattern.java
+++ b/src/com/android/settings/password/SetupChooseLockPattern.java
@@ -90,6 +90,12 @@
}
// Show the skip button during SUW but not during Settings > Biometric Enrollment
mSkipOrClearButton.setOnClickListener(this::onSkipOrClearButtonClick);
+
+ final View headerView = view.findViewById(R.id.sud_layout_header);
+ final ViewGroup.MarginLayoutParams lp =
+ (ViewGroup.MarginLayoutParams) headerView.getLayoutParams();
+ lp.bottomMargin = 0;
+ view.setLayoutParams(lp);
return view;
}
diff --git a/src/com/android/settings/users/GuestTelephonyPreferenceController.java b/src/com/android/settings/users/GuestTelephonyPreferenceController.java
index a935b8a..2aa808f 100644
--- a/src/com/android/settings/users/GuestTelephonyPreferenceController.java
+++ b/src/com/android/settings/users/GuestTelephonyPreferenceController.java
@@ -17,6 +17,7 @@
package com.android.settings.users;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.UserManager;
@@ -73,6 +74,7 @@
public void updateState(Preference preference) {
super.updateState(preference);
mUserCaps.updateAddUserCapabilities(mContext);
- preference.setVisible(isAvailable() && mUserCaps.mUserSwitcherEnabled);
+ preference.setVisible(isAvailable() && mUserCaps.mUserSwitcherEnabled && mContext
+ .getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
}
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index d9fbc42..93b7c78 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -977,10 +977,10 @@
return;
}
try {
- getContext().getSystemService(UserManager.class)
- .removeUserWhenPossible(UserHandle.of(UserHandle.myUserId()),
- /* overrideDevicePolicy= */ false);
- ActivityManager.getService().switchUser(UserHandle.USER_SYSTEM);
+ mUserManager.removeUserWhenPossible(
+ UserHandle.of(UserHandle.myUserId()), /* overrideDevicePolicy= */ false);
+ ActivityManager.getService().switchUser(
+ mUserManager.getPreviousForegroundUser().getIdentifier());
} catch (RemoteException re) {
Log.e(TAG, "Unable to remove self user");
}
@@ -1099,7 +1099,7 @@
}
mMetricsFeatureProvider.action(getActivity(),
SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED);
- switchToUserId(UserHandle.USER_SYSTEM);
+ switchToUserId(mUserManager.getPreviousForegroundUser().getIdentifier());
}
private int createGuest() {
@@ -1139,8 +1139,8 @@
// Create a new guest in the foreground, and then immediately switch to it
int newGuestUserId = createGuest();
if (newGuestUserId == UserHandle.USER_NULL) {
- Log.e(TAG, "Could not create new guest, switching back to system user");
- switchToUserId(UserHandle.USER_SYSTEM);
+ Log.e(TAG, "Could not create new guest, switching back to previous user");
+ switchToUserId(mUserManager.getPreviousForegroundUser().getIdentifier());
mUserManager.removeUser(oldGuestUserId);
WindowManagerGlobal.getWindowManagerService().lockNow(/* options= */ null);
return;
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAccessConfirmationActivityTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAccessConfirmationActivityTest.java
new file mode 100644
index 0000000..86631ff
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAccessConfirmationActivityTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.notification;
+
+import static com.android.internal.notification.NotificationAccessConfirmationActivityContract.EXTRA_COMPONENT_NAME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.widget.TextView;
+
+import com.android.settings.R;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class NotificationAccessConfirmationActivityTest {
+
+ @Test
+ public void start_showsDialog() {
+ ComponentName cn = new ComponentName("com.example", "com.example.SomeService");
+ installPackage(cn.getPackageName(), "X");
+
+ NotificationAccessConfirmationActivity activity = startActivityWithIntent(cn);
+
+ assertThat(activity.isFinishing()).isFalse();
+ assertThat(getDialogText(activity)).isEqualTo(
+ activity.getString(R.string.notification_listener_security_warning_summary, "X"));
+ }
+
+ @Test
+ public void start_withMissingPackage_finishes() {
+ ComponentName cn = new ComponentName("com.example", "com.example.SomeService");
+
+ NotificationAccessConfirmationActivity activity = startActivityWithIntent(cn);
+
+ assertThat(getDialogText(activity)).isNull();
+ assertThat(activity.isFinishing()).isTrue();
+ }
+
+ @Test
+ public void start_componentNameTooLong_finishes() {
+ ComponentName longCn = new ComponentName("com.example", Strings.repeat("Blah", 150));
+ installPackage(longCn.getPackageName(), "<Unused>");
+
+ NotificationAccessConfirmationActivity activity = startActivityWithIntent(longCn);
+
+ assertThat(getDialogText(activity)).isNull();
+ assertThat(activity.isFinishing()).isTrue();
+ }
+
+ private static NotificationAccessConfirmationActivity startActivityWithIntent(
+ ComponentName cn) {
+ return Robolectric.buildActivity(
+ NotificationAccessConfirmationActivity.class,
+ new Intent().putExtra(EXTRA_COMPONENT_NAME, cn))
+ .setup()
+ .get();
+ }
+
+ private static void installPackage(String packageName, String appName) {
+ PackageInfo pi = new PackageInfo();
+ pi.packageName = packageName;
+ pi.applicationInfo = new ApplicationInfo();
+ pi.applicationInfo.packageName = packageName;
+ pi.applicationInfo.name = appName;
+ shadowOf(RuntimeEnvironment.application.getPackageManager()).installPackage(pi);
+ }
+
+ @Nullable
+ private static String getDialogText(Activity activity) {
+ TextView tv = activity.getWindow().findViewById(android.R.id.message);
+ CharSequence text = (tv != null ? tv.getText() : null);
+ return text != null ? text.toString() : null;
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
index c5e0813..2f46986 100644
--- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
@@ -28,6 +28,7 @@
import android.os.UserHandle;
import android.util.TypedValue;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
@@ -114,6 +115,14 @@
assertThat(button.getVisibility()).isEqualTo(View.VISIBLE);
}
+ @Test
+ public void headerView_noBottomMargin() {
+ final View header = mActivity.findViewById(R.id.sud_layout_header);
+ final ViewGroup.MarginLayoutParams lp =
+ (ViewGroup.MarginLayoutParams) header.getLayoutParams();
+ assertThat(lp.bottomMargin).isEqualTo(0);
+ }
+
private void verifyScreenLockOptionsShown() {
final Button button = mActivity.findViewById(R.id.screen_lock_options);
assertThat(button).isNotNull();
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 249b713..4601a1c 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
@@ -84,6 +84,36 @@
}
@Test
+ public void updateState_enabled() {
+ when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
+ AppOpsManager.MODE_ALLOWED);
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(
+ mContext);
+ pref.setAppOps(mAppOpsManager);
+
+ mController.updateState(pref);
+
+ assertThat(pref.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_invalidCn_disabled() {
+ ComponentName longCn = new ComponentName("com.example.package",
+ com.google.common.base.Strings.repeat("Blah", 150));
+ mController.setCn(longCn);
+ when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
+ AppOpsManager.MODE_ALLOWED);
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(
+ mContext);
+ pref.setAppOps(mAppOpsManager);
+
+ mController.updateState(pref);
+
+ assertThat(pref.isEnabled()).isFalse();
+ }
+
+ @Test
public void updateState_checked() {
when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
AppOpsManager.MODE_ALLOWED);
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
index 63dca7e..f063042 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -16,26 +16,32 @@
package com.android.settings.network;
+import static com.android.settings.network.SubscriptionUtil.KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME;
+import static com.android.settings.network.SubscriptionUtil.SUB_ID;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.Resources;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
-import com.android.settings.R;
-
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.settings.R;
+
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -445,6 +451,35 @@
}
@Test
+ public void getUniqueDisplayName_hasRecord_useRecordBeTheResult() {
+ final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+ final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+ when(info1.getSubscriptionId()).thenReturn(SUBID_1);
+ when(info2.getSubscriptionId()).thenReturn(SUBID_2);
+ when(info1.getDisplayName()).thenReturn(CARRIER_1);
+ when(info2.getDisplayName()).thenReturn(CARRIER_1);
+ when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(info1, info2));
+
+ SharedPreferences sp = mock(SharedPreferences.class);
+ when(mContext.getSharedPreferences(
+ KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME, Context.MODE_PRIVATE)).thenReturn(sp);
+ when(sp.getString(eq(SUB_ID + SUBID_1), anyString())).thenReturn(CARRIER_1 + "6789");
+ when(sp.getString(eq(SUB_ID + SUBID_2), anyString())).thenReturn(CARRIER_1 + "4321");
+
+
+ final CharSequence nameOfSub1 =
+ SubscriptionUtil.getUniqueSubscriptionDisplayName(info1, mContext);
+ final CharSequence nameOfSub2 =
+ SubscriptionUtil.getUniqueSubscriptionDisplayName(info2, mContext);
+
+ assertThat(nameOfSub1).isNotNull();
+ assertThat(nameOfSub2).isNotNull();
+ assertEquals(CARRIER_1 + "6789", nameOfSub1.toString());
+ assertEquals(CARRIER_1 + "4321", nameOfSub2.toString());
+ }
+
+ @Test
public void isInactiveInsertedPSim_nullSubInfo_doesNotCrash() {
assertThat(SubscriptionUtil.isInactiveInsertedPSim(null)).isFalse();
}