Merge "Fix typo in product string" into udc-dev am: d3df7f5090
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/23600032
Change-Id: I6ba750177b5016d18408d33e7d95712e936050b8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6689645..2c3e7f3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -864,6 +864,7 @@
<activity
android:name="Settings$LongBackgroundTasksActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/long_background_tasks_label">
<intent-filter android:priority="1">
@@ -1545,6 +1546,7 @@
<activity
android:name="Settings$ManageApplicationsActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/applications_settings">
<intent-filter android:priority="1">
@@ -1607,6 +1609,7 @@
<activity
android:name="Settings$HighPowerApplicationsActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/high_power_apps">
<intent-filter android:priority="1">
@@ -1665,6 +1668,7 @@
This is for compatibility with old shortcuts. -->
<activity-alias android:name=".RunningServices"
android:label="@string/runningservices_settings_title"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:targetActivity="Settings$ManageApplicationsActivity">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
@@ -1677,6 +1681,7 @@
This is for compatibility with old shortcuts. -->
<activity-alias android:name=".applications.StorageUse"
android:label="@string/storageuse_settings_title"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:targetActivity="Settings$ManageApplicationsActivity">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
@@ -1743,6 +1748,7 @@
<!-- Provide direct entry into manage apps showing running services. -->
<activity android:name="Settings$RunningServicesActivity"
android:exported="true"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:label="@string/runningservices_settings_title">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -1761,6 +1767,7 @@
<!-- Provide direct entry into manage apps showing storage usage of apps. -->
<activity
android:name="Settings$StorageUseActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/storageuse_settings_title">
<intent-filter android:priority="1">
@@ -2105,6 +2112,7 @@
<activity
android:name="Settings$UsageAccessSettingsActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/usage_access_title">
<intent-filter android:priority="1">
@@ -3483,6 +3491,7 @@
<activity
android:name="Settings$TurnScreenOnSettingsActivity"
android:exported="true"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:label="@string/turn_screen_on_title">
<intent-filter android:priority="1">
<action android:name="android.settings.TURN_SCREEN_ON_SETTINGS" />
@@ -3662,6 +3671,7 @@
<activity android:name="Settings$NotificationAppListActivity"
android:label="@string/app_notifications_title"
android:icon="@drawable/ic_notifications"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true">
<intent-filter android:priority="1">
<action android:name="android.settings.ALL_APPS_NOTIFICATION_SETTINGS" />
@@ -3676,6 +3686,7 @@
<!-- Displays a list of apps available for cloning on the device -->
<activity android:name=".Settings$ClonedAppsListActivity"
android:label="@string/cloned_apps_dashboard_title"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true">
<intent-filter android:priority="1">
<action android:name="android.settings.MANAGE_CLONED_APPS_SETTINGS" />
@@ -3941,6 +3952,7 @@
<activity
android:name="Settings$OverlaySettingsActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/draw_overlay">
<intent-filter android:priority="1">
@@ -3978,6 +3990,7 @@
<activity
android:name="Settings$WriteSettingsActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/write_settings_title">
<intent-filter android:priority="1">
@@ -4011,6 +4024,7 @@
<activity
android:name="Settings$AlarmsAndRemindersActivity"
android:exported="true"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:label="@string/alarms_and_reminders_label">
<intent-filter android:priority="1">
<action android:name="android.settings.REQUEST_SCHEDULE_EXACT_ALARM" />
@@ -4041,6 +4055,7 @@
<activity
android:name="Settings$ManageExternalSourcesActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/install_other_apps">
<intent-filter android:priority="1">
@@ -4095,6 +4110,7 @@
<activity
android:name="Settings$ManageExternalStorageActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/manage_external_storage_title">
<intent-filter android:priority="1">
@@ -4126,6 +4142,7 @@
<activity
android:name="Settings$MediaManagementAppsActivity"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="true"
android:label="@string/media_management_apps_title">
<intent-filter android:priority="1">
@@ -4881,6 +4898,7 @@
<activity
android:name=".spa.SpaActivity"
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
+ android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
android:exported="false" />
<activity android:name=".spa.SpaBridgeActivity" android:exported="false"/>
<activity android:name=".spa.SpaAppBridgeActivity" android:exported="false"/>
diff --git a/res/layout/preference_external_action_icon.xml b/res/layout/preference_external_action_icon.xml
new file mode 100644
index 0000000..fcec430
--- /dev/null
+++ b/res/layout/preference_external_action_icon.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<ImageView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_chevron_right_24dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="8dp" />
\ No newline at end of file
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 8719626..25663e7 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -2945,8 +2945,7 @@
<string name="keywords_storage_settings" msgid="6018856193950281898">"memorija, keš memorija, podaci, izbrisati, obrisati, osloboditi, prostor"</string>
<string name="keywords_bluetooth_settings" msgid="2588159530959868188">"povezan, uređaj, slušalice, slušalice s mikrofonom, zvučnik, bežično, uparivanje, slušalice za umetanje u uho, muzika, medij"</string>
<string name="keywords_wallpaper" msgid="7332890404629446192">"pozadina, tema, mreža, prilagođavanje, personaliziranje"</string>
- <!-- no translation found for keywords_styles (3367789885254807447) -->
- <skip />
+ <string name="keywords_styles" msgid="3367789885254807447">"ikona, boja isticanja, početni zaslon, zaključan zaslon, prečac, veličina sata"</string>
<string name="keywords_assist_input" msgid="3086289530227075593">"zadani, asistent"</string>
<string name="keywords_default_payment_app" msgid="5162298193637362104">"plaćanje, zadano"</string>
<string name="keywords_ambient_display" msgid="3149287105145443697">"dolazno obavještenje"</string>
@@ -3226,8 +3225,7 @@
<string name="notification_channel_summary_min" msgid="8823399508450176842">"Suzite obavještenja u jedan red na padajućoj traci"</string>
<string name="notification_channel_summary_low" msgid="5549662596677692000">"Bez zvuka ili vibracije"</string>
<string name="notification_conversation_summary_low" msgid="6352818857388412326">"Bez zvuka ili vibracije i pojavljuje se pri dnu odjeljka razgovora"</string>
- <!-- no translation found for notification_channel_summary_default (1168420867670390611) -->
- <skip />
+ <string name="notification_channel_summary_default" msgid="1168420867670390611">"Možda će zvoniti ili vibrirati, ovisno o postavkama uređaja"</string>
<string name="notification_channel_summary_high" msgid="3411637309360617621">"Kada je uređaj otključan, vidite obavještenja u vidu banera na vrhu ekrana"</string>
<string name="notification_switch_label" msgid="8029371325967501557">"Sva obavještenja aplikacije \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="notification_app_switch_label" msgid="4422902423925084193">"Sva obavještenja aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 334d4e5..0c5c7a0 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -364,7 +364,7 @@
<bool name="config_show_wifi_hotspot_settings">true</bool>
<!-- Whether Wi-Fi hotspot speed should be shown or not. -->
- <bool name="config_show_wifi_hotspot_speed">false</bool>
+ <bool name="config_show_wifi_hotspot_speed">true</bool>
<!-- Whether toggle_airplane is available or not. -->
<bool name="config_show_toggle_airplane">true</bool>
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index 979faa2..54775f8 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -208,6 +208,10 @@
mRemoveButton = findPreference(FaceSettingsRemoveButtonPreferenceController.KEY);
mEnrollButton = findPreference(FaceSettingsEnrollButtonPreferenceController.KEY);
+ final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId);
+ mEnrollButton.setVisible(!hasEnrolled);
+ mRemoveButton.setVisible(hasEnrolled);
+
// There is no better way to do this :/
for (AbstractPreferenceController controller : mControllers) {
if (controller instanceof FaceSettingsPreferenceController) {
@@ -233,8 +237,6 @@
public void onStart() {
super.onStart();
final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId);
- mEnrollButton.setVisible(!hasEnrolled);
- mRemoveButton.setVisible(hasEnrolled);
// When the user has face id registered but failed enrolling in device lock state,
// lead users directly to the confirm deletion dialog in Face Unlock settings.
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 7e76405..f653942 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -265,6 +265,12 @@
updateUdfpsEnrollView(udfpsEnrollView, props.get(0));
switch (rotation) {
case Surface.ROTATION_90:
+ final View sudContent = layout.findViewById(R.id.sud_layout_content);
+ if (sudContent != null) {
+ sudContent.setPadding(sudContent.getPaddingLeft(), 0,
+ sudContent.getPaddingRight(), sudContent.getPaddingBottom());
+ }
+
final LinearLayout layoutContainer = layout.findViewById(
R.id.layout_container);
final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 724947c..701967b 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -96,12 +96,6 @@
protected void init(PreferenceScreen screen) {
mProfilesContainer = (PreferenceCategory)screen.findPreference(getPreferenceKey());
mProfilesContainer.setLayoutResource(R.layout.preference_bluetooth_profile_category);
- mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
- SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true);
- mIsLeAudioToggleEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
- SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, false)
- || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
- CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false);
// Call refresh here even though it will get called later in onResume, to avoid the
// list of switches appearing to "pop" into the page.
refresh();
@@ -151,8 +145,8 @@
profilePref.setEnabled(!mCachedDevice.isBusy());
}
- if (profile instanceof LeAudioProfile && !mIsLeAudioToggleEnabled) {
- profilePref.setVisible(false);
+ if (profile instanceof LeAudioProfile) {
+ profilePref.setVisible(mIsLeAudioToggleEnabled);
}
if (profile instanceof MapProfile) {
@@ -437,6 +431,7 @@
@Override
public void onResume() {
+ updateLeAudioConfig();
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
item.registerCallback(this);
}
@@ -444,6 +439,20 @@
refresh();
}
+ private void updateLeAudioConfig() {
+ mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
+ SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true);
+ boolean isLeDeviceDetailEnabled = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_SETTINGS_UI,
+ SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, true);
+ boolean isLeEnabledByDefault = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
+ CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false);
+ mIsLeAudioToggleEnabled = isLeDeviceDetailEnabled || isLeEnabledByDefault;
+ Log.d(TAG, "BT_LE_AUDIO_CONTACT_SHARING_ENABLED:" + mIsLeContactSharingEnabled
+ + ", BT_LE_AUDIO_DEVICE_DETAIL_ENABLED:" + isLeDeviceDetailEnabled
+ + ", CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT:" + isLeEnabledByDefault);
+ }
+
@Override
public void onDeviceAttributesChanged() {
for (CachedBluetoothDevice item : mAllOfCachedDevices) {
diff --git a/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java b/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java
index 1da8672..60d63c6 100644
--- a/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java
+++ b/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
@@ -63,6 +64,13 @@
@Override
public Dialog onCreateDialog(Bundle inState) {
+ Context context = getContext();
+ mDevice = getDevice(context);
+ if (mDevice == null) {
+ Log.e(TAG, "onCreateDialog: Device is null.");
+ return null;
+ }
+
DialogInterface.OnClickListener onConfirm = (dialog, which) -> {
mDevice.unpair();
Activity activity = getActivity();
@@ -70,9 +78,6 @@
activity.finish();
}
};
- Context context = getContext();
- mDevice = getDevice(context);
-
AlertDialog dialog = new AlertDialog.Builder(context)
.setPositiveButton(R.string.bluetooth_unpair_dialog_forget_confirm_button,
onConfirm)
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index 4dc8f1a..578493a 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -33,6 +33,7 @@
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE_URI;
+import android.app.PendingIntent;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
@@ -75,6 +76,8 @@
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.AdaptiveIcon;
+import com.google.common.collect.Iterables;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -152,7 +155,14 @@
}
bindIcon(pref, tile, forceRoundedIcon);
- if (tile instanceof ActivityTile) {
+ if (tile.hasPendingIntent()) {
+ // Pending intent cannot be launched within the settings app panel, and will thus always
+ // be executed directly.
+ pref.setOnPreferenceClickListener(preference -> {
+ launchPendingIntentOrSelectProfile(activity, tile, fragment.getMetricsCategory());
+ return true;
+ });
+ } else if (tile instanceof ActivityTile) {
final int sourceMetricsCategory = fragment.getMetricsCategory();
final Bundle metadata = tile.getMetaData();
String clsName = null;
@@ -441,6 +451,33 @@
preference.setIcon(iconDrawable);
}
+ private void launchPendingIntentOrSelectProfile(FragmentActivity activity, Tile tile,
+ int sourceMetricCategory) {
+ ProfileSelectDialog.updatePendingIntentsIfNeeded(mContext, tile);
+
+ if (tile.pendingIntentMap.isEmpty()) {
+ Log.w(TAG, "Cannot resolve pendingIntent, skipping. " + tile.getIntent());
+ return;
+ }
+
+ mMetricsFeatureProvider.logSettingsTileClick(tile.getKey(mContext), sourceMetricCategory);
+
+ // Launch the pending intent directly if there's only one available.
+ if (tile.pendingIntentMap.size() == 1) {
+ PendingIntent pendingIntent = Iterables.getOnlyElement(tile.pendingIntentMap.values());
+ try {
+ pendingIntent.send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "Failed executing pendingIntent. " + pendingIntent.getIntent(), e);
+ }
+ return;
+ }
+
+ ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile,
+ sourceMetricCategory, /* onShowListener= */ null,
+ /* onDismissListener= */ null, /* onCancelListener= */ null);
+ }
+
private void launchIntentOrSelectProfile(FragmentActivity activity, Tile tile, Intent intent,
int sourceMetricCategory, TopLevelHighlightMixin highlightMixin,
boolean isDuplicateClick) {
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index 6076a25..f8a5d76 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -31,6 +31,7 @@
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleObserver;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@@ -47,7 +48,6 @@
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.drawer.DashboardCategory;
-import com.android.settingslib.drawer.ProviderTile;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.search.Indexable;
@@ -55,6 +55,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -504,6 +505,10 @@
// Install dashboard tiles and collect pending observers.
final boolean forceRoundedIcons = shouldForceRoundedIcon();
final List<DynamicDataObserver> pendingObservers = new ArrayList<>();
+
+ // Move group tiles to the beginning of the list to ensure they are created before the
+ // other tiles.
+ tiles.sort(Comparator.comparingInt(tile -> tile.getType() == Tile.Type.GROUP ? 0 : 1));
for (Tile tile : tiles) {
final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
if (TextUtils.isEmpty(key)) {
@@ -526,7 +531,14 @@
observers = mDashboardFeatureProvider.bindPreferenceToTileAndGetObservers(
getActivity(), this, forceRoundedIcons, pref, tile, key,
mPlaceholderPreferenceController.getOrder());
- screen.addPreference(pref);
+ if (tile.hasGroupKey() && mDashboardTilePrefKeys.containsKey(tile.getGroupKey())) {
+ final Preference group = screen.findPreference(tile.getGroupKey());
+ if (group instanceof PreferenceCategory) {
+ ((PreferenceCategory) group).addPreference(pref);
+ }
+ } else {
+ screen.addPreference(pref);
+ }
registerDynamicDataObservers(observers);
mDashboardTilePrefKeys.put(key, observers);
}
@@ -569,11 +581,28 @@
}
protected Preference createPreference(Tile tile) {
- return tile instanceof ProviderTile
- ? new SwitchPreference(getPrefContext())
- : tile.hasSwitch()
- ? new PrimarySwitchPreference(getPrefContext())
- : new Preference(getPrefContext());
+ switch (tile.getType()) {
+ case EXTERNAL_ACTION:
+ Preference externalActionPreference = new Preference(getPrefContext());
+ externalActionPreference
+ .setWidgetLayoutResource(R.layout.preference_external_action_icon);
+ return externalActionPreference;
+ case SWITCH:
+ return new SwitchPreference(getPrefContext());
+ case SWITCH_WITH_ACTION:
+ return new PrimarySwitchPreference(getPrefContext());
+ case GROUP:
+ mMetricsFeatureProvider.action(
+ mMetricsFeatureProvider.getAttribution(getActivity()),
+ SettingsEnums.ACTION_SETTINGS_GROUP_TILE_ADDED_TO_SCREEN,
+ getMetricsCategory(),
+ tile.getKey(getContext()),
+ /* value= */ 0);
+ return new PreferenceCategory((getPrefContext()));
+ case ACTION:
+ default:
+ return new Preference(getPrefContext());
+ }
}
@VisibleForTesting
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
index ef6ad83..58a51cb 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
@@ -17,6 +17,7 @@
package com.android.settings.dashboard.profileselector;
import android.app.Dialog;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
@@ -127,13 +128,25 @@
@Override
public void onClick(int position) {
final UserHandle user = mSelectedTile.userHandle.get(position);
- // Show menu on top level items.
- final Intent intent = new Intent(mSelectedTile.getIntent());
- FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
- .logStartedIntentWithProfile(intent, mSourceMetricCategory,
- position == 1 /* isWorkProfile */);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- getActivity().startActivityAsUser(intent, user);
+ if (!mSelectedTile.hasPendingIntent()) {
+ final Intent intent = new Intent(mSelectedTile.getIntent());
+ FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
+ .logStartedIntentWithProfile(intent, mSourceMetricCategory,
+ position == 1 /* isWorkProfile */);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ getActivity().startActivityAsUser(intent, user);
+ } else {
+ PendingIntent pendingIntent = mSelectedTile.pendingIntentMap.get(user);
+ FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
+ .logSettingsTileClickWithProfile(mSelectedTile.getKey(getContext()),
+ mSourceMetricCategory,
+ position == 1 /* isWorkProfile */);
+ try {
+ pendingIntent.send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "Failed executing pendingIntent. " + pendingIntent.getIntent(), e);
+ }
+ }
dismiss();
}
@@ -178,4 +191,36 @@
}
}
}
+
+ /**
+ * Checks the userHandle and pendingIntentMap in the provided tile, and remove the invalid
+ * entries if any.
+ */
+ public static void updatePendingIntentsIfNeeded(Context context, Tile tile) {
+ if (tile.userHandle == null || tile.userHandle.size() <= 1
+ || tile.pendingIntentMap.size() <= 1) {
+ return;
+ }
+ for (UserHandle userHandle : List.copyOf(tile.userHandle)) {
+ if (!tile.pendingIntentMap.containsKey(userHandle)) {
+ if (DEBUG) {
+ Log.d(TAG, "Delete the user without pending intent: "
+ + userHandle.getIdentifier());
+ }
+ tile.userHandle.remove(userHandle);
+ }
+ }
+
+ final UserManager userManager = UserManager.get(context);
+ for (UserHandle userHandle : List.copyOf(tile.pendingIntentMap.keySet())) {
+ UserInfo userInfo = userManager.getUserInfo(userHandle.getIdentifier());
+ if (userInfo == null || userInfo.isCloneProfile()) {
+ if (DEBUG) {
+ Log.d(TAG, "Delete the user: " + userHandle.getIdentifier());
+ }
+ tile.userHandle.remove(userHandle);
+ tile.pendingIntentMap.remove(userHandle);
+ }
+ }
+ }
}
diff --git a/src/com/android/settings/development/BluetoothLeAudioDeviceDetailsPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioDeviceDetailsPreferenceController.java
index a54c594..298ced0 100644
--- a/src/com/android/settings/development/BluetoothLeAudioDeviceDetailsPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothLeAudioDeviceDetailsPreferenceController.java
@@ -40,6 +40,7 @@
private static final String PREFERENCE_KEY = "bluetooth_show_leaudio_device_details";
private static final String CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT = "le_audio_enabled_by_default";
+ private static final boolean LE_AUDIO_DEVICE_DETAIL_DEFAULT_VALUE = true;
static int sLeAudioSupportedStateCache = BluetoothStatusCodes.ERROR_UNKNOWN;
@VisibleForTesting
@@ -75,7 +76,7 @@
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_SETTINGS_UI,
SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED,
- isEnabled ? "true" : "false", false);
+ isEnabled ? "true" : "false", LE_AUDIO_DEVICE_DETAIL_DEFAULT_VALUE);
return true;
}
@@ -87,7 +88,8 @@
final boolean leAudioDeviceDetailEnabled = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SETTINGS_UI,
- SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, false);
+ SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED,
+ LE_AUDIO_DEVICE_DETAIL_DEFAULT_VALUE);
final boolean leAudioEnabledByDefault = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_BLUETOOTH, CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false);
@@ -102,6 +104,7 @@
// Reset the toggle to null when the developer option is disabled
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_SETTINGS_UI,
- SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, "null", false);
+ SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, "null",
+ LE_AUDIO_DEVICE_DETAIL_DEFAULT_VALUE);
}
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryEntry.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryEntry.java
index b3e190f..7f86b7c 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryEntry.java
@@ -172,7 +172,6 @@
mName = mDefaultPackageName;
}
}
- getQuickNameIconForUid(uid, packages, loadDataInBackground);
mTimeInForegroundMs =
uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND);
mTimeInBackgroundMs =
diff --git a/src/com/android/settings/wifi/repository/WifiHotspotRepository.java b/src/com/android/settings/wifi/repository/WifiHotspotRepository.java
index 6764214..af8eb47 100644
--- a/src/com/android/settings/wifi/repository/WifiHotspotRepository.java
+++ b/src/com/android/settings/wifi/repository/WifiHotspotRepository.java
@@ -623,9 +623,11 @@
@VisibleForTesting
class SoftApCallback implements WifiManager.SoftApCallback {
+ private static final String TAG = "SoftApCallback";
+
@Override
public void onStateChanged(int state, int failureReason) {
- log("onStateChanged(), state:" + state + ", failureReason:" + failureReason);
+ Log.d(TAG, "onStateChanged(), state:" + state + ", failureReason:" + failureReason);
mWifiApState = state;
if (!mIsRestarting) {
return;
diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java b/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java
index f5066bd..a5e12d8 100644
--- a/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java
@@ -108,15 +108,17 @@
if (radioButton == null) {
continue;
}
- if (radioButton.isChecked() != speedInfo.mIsChecked) {
- radioButton.setChecked(speedInfo.mIsChecked);
+ if (!speedInfo.mIsVisible) {
+ radioButton.setVisible(false);
+ continue;
}
- if (radioButton.isEnabled() != speedInfo.mIsEnabled) {
- radioButton.setEnabled(speedInfo.mIsEnabled);
+ radioButton.setEnabled(speedInfo.mIsEnabled);
+ radioButton.setChecked(speedInfo.mIsChecked);
+ if (speedInfo.mSummary != null) {
+ radioButton.setSummary(speedInfo.mSummary);
}
- if (radioButton.isVisible() != speedInfo.mIsVisible) {
- radioButton.setVisible(speedInfo.mIsVisible);
- }
+ // setVisible at the end to avoid UI flickering
+ radioButton.setVisible(true);
}
}
diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java b/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java
index f04669a..e7eb3a6 100644
--- a/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java
+++ b/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java
@@ -22,12 +22,15 @@
import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ;
import android.app.Application;
+import android.util.Log;
+import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
+import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.repository.WifiHotspotRepository;
@@ -41,6 +44,12 @@
*/
public class WifiHotspotSpeedViewModel extends AndroidViewModel {
private static final String TAG = "WifiHotspotSpeedViewModel";
+ @VisibleForTesting
+ static final int RES_SPEED_5G_SUMMARY = R.string.wifi_hotspot_speed_5g_summary;
+ @VisibleForTesting
+ static final int RES_SPEED_6G_SUMMARY = R.string.wifi_hotspot_speed_6g_summary;
+ @VisibleForTesting
+ static final int RES_SUMMARY_UNAVAILABLE = R.string.wifi_hotspot_speed_summary_unavailable;
protected final WifiHotspotRepository mWifiHotspotRepository;
protected Map<Integer, SpeedInfo> mSpeedInfoMap = new HashMap<>();
@@ -75,14 +84,18 @@
}
protected void on6gAvailableChanged(Boolean available) {
- log("on6gAvailableChanged(), available:" + available);
+ Log.d(TAG, "on6gAvailableChanged(), available:" + available);
mSpeedInfo6g.mIsEnabled = available;
+ mSpeedInfo6g.mSummary = getApplication()
+ .getString(available ? RES_SPEED_6G_SUMMARY : RES_SUMMARY_UNAVAILABLE);
updateSpeedInfoMapData();
}
protected void on5gAvailableChanged(Boolean available) {
- log("on5gAvailableChanged(), available:" + available);
+ Log.d(TAG, "on5gAvailableChanged(), available:" + available);
mSpeedInfo5g.mIsEnabled = available;
+ mSpeedInfo5g.mSummary = getApplication()
+ .getString(available ? RES_SPEED_5G_SUMMARY : RES_SUMMARY_UNAVAILABLE);
boolean showDualBand = mWifiHotspotRepository.isDualBand() && available;
log("on5gAvailableChanged(), showDualBand:" + showDualBand);
@@ -144,6 +157,7 @@
Boolean mIsChecked;
boolean mIsEnabled;
boolean mIsVisible;
+ String mSummary;
public SpeedInfo(boolean isChecked, boolean isEnabled, boolean isVisible) {
this.mIsChecked = isChecked;
@@ -157,6 +171,7 @@
.append("isChecked:").append(mIsChecked)
.append(",isEnabled:").append(mIsEnabled)
.append(",isVisible:").append(mIsVisible)
+ .append(",mSummary:").append(mSummary)
.append('}').toString();
}
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 4ba6eae..f7a940f 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -43,6 +43,7 @@
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -57,6 +58,7 @@
import android.os.UserManager;
import android.util.Pair;
+import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
@@ -200,6 +202,27 @@
}
@Test
+ public void bindPreference_providerTileWithPendingIntent_shouldBindIntent() {
+ final Preference preference = new SwitchPreference(RuntimeEnvironment.application);
+ Bundle metaData = new Bundle();
+ metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label);
+ metaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary);
+ metaData.putInt(META_DATA_KEY_ORDER, 10);
+ metaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY);
+ final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, metaData);
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(RuntimeEnvironment.application, 0, new Intent("test"), 0);
+ tile.pendingIntentMap.put(UserHandle.CURRENT, pendingIntent);
+
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
+
+ assertThat(preference.getFragment()).isNull();
+ assertThat(preference.getOnPreferenceClickListener()).isNotNull();
+ assertThat(preference.getOrder()).isEqualTo(tile.getOrder());
+ }
+
+ @Test
public void bindPreference_noFragmentMetadata_shouldBindIntent() {
final Preference preference = new Preference(RuntimeEnvironment.application);
mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10);
@@ -631,6 +654,55 @@
}
@Test
+ public void clickPreference_providerTileWithPendingIntent_singleUser_executesPendingIntent() {
+ final Preference preference = new SwitchPreference(RuntimeEnvironment.application);
+ Bundle metaData = new Bundle();
+ metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label);
+ metaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary);
+ metaData.putInt(META_DATA_KEY_ORDER, 10);
+ metaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY);
+ final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, metaData);
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(RuntimeEnvironment.application, 0, new Intent("test"), 0);
+ tile.pendingIntentMap.put(UserHandle.CURRENT, pendingIntent);
+
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
+ preference.performClick();
+
+ Intent nextStartedActivity =
+ Shadows.shadowOf(RuntimeEnvironment.application).peekNextStartedActivity();
+ assertThat(nextStartedActivity).isNotNull();
+ assertThat(nextStartedActivity.getAction()).isEqualTo("test");
+ }
+
+ @Test
+ public void clickPreference_providerTileWithPendingIntent_multiUser_showsProfileDialog() {
+ final Preference preference = new SwitchPreference(RuntimeEnvironment.application);
+ Bundle metaData = new Bundle();
+ metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label);
+ metaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary);
+ metaData.putInt(META_DATA_KEY_ORDER, 10);
+ metaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY);
+ final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, metaData);
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(RuntimeEnvironment.application, 0, new Intent("test"), 0);
+ tile.pendingIntentMap.put(UserHandle.CURRENT, pendingIntent);
+ tile.pendingIntentMap.put(new UserHandle(10), pendingIntent);
+
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
+ preference.performClick();
+
+ Fragment dialogFragment =
+ mActivity.getSupportFragmentManager().findFragmentByTag("select_profile");
+ assertThat(dialogFragment).isNotNull();
+ Intent nextStartedActivity =
+ Shadows.shadowOf(RuntimeEnvironment.application).peekNextStartedActivity();
+ assertThat(nextStartedActivity).isNull();
+ }
+
+ @Test
public void openTileIntent_profileSelectionDialog_shouldShow() {
ShadowUserManager.getShadow().addUser(10, "Someone", 0);
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 0739294..ecaf36f 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -16,7 +16,9 @@
package com.android.settings.dashboard;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.DASHBOARD_CONTAINER;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_GROUP_KEY;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_PENDING_INTENT;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI;
import static com.google.common.truth.Truth.assertThat;
@@ -30,6 +32,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.PendingIntent;
import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
@@ -38,15 +41,18 @@
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Bundle;
+import android.os.UserHandle;
import android.preference.PreferenceManager.OnActivityResultListener;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.slices.BlockingSlicePrefController;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -57,6 +63,7 @@
import com.android.settingslib.drawer.ActivityTile;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.ProviderTile;
+import com.android.settingslib.drawer.Tile;
import org.junit.Before;
import org.junit.Ignore;
@@ -178,6 +185,43 @@
}
@Test
+ public void displayTilesAsPreference_withGroup_shouldAddTilesIntoGroup() {
+ final ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.packageName = "pkg";
+ providerInfo.name = "provider";
+ providerInfo.authority = "authority";
+ final Bundle groupTileMetaData = new Bundle();
+ groupTileMetaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_group_key");
+ ProviderTile groupTile = new ProviderTile(providerInfo, mDashboardCategory.key,
+ groupTileMetaData);
+ mDashboardCategory.addTile(groupTile);
+
+ final Bundle subTileMetaData = new Bundle();
+ subTileMetaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key3");
+ subTileMetaData.putString(META_DATA_PREFERENCE_GROUP_KEY, "injected_tile_group_key");
+ subTileMetaData.putParcelable(
+ META_DATA_PREFERENCE_PENDING_INTENT,
+ PendingIntent.getActivity(mContext, 0, new Intent(), 0));
+ ProviderTile subTile = new ProviderTile(providerInfo, mDashboardCategory.key,
+ subTileMetaData);
+ mDashboardCategory.addTile(subTile);
+
+ PreferenceCategory groupPreference = mock(PreferenceCategory.class);
+ when(mFakeFeatureFactory.dashboardFeatureProvider
+ .getTilesForCategory(nullable(String.class)))
+ .thenReturn(mDashboardCategory);
+ when(mFakeFeatureFactory.dashboardFeatureProvider
+ .getDashboardKeyForTile(any(Tile.class)))
+ .then(invocation -> ((Tile) invocation.getArgument(0)).getKey(mContext));
+ when(mTestFragment.mScreen.findPreference("injected_tile_group_key"))
+ .thenReturn(groupPreference);
+ mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
+
+ verify(mTestFragment.mScreen, times(3)).addPreference(nullable(Preference.class));
+ verify(groupPreference).addPreference(nullable(Preference.class));
+ }
+
+ @Test
public void displayTilesAsPreference_shouldNotAddTilesWithoutIntent() {
mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
@@ -352,6 +396,16 @@
}
@Test
+ public void createPreference_isActivityTile_returnPreference() {
+ final Preference pref = mTestFragment.createPreference(mActivityTile);
+
+ assertThat(pref).isInstanceOf(Preference.class);
+ assertThat(pref).isNotInstanceOf(PrimarySwitchPreference.class);
+ assertThat(pref).isNotInstanceOf(SwitchPreference.class);
+ assertThat(pref.getWidgetLayoutResource()).isEqualTo(0);
+ }
+
+ @Test
public void createPreference_isActivityTileAndHasSwitch_returnPrimarySwitchPreference() {
mActivityTile.getMetaData().putString(META_DATA_PREFERENCE_SWITCH_URI, "uri");
@@ -361,6 +415,64 @@
}
@Test
+ public void createPreference_isProviderTileWithPendingIntent_returnPreferenceWithIcon() {
+ final ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.packageName = "pkg";
+ providerInfo.name = "provider";
+ providerInfo.authority = "authority";
+ final Bundle metaData = new Bundle();
+ metaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key2");
+ ProviderTile providerTile = new ProviderTile(providerInfo, mDashboardCategory.key,
+ metaData);
+ providerTile.pendingIntentMap.put(
+ UserHandle.CURRENT, PendingIntent.getActivity(mContext, 0, new Intent(), 0));
+
+ final Preference pref = mTestFragment.createPreference(providerTile);
+
+ assertThat(pref).isInstanceOf(Preference.class);
+ assertThat(pref).isNotInstanceOf(PrimarySwitchPreference.class);
+ assertThat(pref).isNotInstanceOf(SwitchPreference.class);
+ assertThat(pref.getWidgetLayoutResource())
+ .isEqualTo(R.layout.preference_external_action_icon);
+ }
+
+ @Test
+ public void createPreference_isProviderTileWithPendingIntentAndSwitch_returnPrimarySwitch() {
+ mProviderTile.pendingIntentMap.put(
+ UserHandle.CURRENT, PendingIntent.getActivity(mContext, 0, new Intent(), 0));
+
+ final Preference pref = mTestFragment.createPreference(mProviderTile);
+
+ assertThat(pref).isInstanceOf(PrimarySwitchPreference.class);
+ }
+
+ @Test
+ public void createPreference_isGroupTile_returnPreferenceCategory_logTileAdded() {
+ final ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.packageName = "pkg";
+ providerInfo.name = "provider";
+ providerInfo.authority = "authority";
+ final Bundle metaData = new Bundle();
+ metaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key2");
+ ProviderTile providerTile =
+ new ProviderTile(providerInfo, mDashboardCategory.key, metaData);
+ MetricsFeatureProvider metricsFeatureProvider =
+ mFakeFeatureFactory.getMetricsFeatureProvider();
+ when(metricsFeatureProvider.getAttribution(any())).thenReturn(123);
+
+ final Preference pref = mTestFragment.createPreference(providerTile);
+
+ assertThat(pref).isInstanceOf(PreferenceCategory.class);
+ verify(metricsFeatureProvider)
+ .action(
+ 123,
+ SettingsEnums.ACTION_SETTINGS_GROUP_TILE_ADDED_TO_SCREEN,
+ mTestFragment.getMetricsCategory(),
+ "injected_tile_key2",
+ 0);
+ }
+
+ @Test
public void onActivityResult_test() {
final int requestCode = 10;
final int resultCode = 1;
diff --git a/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java b/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java
index 4e81cee..9a13961 100644
--- a/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java
@@ -24,7 +24,9 @@
import static org.mockito.Mockito.when;
import android.app.Dialog;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
@@ -119,6 +121,28 @@
}
@Test
+ public void updatePendingIntentsIfNeeded_removesUsersWithNoPendingIntentsAndCloneProfile() {
+ final UserInfo userInfo = new UserInfo(CLONE_USER.getIdentifier(), "clone_user", null,
+ UserInfo.FLAG_PROFILE, UserManager.USER_TYPE_PROFILE_CLONE);
+ when(mUserManager.getUserInfo(CLONE_USER.getIdentifier())).thenReturn(userInfo);
+ final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
+ tile.userHandle.add(CLONE_USER);
+ tile.userHandle.add(NORMAL_USER);
+ tile.userHandle.add(new UserHandle(10));
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ tile.pendingIntentMap.put(CLONE_USER, pendingIntent);
+ tile.pendingIntentMap.put(NORMAL_USER, pendingIntent);
+
+ ProfileSelectDialog.updatePendingIntentsIfNeeded(mContext, tile);
+
+ assertThat(tile.userHandle).hasSize(1);
+ assertThat(tile.userHandle).containsExactly(NORMAL_USER);
+ assertThat(tile.pendingIntentMap).hasSize(1);
+ assertThat(tile.pendingIntentMap).containsKey(NORMAL_USER);
+ verify(mUserManager, times(1)).getUserInfo(CLONE_USER.getIdentifier());
+ }
+
+ @Test
public void createDialog_showsCorrectTitle() {
mContext.setTheme(R.style.Theme_AppCompat);
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java
index 969f992..31f4c09 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java
@@ -25,8 +25,10 @@
import static com.android.settings.wifi.tether.WifiHotspotSpeedSettings.KEY_SPEED_5GHZ;
import static com.android.settings.wifi.tether.WifiHotspotSpeedSettings.KEY_SPEED_6GHZ;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -89,98 +91,156 @@
@Test
public void onSpeedInfoMapDataChanged_checkedSpeed2g_checkedToRadioButton2g() {
- mSpeedInfo2g = new WifiHotspotSpeedViewModel.SpeedInfo(false, true, false);
+ mSpeedInfo2g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, true);
updateSpeedInfoMap();
- mockRadioButton(true, false, true);
+ mockRadioButton(false, false, false);
mSettings.mSpeedPreferenceMap.put(SPEED_2GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(false, true, false);
+ verifyRadioButton(true, true, true);
}
@Test
public void onSpeedInfoMapDataChanged_uncheckedSpeed2g_uncheckedToRadioButton2g() {
- mSpeedInfo2g = new WifiHotspotSpeedViewModel.SpeedInfo(true, false, true);
+ mSpeedInfo2g = new WifiHotspotSpeedViewModel.SpeedInfo(false, false, true);
updateSpeedInfoMap();
- mockRadioButton(false, true, false);
+ mockRadioButton(true, true, true);
mSettings.mSpeedPreferenceMap.put(SPEED_2GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(true, false, true);
+ verifyRadioButton(false, false, true);
}
@Test
public void onSpeedInfoMapDataChanged_checkedSpeed5g_checkedToRadioButton5g() {
- mSpeedInfo5g = new WifiHotspotSpeedViewModel.SpeedInfo(false, true, false);
+ mSpeedInfo5g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, true);
updateSpeedInfoMap();
- mockRadioButton(true, false, true);
+ mockRadioButton(false, false, false);
mSettings.mSpeedPreferenceMap.put(SPEED_5GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(false, true, false);
+ verifyRadioButton(true, true, true);
}
@Test
public void onSpeedInfoMapDataChanged_uncheckedSpeed5g_uncheckedToRadioButton5g() {
- mSpeedInfo5g = new WifiHotspotSpeedViewModel.SpeedInfo(true, false, true);
+ mSpeedInfo5g = new WifiHotspotSpeedViewModel.SpeedInfo(false, false, true);
updateSpeedInfoMap();
- mockRadioButton(false, true, false);
+ mockRadioButton(true, true, true);
mSettings.mSpeedPreferenceMap.put(SPEED_5GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(true, false, true);
+ verifyRadioButton(false, false, true);
}
@Test
public void onSpeedInfoMapDataChanged_checkedSpeed2g5g_checkedToRadioButton2g5g() {
- mSpeedInfo2g5g = new WifiHotspotSpeedViewModel.SpeedInfo(false, true, false);
+ mSpeedInfo2g5g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, true);
updateSpeedInfoMap();
- mockRadioButton(true, false, true);
+ mockRadioButton(false, false, false);
mSettings.mSpeedPreferenceMap.put(SPEED_2GHZ_5GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(false, true, false);
+ verifyRadioButton(true, true, true);
}
@Test
- public void onSpeedInfoMapDataChanged_uncheckedSpeed25g_uncheckedToRadioButton25g() {
- mSpeedInfo2g5g = new WifiHotspotSpeedViewModel.SpeedInfo(true, false, true);
+ public void onSpeedInfoMapDataChanged_uncheckedSpeed2g5g_uncheckedToRadioButton2g5g() {
+ mSpeedInfo2g5g = new WifiHotspotSpeedViewModel.SpeedInfo(false, false, true);
updateSpeedInfoMap();
- mockRadioButton(false, true, false);
+ mockRadioButton(true, true, true);
mSettings.mSpeedPreferenceMap.put(SPEED_2GHZ_5GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(true, false, true);
+ verifyRadioButton(false, false, true);
}
@Test
public void onSpeedInfoMapDataChanged_checkedSpeed6g_checkedToRadioButton6g() {
- mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(false, true, false);
+ mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, true);
updateSpeedInfoMap();
+ mockRadioButton(false, false, false);
+ mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
+
+ mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
+
+ verifyRadioButton(true, true, true);
+ }
+
+ @Test
+ public void onSpeedInfoMapDataChanged_uncheckedSpeed6g_uncheckedToRadioButton6g() {
+ mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(false, false, true);
+ updateSpeedInfoMap();
+ mockRadioButton(true, true, true);
+ mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
+
+ mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
+
+ verifyRadioButton(false, false, true);
+ }
+
+ @Test
+ public void onSpeedInfoMapDataChanged_setVisibleFalse_setVisibleOnly() {
+ mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, false);
+ mSpeedInfo6g.mSummary = "summary";
+ mSpeedInfoMap.put(SPEED_6GHZ, mSpeedInfo6g);
+ mockRadioButton(true, true, true);
+ mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
+
+ mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
+
+ verify(mRadioButton).setVisible(false);
+ verify(mRadioButton, never()).setChecked(anyBoolean());
+ verify(mRadioButton, never()).setEnabled(anyBoolean());
+ verify(mRadioButton, never()).setSummary(anyString());
+ }
+
+ @Test
+ public void onSpeedInfoMapDataChanged_setVisibleTrue_setAllProperties() {
+ mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, true);
+ mSpeedInfo6g.mSummary = "summary";
+ mSpeedInfoMap.put(SPEED_6GHZ, mSpeedInfo6g);
+ mockRadioButton(true, true, true);
+ mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
+
+ mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
+
+ verify(mRadioButton).setVisible(true);
+ verify(mRadioButton).setChecked(anyBoolean());
+ verify(mRadioButton).setEnabled(anyBoolean());
+ verify(mRadioButton).setSummary(anyString());
+ }
+
+ @Test
+ public void onSpeedInfoMapDataChanged_summaryIsNull_doNotSetSummary() {
+ mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(true, true, true);
+ mSpeedInfo6g.mSummary = null;
+ mSpeedInfoMap.put(SPEED_6GHZ, mSpeedInfo6g);
+ mockRadioButton(true, true, true);
+ mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
+
+ mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
+
+ verify(mRadioButton, never()).setSummary(anyString());
+ }
+
+ @Test
+ public void onSpeedInfoMapDataChanged_summaryNotNull_setSummary() {
+ mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(true, false, true);
+ mSpeedInfo6g.mSummary = "summary";
+ mSpeedInfoMap.put(SPEED_6GHZ, mSpeedInfo6g);
mockRadioButton(true, false, true);
mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
- verifyRadioButton(false, true, false);
- }
-
- @Test
- public void onSpeedInfoMapDataChanged_uncheckedSpeed6g_uncheckedToRadioButton6g() {
- mSpeedInfo6g = new WifiHotspotSpeedViewModel.SpeedInfo(true, false, true);
- updateSpeedInfoMap();
- mockRadioButton(false, true, false);
- mSettings.mSpeedPreferenceMap.put(SPEED_6GHZ, mRadioButton);
-
- mSettings.onSpeedInfoMapDataChanged(mSpeedInfoMap);
-
- verifyRadioButton(true, false, true);
+ verify(mRadioButton).setSummary(mSpeedInfo6g.mSummary);
}
@Test
diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java
index 3a1a927..f52478e 100644
--- a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java
+++ b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java
@@ -20,6 +20,9 @@
import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ_5GHZ;
import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_5GHZ;
import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ;
+import static com.android.settings.wifi.tether.WifiHotspotSpeedViewModel.RES_SPEED_5G_SUMMARY;
+import static com.android.settings.wifi.tether.WifiHotspotSpeedViewModel.RES_SPEED_6G_SUMMARY;
+import static com.android.settings.wifi.tether.WifiHotspotSpeedViewModel.RES_SUMMARY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
@@ -128,7 +131,9 @@
mViewModel.on6gAvailableChanged(true);
verify(mSpeedInfoMapData).setValue(mViewModel.mSpeedInfoMap);
- assertThat(mViewModel.mSpeedInfoMap.get(SPEED_6GHZ).mIsEnabled).isTrue();
+ WifiHotspotSpeedViewModel.SpeedInfo speedInfo = mViewModel.mSpeedInfoMap.get(SPEED_6GHZ);
+ assertThat(speedInfo.mIsEnabled).isTrue();
+ assertThat(speedInfo.mSummary).isEqualTo(mContext.getString(RES_SPEED_6G_SUMMARY));
}
@Test
@@ -139,7 +144,9 @@
mViewModel.on6gAvailableChanged(false);
verify(mSpeedInfoMapData).setValue(mViewModel.mSpeedInfoMap);
- assertThat(mViewModel.mSpeedInfoMap.get(SPEED_6GHZ).mIsEnabled).isFalse();
+ WifiHotspotSpeedViewModel.SpeedInfo speedInfo = mViewModel.mSpeedInfoMap.get(SPEED_6GHZ);
+ assertThat(speedInfo.mIsEnabled).isFalse();
+ assertThat(speedInfo.mSummary).isEqualTo(mContext.getString(RES_SUMMARY_UNAVAILABLE));
}
@Test
@@ -150,7 +157,9 @@
mViewModel.on5gAvailableChanged(true);
verify(mSpeedInfoMapData).setValue(mViewModel.mSpeedInfoMap);
- assertThat(mViewModel.mSpeedInfoMap.get(SPEED_5GHZ).mIsEnabled).isTrue();
+ WifiHotspotSpeedViewModel.SpeedInfo speedInfo = mViewModel.mSpeedInfoMap.get(SPEED_5GHZ);
+ assertThat(speedInfo.mIsEnabled).isTrue();
+ assertThat(speedInfo.mSummary).isEqualTo(mContext.getString(RES_SPEED_5G_SUMMARY));
}
@Test
@@ -161,7 +170,9 @@
mViewModel.on5gAvailableChanged(false);
verify(mSpeedInfoMapData).setValue(mViewModel.mSpeedInfoMap);
- assertThat(mViewModel.mSpeedInfoMap.get(SPEED_5GHZ).mIsEnabled).isFalse();
+ WifiHotspotSpeedViewModel.SpeedInfo speedInfo = mViewModel.mSpeedInfoMap.get(SPEED_5GHZ);
+ assertThat(speedInfo.mIsEnabled).isFalse();
+ assertThat(speedInfo.mSummary).isEqualTo(mContext.getString(RES_SUMMARY_UNAVAILABLE));
}
@Test