Merge "Allow overriding of strings referenced in XML files."
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a50c51a..5cbdb60 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12032,20 +12032,44 @@
<!-- Title of setting on security settings screen on a financed device. This will take the user to a screen with information about what a device administrator can control and their impact on the user's privacy on a financed device. Shown on financed-managed devices only. [CHAR LIMIT=NONE] -->
<string name="financed_privacy_settings">Financed device info</string>
- <!-- Section header. This section shows what information a device administrator can see on a financed device. [CHAR LIMIT=60] -->
- <string name="financed_privacy_exposure_category">Types of information your device administrator can see</string>
- <!-- Label explaining that the device administrator can see data associated on the user's financed device. [CHAR LIMIT=NONE] -->
- <string name="financed_privacy_data">Data associated with your account, such as email and calendar info</string>
- <!-- Section header. This section shows what changes a device administrator made to a financed device. [CHAR LIMIT=60] -->
- <string name="financed_privacy_exposure_changes_category">Changes made by your device administrator</string>
- <!-- Label explaining that the device admin can lock the device and change the user's password on their financed device. [CHAR LIMIT=NONE] -->
- <string name="financed_privacy_lock_device">Device administrator can lock this device and reset password</string>
- <!-- Label explaining that the device admin can wipe the device remotely for a financed device. [CHAR LIMIT=NONE] -->
- <string name="financed_privacy_wipe_device">Device administrator can delete all device data</string>
- <!-- Label explaining that the device admin configured the device to wipe itself when an incorrect password is entered too many times on a financed device. [CHAR LIMIT=NONE] -->
- <string name="financed_privacy_failed_password_wipe_device">Failed password attempts before deleting device data</string>
- <!-- Financed Privacy settings activity header, summarizing the changes a credit provider can make to a financed device. [CHAR LIMIT=NONE] -->
- <string name="financed_privacy_header">Your credit provider can change settings and install software on this device.\n\nTo learn more, contact your creditor provider.</string>
+ <!-- Top introduction on the financed device privacy settings, summarizing the changes a credit provider can make to a financed device. [CHAR LIMIT=NONE] -->
+ <string name="financed_privacy_intro">Your credit provider can change settings and install software on this device.\n\nIf you miss a payment, your device will be locked.\n\nTo learn more, contact your credit provider.</string>
+ <!-- Section header. This section shows what restrictions will be enforced on the device when it is financed. [CHAR LIMIT=60] -->
+ <string name="financed_privacy_restrictions_category">If your device is financed, you can\u2019t:</string>
+ <!-- Label explaining that installing apps from unknown sources beyond Play Store. [CHAR LIMIT=60]-->
+ <string name="financed_privacy_install_apps">Install apps from outside the Play Store</string>
+ <!-- Label explaining that rebooting the device into safe mode. [CHAR LIMIT=60]-->
+ <string name="financed_privacy_safe_mode">Reboot your device into safe mode</string>
+ <!-- Label explaining that adding more than one user into the device. [CHAR LIMIT=60]-->
+ <string name="financed_privacy_multi_users">Add multiple users to your device</string>
+ <!-- Label explaining that updating the date and time on the device. [CHAR LIMIT=60] -->
+ <string name="financed_privacy_config_date_time">Change date, time, and time zones</string>
+ <!-- Label explaining that turning on the developer options on the device. [CHAR LIMIT=40]-->
+ <string name="financed_privacy_developer_options">Use developer options</string>
+ <!-- Section header. This section shows how credit provider would control the device. [CHAR LIMIT=40]-->
+ <string name="financed_privacy_credit_provider_capabilities_category">Your credit provider can:</string>
+ <!-- Label explaining that IMEI can be access by the credit provider. [CHAR LIMIT=40] -->
+ <string name="financed_privacy_IMEI">Access your IMEI number</string>
+ <!-- Label explaining that device can be reset and data can be deleted. [CHAR LIMIT=40]-->
+ <string name="financed_privacy_factory_reset">Factory reset your device</string>
+ <!-- Section header. This section shows what the user can do if the device is locked by the credit provider. [CHAR LIMIT=100] -->
+ <string name="financed_privacy_locked_mode_category">If your device is locked, you can only use it to:</string>
+ <!-- Label explaining that calling emergency numbers. [CHAR LIMIT=40]-->
+ <string name="financed_privacy_emergency_calls">Make emergency calls</string>
+ <!-- Label explaining that access basic system level data including date, time, network status, and battery info. [CHAR LIMIT=100]-->
+ <string name="financed_privacy_system_info">View system info like date, time, network status, and battery</string>
+ <!-- Label explaining that powering on or off the device. [CHAR LIMIT=60]-->
+ <string name="financed_privacy_turn_on_off_device">Turn your device on or off</string>
+ <!-- Label explaining that accessing notifications and text messages. [CHAR LIMIT=60]-->
+ <string name="financed_privacy_notifications">View notifications & text messages</string>
+ <!-- Label explaining that using apps that are allowed to be used by the credit provider when the device is locked. [CHAR LIMIT=100]-->
+ <string name="financed_privacy_allowlisted_apps">Access apps that are allowed by the credit provider</string>
+ <!-- Section header. This sections shows what would happen if the device is fully paid. [CHAR LIMIT=60] -->
+ <string name="financed_privacy_fully_paid_category">Once you pay the full amount:</string>
+ <!-- Label explaining that all previously restrictions enforce by the credit provider will be revoked. [CHAR LIMIT=100]-->
+ <string name="financed_privacy_restrictions_removed">All restrictions are removed from the device</string>
+ <!-- Label explaining that the app installed by credit provider can be uninstalled. [CHAR LIMIT=60]-->
+ <string name="financed_privacy_uninstall_creditor_app">You can uninstall the creditor app</string>
<!-- Strings for displaying which applications were set as default for specific actions. -->
<!-- Title for the apps that have been set as default handlers of camera-related intents. [CHAR LIMIT=30] -->
diff --git a/res/xml/financed_privacy_settings.xml b/res/xml/financed_privacy_settings.xml
index 742d7e1..4e5a46a 100644
--- a/res/xml/financed_privacy_settings.xml
+++ b/res/xml/financed_privacy_settings.xml
@@ -19,66 +19,102 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/financed_privacy_settings">
- <PreferenceCategory android:key="exposure_category"
+ <com.android.settingslib.widget.TopIntroPreference
+ android:title="@string/financed_privacy_intro"
+ settings:searchable="false" />
+
+ <PreferenceCategory android:key="restrictions_category"
+ android:order="100"
+ android:title="@string/financed_privacy_restrictions_category"
+ android:contentDescription="@string/financed_privacy_restrictions_category">
+ <Preference android:key="financed_privacy_install_apps"
+ android:order="110"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_install_apps"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_safe_mode"
+ android:order="120"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_safe_mode"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_multi_users"
+ android:order="130"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_multi_users"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_config_date_time"
+ android:order="140"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_config_date_time"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_developer_options"
+ android:order="150"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_developer_options"
+ android:selectable="false" />
+ </PreferenceCategory>
+
+ <PreferenceCategory android:key="credit_provider_capabilities_category"
android:order="200"
- android:title="@string/financed_privacy_exposure_category"
- android:contentDescription="@string/financed_privacy_exposure_category">
- <Preference android:key="enterprise_privacy_enterprise_data"
+ android:title="@string/financed_privacy_credit_provider_capabilities_category"
+ android:contentDescription="@string/financed_privacy_credit_provider_capabilities_category">
+ <Preference android:key="financed_privacy_IMEI"
android:order="210"
android:layout_height="wrap_content"
- android:title="@string/financed_privacy_data"
- android:selectable="false"/>
- <Preference android:key="enterprise_privacy_installed_packages"
+ android:title="@string/financed_privacy_IMEI"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_factory_reset"
android:order="220"
- android:title="@string/enterprise_privacy_installed_packages"
- android:selectable="false"/>
- <Preference android:key="enterprise_privacy_usage_stats"
- android:order="230"
- android:title="@string/enterprise_privacy_usage_stats"
- android:selectable="false"/>
- <Preference android:key="network_logs"
- android:order="240"
- android:title="@string/enterprise_privacy_network_logs"
- android:selectable="false"/>
- <Preference android:key="bug_reports"
- android:order="250"
- android:title="@string/enterprise_privacy_bug_reports"
- android:selectable="false"/>
- <Preference android:key="security_logs"
- android:order="260"
- android:title="@string/enterprise_privacy_security_logs"
- android:selectable="false"/>
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_factory_reset"
+ android:selectable="false" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/financed_privacy_exposure_changes_category"
+ <PreferenceCategory android:key="locked_mode_category"
android:order="300"
- android:key="exposure_changes_category">
- <Preference android:fragment="com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages"
+ android:title="@string/financed_privacy_locked_mode_category"
+ android:contentDescription="@string/financed_privacy_locked_mode_category">
+ <Preference android:key="financed_privacy_emergency_calls"
android:order="310"
- android:key="number_enterprise_installed_packages"
- android:title="@string/enterprise_privacy_enterprise_installed_packages"/>
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_emergency_calls"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_system_info"
+ android:order="320"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_system_info"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_turn_on_off_device"
+ android:order="330"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_turn_on_off_device"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_notifications"
+ android:order="340"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_notifications"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_allowlisted_apps"
+ android:order="350"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_allowlisted_apps"
+ android:selectable="false" />
</PreferenceCategory>
- <PreferenceCategory android:key="device_access_category"
- android:order="500"
- android:title="@string/enterprise_privacy_device_access_category">
- <Preference android:key="enterprise_privacy_lock_device"
- android:order="510"
- android:title="@string/financed_privacy_lock_device"
- android:selectable="false"/>
- <Preference android:key="enterprise_privacy_wipe_device"
- android:order="520"
- android:title="@string/financed_privacy_wipe_device"
- android:selectable="false"/>
- <Preference android:key="failed_password_wipe_current_user"
- android:order="530"
- android:title="@string/financed_privacy_failed_password_wipe_device"
- android:selectable="false"/>
+ <PreferenceCategory android:key="fully_paid_category"
+ android:order="400"
+ android:title="@string/financed_privacy_fully_paid_category"
+ android:contentDescription="@string/financed_privacy_fully_paid_category">
+ <Preference android:key="financed_privacy_restrictions_removed"
+ android:order="410"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_restrictions_removed"
+ android:selectable="false" />
+ <Preference android:key="financed_privacy_uninstall_creditor_app"
+ android:order="420"
+ android:layout_height="wrap_content"
+ android:title="@string/financed_privacy_uninstall_creditor_app"
+ android:selectable="false" />
</PreferenceCategory>
- <com.android.settingslib.widget.FooterPreference
- android:key="financed_privacy_footer"
- android:title="@string/financed_privacy_header"
- android:selectable="false"
- settings:searchable="false"/>
</PreferenceScreen>
diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 40867aa..b70470b 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -42,7 +42,7 @@
public class FallbackHome extends Activity {
private static final String TAG = "FallbackHome";
- private static final int PROGRESS_TIMEOUT = 2000;
+ private int mProgressTimeout;
private boolean mProvisioned;
private WallpaperManager mWallManager;
@@ -76,6 +76,12 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mProgressTimeout = getResources().getInteger(
+ com.android.internal.R.integer.config_progressTimeoutFallbackHome);
+
+ if (mProgressTimeout <= 0) {
+ mProgressTimeout = 0;
+ }
// Set ourselves totally black before the device is provisioned so that
// we don't flash the wallpaper before SUW
@@ -107,7 +113,7 @@
protected void onResume() {
super.onResume();
if (mProvisioned) {
- mHandler.postDelayed(mProgressTimeoutRunnable, PROGRESS_TIMEOUT);
+ mHandler.postDelayed(mProgressTimeoutRunnable, mProgressTimeout);
}
}
diff --git a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
index f9b537b..5fc4cd2 100644
--- a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
@@ -221,6 +221,13 @@
extras.putString(AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME,
new ComponentName(packageName, settingsClassName).flattenToString());
}
+
+ final String tileServiceClassName = info.getTileServiceClassName();
+ if (!TextUtils.isEmpty(tileServiceClassName)) {
+ extras.putString(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME,
+ new ComponentName(packageName, tileServiceClassName).flattenToString());
+ }
+
extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, componentName);
extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, info.getAnimatedImageRes());
diff --git a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java
index 0ca16cb..773c987 100644
--- a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java
+++ b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java
@@ -46,6 +46,7 @@
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.RawRes;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
@@ -125,9 +126,15 @@
}
static AlertDialog createAccessibilityTutorialDialog(Context context, int shortcutTypes) {
+ return createAccessibilityTutorialDialog(context, shortcutTypes, mOnClickListener);
+ }
+
+ static AlertDialog createAccessibilityTutorialDialog(Context context, int shortcutTypes,
+ @Nullable DialogInterface.OnClickListener negativeButtonListener) {
return new AlertDialog.Builder(context)
.setView(createShortcutNavigationContentView(context, shortcutTypes))
- .setNegativeButton(R.string.accessibility_tutorial_dialog_button, mOnClickListener)
+ .setNegativeButton(R.string.accessibility_tutorial_dialog_button,
+ negativeButtonListener)
.create();
}
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index b712b9d..e834640 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -97,6 +97,7 @@
static final String EXTRA_SETTINGS_TITLE = "settings_title";
static final String EXTRA_COMPONENT_NAME = "component_name";
static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
+ static final String EXTRA_TILE_SERVICE_COMPONENT_NAME = "tile_service_component_name";
static final String EXTRA_VIDEO_RAW_RESOURCE_ID = "video_resource";
static final String EXTRA_LAUNCHED_FROM_SUW = "from_suw";
static final String EXTRA_ANIMATED_IMAGE_RES = "animated_image_res";
@@ -573,11 +574,13 @@
serviceEnabled);
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
+ final String tileServiceClassName = info.getTileServiceClassName();
putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
componentName);
putServiceExtras(preference, resolveInfo, serviceEnabled);
putSettingsExtras(preference, packageName, settingsClassName);
+ putTileServiceExtras(preference, packageName, tileServiceClassName);
preferenceList.add(preference);
}
@@ -631,10 +634,13 @@
final int imageRes = info.getAnimatedImageRes();
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
+ final String tileServiceClassName = info.getTileServiceClassName();
putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
componentName);
putSettingsExtras(preference, componentName.getPackageName(), settingsClassName);
+ putTileServiceExtras(preference, componentName.getPackageName(),
+ tileServiceClassName);
preferenceList.add(preference);
}
@@ -730,7 +736,11 @@
/**
* Puts the service extras into {@link RestrictedPreference}'s getExtras().
*
- * Called by {@link AccessibilityServiceInfo} for now.
+ * <p><b>Note:</b> Called by {@link AccessibilityServiceInfo}.</p>
+ *
+ * @param preference The preference we are configuring.
+ * @param resolveInfo The service resolve info.
+ * @param serviceEnabled Whether the accessibility service is enabled.
*/
private void putServiceExtras(RestrictedPreference preference, ResolveInfo resolveInfo,
Boolean serviceEnabled) {
@@ -743,7 +753,12 @@
/**
* Puts the settings extras into {@link RestrictedPreference}'s getExtras().
*
- * Called when settings UI is needed.
+ * <p><b>Note:</b> Called when settings UI is needed.</p>
+ *
+ * @param preference The preference we are configuring.
+ * @param packageName Package of accessibility feature.
+ * @param settingsClassName The component name of an activity that allows the user to modify
+ * the settings for this accessibility feature.
*/
private void putSettingsExtras(RestrictedPreference preference, String packageName,
String settingsClassName) {
@@ -756,5 +771,27 @@
new ComponentName(packageName, settingsClassName).flattenToString());
}
}
+
+ /**
+ * Puts the information about a particular application
+ * {@link android.service.quicksettings.TileService} into {@link RestrictedPreference}'s
+ * getExtras().
+ *
+ * <p><b>Note:</b> Called when a tooltip of
+ * {@link android.service.quicksettings.TileService} is needed.</p>
+ *
+ * @param preference The preference we are configuring.
+ * @param packageName Package of accessibility feature.
+ * @param tileServiceClassName The component name of tileService is associated with this
+ * accessibility feature.
+ */
+ private void putTileServiceExtras(RestrictedPreference preference, String packageName,
+ String tileServiceClassName) {
+ final Bundle extras = preference.getExtras();
+ if (!TextUtils.isEmpty(tileServiceClassName)) {
+ extras.putString(EXTRA_TILE_SERVICE_COMPONENT_NAME,
+ new ComponentName(packageName, tileServiceClassName).flattenToString());
+ }
+ }
}
}
diff --git a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
index 00f2804..ce8db21 100644
--- a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
@@ -20,9 +20,11 @@
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.app.ActivityOptions;
+import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
@@ -51,6 +53,7 @@
private static final String TAG = "LaunchA11yActivity";
private static final String EMPTY_STRING = "";
protected static final String KEY_LAUNCH_PREFERENCE = "launch_preference";
+ private ComponentName mTileComponentName;
@Override
public int getMetricsCategory() {
@@ -106,6 +109,13 @@
AccessibilitySettings.EXTRA_SETTINGS_TITLE);
mSettingsIntent = TextUtils.isEmpty(settingsTitle) ? null : getSettingsIntent(arguments);
mSettingsTitle = (mSettingsIntent == null) ? null : settingsTitle;
+
+ // Tile service.
+ if (arguments.containsKey(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME)) {
+ final String tileServiceComponentName = arguments.getString(
+ AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME);
+ mTileComponentName = ComponentName.unflattenFromString(tileServiceComponentName);
+ }
}
@Override
@@ -116,12 +126,30 @@
@Override
ComponentName getTileComponentName() {
- return null;
+ return mTileComponentName;
}
@Override
CharSequence getTileName() {
- return null;
+ final ComponentName componentName = getTileComponentName();
+ if (componentName == null) {
+ return null;
+ }
+ return loadTileLabel(getPrefContext(), componentName);
+ }
+
+ @Override
+ public Dialog onCreateDialog(int dialogId) {
+ switch (dialogId) {
+ case AccessibilityDialogUtils.DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
+ final Dialog dialog = AccessibilityGestureNavigationTutorial
+ .createAccessibilityTutorialDialog(getPrefContext(),
+ getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
+ dialog.setCanceledOnTouchOutside(false);
+ return dialog;
+ default:
+ return super.onCreateDialog(dialogId);
+ }
}
@Override
@@ -208,4 +236,22 @@
return settingsIntent;
}
+
+ /**
+ * This method will be invoked when a button in the tutorial dialog is clicked.
+ *
+ * @param dialog The dialog that received the click
+ * @param which The button that was clicked
+ */
+ private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ showQuickSettingsTooltipIfNeeded();
+ }
+
+
+ @Override
+ protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
+ super.callOnAlertDialogCheckboxClicked(dialog, which);
+ showQuickSettingsTooltipIfNeeded(getShortcutTypeCheckBoxValue());
+ }
}
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index a1c98cd..d7a506a 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -65,6 +65,7 @@
private static final String EMPTY_STRING = "";
private Dialog mWarningDialog;
+ private ComponentName mTileComponentName;
private BroadcastReceiver mPackageRemovedReceiver;
private boolean mDisabledStateLogged = false;
private long mStartTimeMillsForLogging = 0;
@@ -168,9 +169,9 @@
@Override
public Dialog onCreateDialog(int dialogId) {
+ final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
switch (dialogId) {
- case DialogEnums.ENABLE_WARNING_FROM_TOGGLE: {
- final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
+ case DialogEnums.ENABLE_WARNING_FROM_TOGGLE:
if (info == null) {
return null;
}
@@ -178,10 +179,8 @@
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromEnableToggleClicked,
this::onDialogButtonFromUninstallClicked);
- break;
- }
- case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE: {
- final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
+ return mWarningDialog;
+ case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE:
if (info == null) {
return null;
}
@@ -189,10 +188,8 @@
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromShortcutToggleClicked,
this::onDialogButtonFromUninstallClicked);
- break;
- }
- case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT: {
- final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
+ return mWarningDialog;
+ case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT:
if (info == null) {
return null;
}
@@ -200,23 +197,24 @@
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromShortcutClicked,
this::onDialogButtonFromUninstallClicked);
- break;
- }
- case DialogEnums.DISABLE_WARNING_FROM_TOGGLE: {
- final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
+ return mWarningDialog;
+ case DialogEnums.DISABLE_WARNING_FROM_TOGGLE:
if (info == null) {
return null;
}
mWarningDialog = AccessibilityServiceWarning
.createDisableDialog(getPrefContext(), info,
this::onDialogButtonFromDisableToggleClicked);
- break;
- }
- default: {
- mWarningDialog = super.onCreateDialog(dialogId);
- }
+ return mWarningDialog;
+ case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
+ final Dialog dialog = AccessibilityGestureNavigationTutorial
+ .createAccessibilityTutorialDialog(getPrefContext(),
+ getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
+ dialog.setCanceledOnTouchOutside(false);
+ return dialog;
+ default:
+ return super.onCreateDialog(dialogId);
}
- return mWarningDialog;
}
@Override
@@ -243,12 +241,16 @@
@Override
ComponentName getTileComponentName() {
- return null;
+ return mTileComponentName;
}
@Override
CharSequence getTileName() {
- return null;
+ final ComponentName componentName = getTileComponentName();
+ if (componentName == null) {
+ return null;
+ }
+ return loadTileLabel(getPrefContext(), componentName);
}
@Override
@@ -386,6 +388,12 @@
mPackageName = getAccessibilityServiceInfo().getResolveInfo().loadLabel(
getPackageManager());
+ if (arguments.containsKey(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME)) {
+ final String tileServiceComponentName = arguments.getString(
+ AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME);
+ mTileComponentName = ComponentName.unflattenFromString(tileServiceComponentName);
+ }
+
mStartTimeMillsForLogging = arguments.getLong(AccessibilitySettings.EXTRA_TIME_FOR_LOGGING);
}
@@ -488,6 +496,23 @@
mWarningDialog.dismiss();
}
+ /**
+ * This method will be invoked when a button in the tutorial dialog is clicked.
+ *
+ * @param dialog The dialog that received the click
+ * @param which The button that was clicked
+ */
+ private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ showQuickSettingsTooltipIfNeeded();
+ }
+
+ @Override
+ protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
+ super.callOnAlertDialogCheckboxClicked(dialog, which);
+ showQuickSettingsTooltipIfNeeded(getShortcutTypeCheckBoxValue());
+ }
+
void onDialogButtonFromShortcutClicked(View view) {
final int viewId = view.getId();
if (viewId == R.id.permission_enable_allow_button) {
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 0cc1f1c..08e9b88 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -25,7 +25,9 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
import android.icu.text.CaseMap;
import android.net.Uri;
@@ -33,6 +35,7 @@
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.quicksettings.TileService;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -799,6 +802,19 @@
}
/**
+ * Shows the quick settings tooltip if the quick settings service and the shortcut are assigned.
+ * The tooltip only shows once.
+ *
+ * @param shortcutType The shortcut type.
+ */
+ protected void showQuickSettingsTooltipIfNeeded(@UserShortcutType int shortcutType) {
+ if (shortcutType == AccessibilityUtil.UserShortcutType.EMPTY) {
+ return;
+ }
+ showQuickSettingsTooltipIfNeeded();
+ }
+
+ /**
* Shows the quick settings tooltip if the quick settings service is assigned. The tooltip only
* shows once.
*/
@@ -830,4 +846,20 @@
tileComponentName);
mNeedsQSTooltipReshow = false;
}
+
+ /** Returns user visible name of the tile by given {@link ComponentName}. */
+ protected CharSequence loadTileLabel(Context context, ComponentName componentName) {
+ final PackageManager packageManager = context.getPackageManager();
+ final Intent queryIntent = new Intent(TileService.ACTION_QS_TILE);
+ final List<ResolveInfo> resolveInfos =
+ packageManager.queryIntentServices(queryIntent, PackageManager.GET_META_DATA);
+ for (ResolveInfo info : resolveInfos) {
+ final ServiceInfo serviceInfo = info.serviceInfo;
+ if (TextUtils.equals(componentName.getPackageName(), serviceInfo.packageName)
+ && TextUtils.equals(componentName.getClassName(), serviceInfo.name)) {
+ return serviceInfo.loadLabel(packageManager);
+ }
+ }
+ return null;
+ }
}
diff --git a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
index aee360e..164cfd9 100644
--- a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
+++ b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
@@ -18,6 +18,7 @@
import static com.android.settings.widget.EntityHeaderController.ActionType;
import android.app.Activity;
+import android.app.LocaleConfig;
import android.app.LocaleManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -289,12 +290,18 @@
@VisibleForTesting
void handleSupportedLocales() {
- //TODO Waiting for PackageManager api
- String[] languages = getAssetSystemLocales();
-
- for (String language : languages) {
- mSupportedLocales.add(Locale.forLanguageTag(language));
+ LocaleList localeList = getPackageLocales();
+ if (localeList == null) {
+ String[] languages = getAssetSystemLocales();
+ for (String language : languages) {
+ mSupportedLocales.add(Locale.forLanguageTag(language));
+ }
+ } else {
+ for (int i = 0; i < localeList.size(); i++) {
+ mSupportedLocales.add(localeList.get(i));
+ }
}
+
if (mSuggestedLocales != null || !mSuggestedLocales.isEmpty()) {
mSupportedLocales.removeAll(mSuggestedLocales);
}
@@ -349,9 +356,23 @@
packageManager.getPackageInfo(mPackageName, PackageManager.MATCH_ALL)
.applicationInfo).getAssets().getNonSystemLocales();
} catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Can not found the package name : " + e);
+ Log.w(TAG, "Can not found the package name : " + mPackageName + " / " + e);
}
return new String[0];
}
+
+ @VisibleForTesting
+ LocaleList getPackageLocales() {
+ try {
+ LocaleConfig localeConfig =
+ new LocaleConfig(mContext.createPackageContext(mPackageName, 0));
+ if (localeConfig.getStatus() == LocaleConfig.STATUS_SUCCESS) {
+ return localeConfig.getSupportedLocales();
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Can not found the package name : " + mPackageName + " / " + e);
+ }
+ return null;
+ }
}
}
diff --git a/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java b/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java
index fb75695..bd8169a 100644
--- a/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java
@@ -16,8 +16,9 @@
package com.android.settings.development;
-import android.bluetooth.BluetoothManager;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.os.SystemProperties;
import androidx.annotation.VisibleForTesting;
@@ -39,13 +40,20 @@
static final String MAX_CONNECTED_AUDIO_DEVICES_PROPERTY =
"persist.bluetooth.maxconnectedaudiodevices";
- private final int mDefaultMaxConnectedAudioDevices;
+ private int mDefaultMaxConnectedAudioDevices = 0;
public BluetoothMaxConnectedAudioDevicesPreferenceController(Context context) {
super(context);
- BluetoothManager mBluetoothManager = context.getSystemService(BluetoothManager.class);
- mDefaultMaxConnectedAudioDevices = mBluetoothManager.getAdapter()
- .getMaxConnectedAudioDevices();
+
+ try {
+ Resources res = context.getPackageManager().getResourcesForApplication(
+ "com.android.bluetooth");
+ mDefaultMaxConnectedAudioDevices = res.getInteger(res.getIdentifier(
+ "config_bluetooth_max_connected_audio_devices",
+ "integer", "com.android.bluetooth"));
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
}
@Override
diff --git a/src/com/android/settings/display/darkmode/BedtimeSettings.java b/src/com/android/settings/display/darkmode/BedtimeSettings.java
index d9a458c..28121b2 100644
--- a/src/com/android/settings/display/darkmode/BedtimeSettings.java
+++ b/src/com/android/settings/display/darkmode/BedtimeSettings.java
@@ -17,11 +17,13 @@
package com.android.settings.display.darkmode;
import static android.provider.Settings.ACTION_BEDTIME_SETTINGS;
+import static android.util.FeatureFlagUtils.SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.util.FeatureFlagUtils;
import androidx.annotation.Nullable;
@@ -44,6 +46,10 @@
*/
@Nullable
public Intent getBedtimeSettingsIntent() {
+ if (!FeatureFlagUtils.isEnabled(mContext,
+ SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME)) {
+ return null;
+ }
Intent bedtimeSettingsIntent = new Intent(ACTION_BEDTIME_SETTINGS).setPackage(
mWellbeingPackage);
ResolveInfo bedtimeSettingInfo = mPackageManager.resolveActivity(bedtimeSettingsIntent,
diff --git a/src/com/android/settings/enterprise/PrivacySettingsFinancedPreference.java b/src/com/android/settings/enterprise/PrivacySettingsFinancedPreference.java
index 12901a6..8612f6a 100644
--- a/src/com/android/settings/enterprise/PrivacySettingsFinancedPreference.java
+++ b/src/com/android/settings/enterprise/PrivacySettingsFinancedPreference.java
@@ -20,10 +20,8 @@
import android.provider.SearchIndexableResource;
import com.android.settings.R;
-import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -61,18 +59,6 @@
*/
@Override
public List<AbstractPreferenceController> createPreferenceControllers(boolean async) {
- final List<AbstractPreferenceController> controllers = new ArrayList<>();
- controllers.add(new NetworkLogsPreferenceController(mContext));
- controllers.add(new BugReportsPreferenceController(mContext));
- controllers.add(new SecurityLogsPreferenceController(mContext));
- final List<AbstractPreferenceController> exposureChangesCategoryControllers =
- new ArrayList<>();
- exposureChangesCategoryControllers.add(new EnterpriseInstalledPackagesPreferenceController(
- mContext, async));
- controllers.addAll(exposureChangesCategoryControllers);
- controllers.add(new PreferenceCategoryController(mContext, KEY_EXPOSURE_CHANGES_CATEGORY)
- .setChildren(exposureChangesCategoryControllers));
- controllers.add(new FailedPasswordWipeCurrentUserPreferenceController(mContext));
- return controllers;
+ return Collections.emptyList();
}
}
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 85bb0ea..ab3ed20 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -65,6 +65,7 @@
private LocationSwitchBarController mSwitchBarController;
private LocationEnabler mLocationEnabler;
+ private RecentLocationAccessPreferenceController mController;
@Override
public int getMetricsCategory() {
@@ -88,13 +89,22 @@
super.onAttach(context);
use(AppLocationPermissionPreferenceController.class).init(this);
- use(RecentLocationAccessPreferenceController.class).init(this);
+ mController = use(RecentLocationAccessPreferenceController.class);
+ mController.init(this);
use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
use(LocationForWorkPreferenceController.class).init(this);
use(LocationSettingsFooterPreferenceController.class).init(this);
}
@Override
+ public void onPause() {
+ super.onPause();
+ if (mController != null) {
+ mController.clearPreferenceList();
+ }
+ }
+
+ @Override
protected int getPreferenceScreenResId() {
return R.xml.location_settings;
}
diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
index ba660ee..ea3704c 100644
--- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
@@ -127,6 +127,15 @@
}
/**
+ * Clears the list of apps which recently accessed location from the screen.
+ */
+ public void clearPreferenceList() {
+ if (mCategoryRecentLocationRequests != null) {
+ mCategoryRecentLocationRequests.removeAll();
+ }
+ }
+
+ /**
* Initialize {@link ProfileSelectFragment.ProfileType} of the controller
*
* @param type {@link ProfileSelectFragment.ProfileType} of the controller.
diff --git a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
index 9524164..c6d1ea0 100644
--- a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
+++ b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
@@ -69,20 +69,15 @@
}
}
- /** Starts calling EuiccManager#switchToSubscription to enable/disable the eSIM profile. */
- // ToDo: delete this api and refactor the related code.
- public void run(int subscriptionId) {
- setState(State.RUNNING, Substate.UNUSED);
- mCallbackIntent = createCallbackIntent();
- mEuiccManager.switchToSubscription(subscriptionId, mCallbackIntent);
- }
-
/**
* Starts calling EuiccManager#switchToSubscription to enable/disable the eSIM profile.
*
* @param subscriptionId the esim's subscriptionId.
- * @param port the esim's portId. If user wants to inactivate esim, then user must to assign the
- * the port. If user wants to activate esim, then the port can be -1.
+ * @param port the esim's portId. If user wants to inactivate esim, then user must to assign
+ * the corresponding port. If user wants to activate esim, then the port can be
+ * {@link UiccSlotUtil#INVALID_PORT_ID}. When it is
+ * {@link UiccSlotUtil#INVALID_PORT_ID}, the system will reassign a corresponding
+ * port id.
* @param removedSubInfo if the all of slots have sims, it should remove the one of active sim.
* If the removedSubInfo is null, then use the default value.
* The default value is the esim slot and portId 0.
diff --git a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
index 9b9c0dd..e98b405 100644
--- a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
+++ b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
@@ -81,29 +81,6 @@
}
/**
- * Starts switching to the removable slot. It disables the active eSIM profile before switching
- * if there is one.
- *
- * @param physicalSlotId removable physical SIM slot ID.
- */
- // ToDo: delete this api and refactor the related code.
- public void run(int physicalSlotId) {
- mPhysicalSlotId = physicalSlotId;
- SubscriptionManager subscriptionManager =
- getContext().getSystemService(SubscriptionManager.class);
- if (SubscriptionUtil.getActiveSubscriptions(subscriptionManager).stream()
- .anyMatch(SubscriptionInfo::isEmbedded)) {
- // In SS mode, the esim is active, then inactivate the esim.
- Log.i(TAG, "There is an active eSIM profile. Disable the profile first.");
- // Use INVALID_SUBSCRIPTION_ID to disable the only active profile.
- mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID, 0, null);
- } else {
- Log.i(TAG, "There is no active eSIM profiles. Start to switch to removable slot.");
- mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, null);
- }
- }
-
- /**
* Starts switching to the removable slot.
*
* @param physicalSlotId removable physical SIM slot ID.
diff --git a/src/com/android/settings/sim/ChooseSimActivity.java b/src/com/android/settings/sim/ChooseSimActivity.java
index d0ccc4c..cebc1ba 100644
--- a/src/com/android/settings/sim/ChooseSimActivity.java
+++ b/src/com/android/settings/sim/ChooseSimActivity.java
@@ -159,11 +159,12 @@
mSelectedItemIndex = subItem.getId();
if (mSelectedItemIndex == INDEX_PSIM) {
Log.i(TAG, "Ready to switch to pSIM slot.");
- mSwitchToRemovableSlotSidecar.run(UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID);
+ mSwitchToRemovableSlotSidecar.run(UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID, null);
} else {
Log.i(TAG, "Ready to switch to eSIM subscription with index: " + mSelectedItemIndex);
mSwitchToEuiccSubscriptionSidecar.run(
- mEmbeddedSubscriptions.get(mSelectedItemIndex).getSubscriptionId());
+ mEmbeddedSubscriptions.get(mSelectedItemIndex).getSubscriptionId(),
+ UiccSlotUtil.INVALID_PORT_ID, null);
}
}
diff --git a/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java b/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
index be2fa2d..db6e1b4 100644
--- a/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
+++ b/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
@@ -23,6 +23,7 @@
import com.android.settings.R;
import com.android.settings.SidecarFragment;
import com.android.settings.network.SwitchToEuiccSubscriptionSidecar;
+import com.android.settings.network.UiccSlotUtil;
import com.android.settings.network.telephony.AlertDialogFragment;
import com.android.settings.network.telephony.ConfirmDialogFragment;
import com.android.settings.network.telephony.SubscriptionActionDialogActivity;
@@ -110,7 +111,8 @@
return;
}
Log.i(TAG, "User confirmed to switch to embedded slot.");
- mSwitchToEuiccSubscriptionSidecar.run(mSubToEnabled.getSubscriptionId());
+ mSwitchToEuiccSubscriptionSidecar.run(mSubToEnabled.getSubscriptionId(),
+ UiccSlotUtil.INVALID_PORT_ID, null);
showProgressDialog(
getString(
R.string.sim_action_switch_sub_dialog_progress,
diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
index e0bc9cd..8c8964f 100644
--- a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
+++ b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
@@ -210,10 +210,11 @@
}
List<SubscriptionInfo> groupedEmbeddedSubscriptions = getGroupedEmbeddedSubscriptions();
-
if (groupedEmbeddedSubscriptions.size() == 0 || !removableSlotInfo.getPorts().stream()
.findFirst().get().isActive()) {
- Log.i(TAG, "eSIM slot is active or no subscriptions exist. Do nothing.");
+ Log.i(TAG, "eSIM slot is active or no subscriptions exist. Do nothing."
+ + " The removableSlotInfo: " + removableSlotInfo
+ + ", groupedEmbeddedSubscriptions: " + groupedEmbeddedSubscriptions);
return;
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
index cf0ce96..6efdcf7a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
@@ -22,26 +22,41 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
+import android.content.DialogInterface;
import androidx.appcompat.app.AlertDialog;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
/** Tests for {@link AccessibilityGestureNavigationTutorial}. */
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityGestureNavigationTutorialTest {
- private Context mContext;
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock
+ private DialogInterface.OnClickListener mMockOnClickListener;
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
private int mShortcutTypes;
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
+ mContext.setTheme(R.style.Theme_AppCompat);
mShortcutTypes = /* initial */ 0;
}
@@ -86,4 +101,28 @@
mShortcutTypes)).hasSize(/* expectedSize= */ 2);
assertThat(alertDialog).isNotNull();
}
+
+ @Test
+ public void performClickOnNegativeButton_turnOnSoftwareShortcut_dismiss() {
+ mShortcutTypes |= UserShortcutType.SOFTWARE;
+ final AlertDialog alertDialog =
+ createAccessibilityTutorialDialog(mContext, mShortcutTypes);
+ alertDialog.show();
+
+ alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
+
+ assertThat(alertDialog.isShowing()).isFalse();
+ }
+
+ @Test
+ public void performClickOnNegativeButton_turnOnSoftwareShortcut_callOnClickListener() {
+ mShortcutTypes |= UserShortcutType.SOFTWARE;
+ final AlertDialog alertDialog =
+ createAccessibilityTutorialDialog(mContext, mShortcutTypes, mMockOnClickListener);
+ alertDialog.show();
+
+ alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
+
+ verify(mMockOnClickListener).onClick(alertDialog, DialogInterface.BUTTON_NEGATIVE);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java
new file mode 100644
index 0000000..0c656b3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.service.quicksettings.TileService;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPackageManager;
+
+import java.util.Arrays;
+
+/** Tests for {@link LaunchAccessibilityActivityPreferenceFragment} */
+@RunWith(RobolectricTestRunner.class)
+public class LaunchAccessibilityActivityPreferenceFragmentTest {
+
+ private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
+ private static final String PLACEHOLDER_TILE_CLASS_NAME =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
+ private static final String PLACEHOLDER_TILE_CLASS_NAME2 =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder2";
+ private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
+ PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
+ private static final String PLACEHOLDER_TILE_NAME =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
+ private static final String PLACEHOLDER_TILE_NAME2 =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder2";
+
+ private TestLaunchAccessibilityActivityPreferenceFragment mFragment;
+ private PreferenceScreen mScreen;
+ private Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceManager mPreferenceManager;
+
+ @Before
+ public void setUpTestFragment() {
+ MockitoAnnotations.initMocks(this);
+
+ mFragment = spy(new TestLaunchAccessibilityActivityPreferenceFragment());
+ when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
+ when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
+ when(mFragment.getContext()).thenReturn(mContext);
+ mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null));
+ when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
+ doReturn(mScreen).when(mFragment).getPreferenceScreen();
+ }
+
+ @Test
+ public void getTileName_noTileServiceAssigned_noMatchString() {
+ final CharSequence tileName = mFragment.getTileName();
+ assertThat(tileName.toString()).isEqualTo("");
+ }
+
+ @Test
+ public void getTileName_hasOneTileService_haveMatchString() {
+ final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE);
+ final ResolveInfo info = new ResolveInfo();
+ info.serviceInfo = new FakeServiceInfo();
+ info.serviceInfo.packageName = PLACEHOLDER_PACKAGE_NAME;
+ info.serviceInfo.name = PLACEHOLDER_TILE_CLASS_NAME;
+ final ShadowPackageManager shadowPackageManager =
+ Shadows.shadowOf(mContext.getPackageManager());
+ shadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info));
+
+ final CharSequence tileName = mFragment.getTileName();
+ assertThat(tileName.toString()).isEqualTo(PLACEHOLDER_TILE_NAME);
+ }
+
+ @Test
+ public void getTileName_hasTwoTileServices_haveMatchString() {
+ final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE);
+ final ResolveInfo info = new ResolveInfo();
+ info.serviceInfo = new FakeServiceInfo();
+ info.serviceInfo.packageName = PLACEHOLDER_PACKAGE_NAME;
+ info.serviceInfo.name = PLACEHOLDER_TILE_CLASS_NAME;
+ final ResolveInfo info2 = new ResolveInfo();
+ info2.serviceInfo = new FakeServiceInfo2();
+ info2.serviceInfo.packageName = PLACEHOLDER_PACKAGE_NAME;
+ info2.serviceInfo.name = PLACEHOLDER_TILE_CLASS_NAME2;
+ final ShadowPackageManager shadowPackageManager =
+ Shadows.shadowOf(mContext.getPackageManager());
+ shadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info, info2));
+
+ final CharSequence tileName = mFragment.getTileName();
+ assertThat(tileName.toString()).isEqualTo(PLACEHOLDER_TILE_NAME);
+ }
+
+ private static class FakeServiceInfo extends ServiceInfo {
+ public String loadLabel(PackageManager mgr) {
+ return PLACEHOLDER_TILE_NAME;
+ }
+ }
+
+ private static class FakeServiceInfo2 extends ServiceInfo {
+ public String loadLabel(PackageManager mgr) {
+ return PLACEHOLDER_TILE_NAME2;
+ }
+ }
+
+ private static class TestLaunchAccessibilityActivityPreferenceFragment
+ extends LaunchAccessibilityActivityPreferenceFragment {
+
+ @Override
+ protected ComponentName getTileComponentName() {
+ return PLACEHOLDER_TILE_COMPONENT_NAME;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
new file mode 100644
index 0000000..db5b83c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.service.quicksettings.TileService;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPackageManager;
+
+import java.util.Arrays;
+
+/** Tests for {@link ToggleAccessibilityServicePreferenceFragment} */
+@RunWith(RobolectricTestRunner.class)
+public class ToggleAccessibilityServicePreferenceFragmentTest {
+
+ private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
+ private static final String PLACEHOLDER_TILE_CLASS_NAME =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
+ private static final String PLACEHOLDER_TILE_CLASS_NAME2 =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder2";
+ private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
+ PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
+ private static final String PLACEHOLDER_TILE_NAME =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
+ private static final String PLACEHOLDER_TILE_NAME2 =
+ PLACEHOLDER_PACKAGE_NAME + "tile.placeholder2";
+
+ private TestToggleAccessibilityServicePreferenceFragment mFragment;
+ private PreferenceScreen mScreen;
+ private Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceManager mPreferenceManager;
+
+ @Before
+ public void setUpTestFragment() {
+ MockitoAnnotations.initMocks(this);
+
+ mFragment = spy(new TestToggleAccessibilityServicePreferenceFragment());
+ when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
+ when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
+ when(mFragment.getContext()).thenReturn(mContext);
+ mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null));
+ when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
+ doReturn(mScreen).when(mFragment).getPreferenceScreen();
+ }
+
+ @Test
+ public void getTileName_noTileServiceAssigned_noMatchString() {
+ final CharSequence tileName = mFragment.getTileName();
+ assertThat(tileName.toString()).isEqualTo("");
+ }
+
+ @Test
+ public void getTileName_hasOneTileService_haveMatchString() {
+ final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE);
+ final ResolveInfo info = new ResolveInfo();
+ info.serviceInfo = new FakeServiceInfo();
+ info.serviceInfo.packageName = PLACEHOLDER_PACKAGE_NAME;
+ info.serviceInfo.name = PLACEHOLDER_TILE_CLASS_NAME;
+ final ShadowPackageManager shadowPackageManager =
+ Shadows.shadowOf(mContext.getPackageManager());
+ shadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info));
+
+ final CharSequence tileName = mFragment.getTileName();
+ assertThat(tileName.toString()).isEqualTo(PLACEHOLDER_TILE_NAME);
+ }
+
+ @Test
+ public void getTileName_hasTwoTileServices_haveMatchString() {
+ final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE);
+ final ResolveInfo info = new ResolveInfo();
+ info.serviceInfo = new FakeServiceInfo();
+ info.serviceInfo.packageName = PLACEHOLDER_PACKAGE_NAME;
+ info.serviceInfo.name = PLACEHOLDER_TILE_CLASS_NAME;
+ final ResolveInfo info2 = new ResolveInfo();
+ info2.serviceInfo = new FakeServiceInfo2();
+ info2.serviceInfo.packageName = PLACEHOLDER_PACKAGE_NAME;
+ info2.serviceInfo.name = PLACEHOLDER_TILE_CLASS_NAME2;
+ final ShadowPackageManager shadowPackageManager =
+ Shadows.shadowOf(mContext.getPackageManager());
+ shadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info, info2));
+
+ final CharSequence tileName = mFragment.getTileName();
+ assertThat(tileName.toString()).isEqualTo(PLACEHOLDER_TILE_NAME);
+ }
+
+ private static class FakeServiceInfo extends ServiceInfo {
+ public String loadLabel(PackageManager mgr) {
+ return PLACEHOLDER_TILE_NAME;
+ }
+ }
+
+ private static class FakeServiceInfo2 extends ServiceInfo {
+ public String loadLabel(PackageManager mgr) {
+ return PLACEHOLDER_TILE_NAME2;
+ }
+ }
+
+ private static class TestToggleAccessibilityServicePreferenceFragment
+ extends ToggleAccessibilityServicePreferenceFragment {
+
+ @Override
+ protected ComponentName getTileComponentName() {
+ return PLACEHOLDER_TILE_COMPONENT_NAME;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java
index e5fbd65..72477b9 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java
@@ -24,9 +24,10 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothManager;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+
import android.os.SystemProperties;
import androidx.preference.ListPreference;
@@ -46,17 +47,12 @@
@RunWith(RobolectricTestRunner.class)
public class BluetoothMaxConnectedAudioDevicesPreferenceControllerTest {
- private static final int TEST_MAX_CONNECTED_AUDIO_DEVICES = 3;
+ private static int TEST_MAX_CONNECTED_AUDIO_DEVICES = 5;
@Mock
private PreferenceScreen mPreferenceScreen;
@Spy
private Context mSpyContext = RuntimeEnvironment.application;
- @Spy
- private BluetoothManager mBluetoothManager =
- mSpyContext.getSystemService(BluetoothManager.class);
- @Spy
- private BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
private ListPreference mPreference;
private BluetoothMaxConnectedAudioDevicesPreferenceController mController;
@@ -67,16 +63,19 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- doReturn(mBluetoothManager).when(mSpyContext).getSystemService(BluetoothManager.class);
- doReturn(mBluetoothAdapter).when(mBluetoothManager).getAdapter();
// Get XML values without mock
// Setup test list preference using XML values
mPreference = new ListPreference(mSpyContext);
mPreference.setEntries(R.array.bluetooth_max_connected_audio_devices);
mPreference.setEntryValues(R.array.bluetooth_max_connected_audio_devices_values);
- // Stub default max connected audio devices to a test controlled value
- doReturn(TEST_MAX_CONNECTED_AUDIO_DEVICES).when(mBluetoothAdapter)
- .getMaxConnectedAudioDevices();
+ // Retrieve default max connected audio devices to a test controlled value
+ try {
+ Resources res = mSpyContext.getPackageManager().getResourcesForApplication("com.android.bluetooth");
+ TEST_MAX_CONNECTED_AUDIO_DEVICES = res.getInteger(res.getIdentifier("config_bluetooth_max_connected_audio_devices", "integer", "com.android.bluetooth"));
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+
// Init the actual controller
mController = new BluetoothMaxConnectedAudioDevicesPreferenceController(mSpyContext);
// Construct preference in the controller via a mocked preference screen object
diff --git a/tests/robotests/src/com/android/settings/enterprise/AbsBasePrivacySettingsPreference.java b/tests/robotests/src/com/android/settings/enterprise/AbsBasePrivacySettingsPreference.java
index 5cf2224..34b218a 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AbsBasePrivacySettingsPreference.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AbsBasePrivacySettingsPreference.java
@@ -84,18 +84,6 @@
protected void verifyFinancedPreferenceControllers(
List<AbstractPreferenceController> controllers) {
- assertThat(controllers).isNotNull();
- assertThat(controllers.size()).isEqualTo(6);
- int position = 0;
- assertThat(controllers.get(position++)).isInstanceOf(NetworkLogsPreferenceController.class);
- assertThat(controllers.get(position++)).isInstanceOf(BugReportsPreferenceController.class);
- assertThat(controllers.get(position++)).isInstanceOf(
- SecurityLogsPreferenceController.class);
- assertThat(controllers.get(position++)).isInstanceOf(
- EnterpriseInstalledPackagesPreferenceController.class);
- assertThat(controllers.get(position++)).isInstanceOf(
- PreferenceCategoryController.class);
- assertThat(controllers.get(position)).isInstanceOf(
- FailedPasswordWipeCurrentUserPreferenceController.class);
+ assertThat(controllers).isEmpty();
}
}
diff --git a/tests/robotests/src/com/android/settings/testutils/BedtimeSettingsUtils.java b/tests/robotests/src/com/android/settings/testutils/BedtimeSettingsUtils.java
index 59c501b..ac55334 100644
--- a/tests/robotests/src/com/android/settings/testutils/BedtimeSettingsUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BedtimeSettingsUtils.java
@@ -17,6 +17,7 @@
package com.android.settings.testutils;
import static android.provider.Settings.ACTION_BEDTIME_SETTINGS;
+import static android.util.FeatureFlagUtils.SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME;
import static org.robolectric.Shadows.shadowOf;
@@ -25,6 +26,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
+import android.util.FeatureFlagUtils;
/** A helper class for installing bedtime settings activity. */
public final class BedtimeSettingsUtils {
@@ -35,6 +37,8 @@
}
public void installBedtimeSettings(String wellbeingPackage, boolean enabled) {
+ FeatureFlagUtils.setEnabled(mContext, SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME,
+ true /* enabled */);
Intent bedtimeSettingsIntent = new Intent(ACTION_BEDTIME_SETTINGS)
.setPackage(wellbeingPackage);
ResolveInfo bedtimeResolveInfo = new ResolveInfo();
diff --git a/tests/unit/OWNERS b/tests/unit/OWNERS
index 4123742..8a7a27e 100644
--- a/tests/unit/OWNERS
+++ b/tests/unit/OWNERS
@@ -1,2 +1,2 @@
-# Additional reviewers for this and subdirectories.
-goldmanj@google.com
+# We do not guard tests - everyone is welcomed to contribute to tests.
+per-file *.java=*
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
index 1042a6a..ed4c127 100644
--- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
+++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
@@ -55,6 +55,7 @@
private LocaleList mSystemLocales;
private LocaleList mAppLocale;
private String[] mAssetLocales;
+ private LocaleList mPackageLocales;
@Before
@UiThreadTest
@@ -67,11 +68,13 @@
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(LocaleManager.class)).thenReturn(mLocaleManager);
- setupInitialLocales("en",
- "tw",
- "jp",
- "en, uk, jp, ne",
- new String[]{"en", "ne", "ms", "pa"});
+ setupInitialLocales(
+ /* appLocale= */ "en",
+ /* simCountry= */ "tw",
+ /* networkCountry= */ "jp",
+ /* systemLocales= */ "en, uk, jp, ne",
+ /* packageLocales= */ "pa, cn, tw, en",
+ /* assetLocales= */ new String[]{"en", "ne", "ms", "pa"});
}
@Test
@@ -105,11 +108,13 @@
@UiThreadTest
public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsSimCountryLocale() {
Locale simCountryLocale = new Locale("zh", "TW");
- setupInitialLocales("",
- "tw",
- "",
- "en, uk, jp, ne",
- new String[]{"en", "ne", "ms", "pa"});
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "tw",
+ /* networkCountry= */ "",
+ /* systemLocales= */ "en, uk, jp, ne",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{});
DummyAppLocaleDetailsHelper helper =
new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
@@ -124,11 +129,13 @@
@UiThreadTest
public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsNetworkCountryLocale() {
Locale networkCountryLocale = new Locale("en", "GB");
- setupInitialLocales("",
- "",
- "gb",
- "en, uk, jp, ne",
- new String[]{"en", "ne", "ms", "pa"});
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "",
+ /* networkCountry= */ "gb",
+ /* systemLocales= */ "en, uk, jp, ne",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{});
DummyAppLocaleDetailsHelper helper =
new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
@@ -142,11 +149,32 @@
@Test
@UiThreadTest
public void handleAllLocalesData_noAppAndSimNetworkLocale_1stLocaleIsFirstOneInSystemLocales() {
- setupInitialLocales("",
- "",
- "",
- "en, uk, jp, ne",
- new String[]{"en", "ne", "ms", "pa"});
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "",
+ /* networkCountry= */ "",
+ /* systemLocales= */ "en, uk, jp, ne",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{});
+ DummyAppLocaleDetailsHelper helper =
+ new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+
+ helper.handleAllLocalesData();
+
+ Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
+ assertTrue(locale.equals(mSystemLocales.get(0)));
+ }
+
+ @Test
+ @UiThreadTest
+ public void handleAllLocalesData_hasPackageAndSystemLocales_1stLocaleIs1stOneInSystemLocales() {
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "",
+ /* networkCountry= */ "",
+ /* systemLocales= */ "en, uk, jp, ne",
+ /* packageLocales= */ "pa, cn, tw, en",
+ /* assetLocales= */ new String[]{});
DummyAppLocaleDetailsHelper helper =
new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
@@ -204,6 +232,11 @@
*
* @param systemLocales System locales, a locale list by a multiple language tags with comma.
* example: "en, uk, jp"
+ *
+ * @param packageLocales PackageManager locales, a locale list by a multiple language tags with
+ * comma.
+ * example: "en, uk, jp"
+ *
* @param assetLocales Asset locales, a locale list by a multiple language tags with String
* array.
* example: new String[] {"en", "ne", "ms", "pa"}
@@ -212,10 +245,12 @@
String simCountry,
String networkCountry,
String systemLocales,
+ String packageLocales,
String[] assetLocales) {
mAppLocale = LocaleList.forLanguageTags(appLocale);
mSystemLocales = LocaleList.forLanguageTags(systemLocales);
mAssetLocales = assetLocales;
+ mPackageLocales = LocaleList.forLanguageTags(packageLocales);
when(mTelephonyManager.getSimCountryIso()).thenReturn(simCountry);
when(mTelephonyManager.getNetworkCountryIso()).thenReturn(networkCountry);
when(mLocaleManager.getApplicationLocales(anyString())).thenReturn(mAppLocale);
@@ -237,6 +272,10 @@
LocaleList getCurrentSystemLocales() {
return mSystemLocales;
}
- }
+ @Override
+ LocaleList getPackageLocales() {
+ return mPackageLocales;
+ }
+ }
}