Merge "Enable some settings pages to use paralleled-loading method" into rvc-dev
diff --git a/res/layout/network_request_dialog_title.xml b/res/layout/network_request_dialog_title.xml
index b61a7db..4385a88 100644
--- a/res/layout/network_request_dialog_title.xml
+++ b/res/layout/network_request_dialog_title.xml
@@ -18,28 +18,43 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="?android:attr/dialogPreferredPadding"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:background="?android:attr/selectableItemBackground"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
- <TextView
- android:id="@+id/network_request_title_text"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingLeft="24dp"
- android:paddingTop="18dp"
- android:layout_weight="1"
- android:textSize="18sp"
- android:gravity="center_vertical"
- style="@style/info_label"/>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingStart="24dp">
- <ProgressBar
- android:id="@+id/network_request_title_progress"
- style="?android:attr/progressBarStyleSmallTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginStart="16dip"
- android:minWidth="32dp"
- android:text="@string/progress_scanning"/>
+ <TextView
+ android:id="@+id/network_request_title_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingTop="18dp"
+ android:layout_weight="1"
+ android:textSize="20sp"
+ android:gravity="center_vertical"
+ style="@style/info_label"/>
+
+ <ProgressBar
+ android:id="@+id/network_request_title_progress"
+ style="?android:attr/progressBarStyleSmallTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="20dp"
+ android:gravity="center_vertical"
+ android:layout_marginStart="16dip"
+ android:minWidth="32dp"
+ android:text="@string/progress_scanning"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/network_request_summary_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="24dp"
+ android:paddingTop="18dp"
+ android:textSize="16sp"/>
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 18673e4..dc343a5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -176,6 +176,8 @@
<string name="bluetooth_empty_list_user_restricted">You don\u2019t have permission to change Bluetooth settings.</string>
<!-- Title for bluetooth pairing item [CHAR LIMIT=60] -->
<string name="bluetooth_pairing_pref_title">Pair new device</string>
+ <!-- Keywords for bluetooth pairing item [CHAR LIMIT=30] -->
+ <string name="keywords_add_bt_device">bluetooth</string>
<!-- Bluetooth Visibility message. This message informs the user that their device is now visible to other bluetooth devices. [CHAR LIMIT=NONE] -->
<string name="bluetooth_is_visible_message"><xliff:g id="device_name">%1$s</xliff:g> is visible to nearby devices while Bluetooth settings is open.</string>
@@ -8470,7 +8472,7 @@
<string name="notification_priority_title">Priority</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
- <string name="notification_channel_summary_priority">Shows at top of conversation section and appears as a bubble.</string>
+ <string name="notification_channel_summary_priority">Shows at top of conversation section and appears as a bubble</string>
<string name="convo_not_supported_summary"><xliff:g id="app_name" example="Android Services">%1$s</xliff:g> does not support conversation-specific settings.</string>
@@ -8491,6 +8493,9 @@
<!-- [CHAR LIMIT=100] Label for on/off toggle -->
<string name="notification_switch_label">All \"<xliff:g id="app_name" example="Android Services">%1$s</xliff:g>\" notifications</string>
+ <!-- [CHAR LIMIT=100] Label for on/off toggle -->
+ <string name="notification_app_switch_label">All <xliff:g id="app_name" example="Android Services">%1$s</xliff:g> notifications</string>
+
<!-- Default Apps > Default notification assistant -->
<string name="default_notification_assistant">Adaptive Notifications</string>
@@ -11300,7 +11305,7 @@
<string name="media_output_title">Play media to</string>
<!-- Title with application label for media output settings. [CHAR LIMIT=NONE] -->
- <string name="media_output_label_title">Play <xliff:g id="label" example="Music Player">%s</xliff:g> to</string>
+ <string name="media_output_label_title">Play <xliff:g id="label" example="Music Player">%s</xliff:g> on</string>
<!-- Summary for media output default settings. (this device) [CHAR LIMIT=30] -->
<string name="media_output_default_summary">This device</string>
@@ -11736,7 +11741,12 @@
<string name="see_less">See less</string>
<!-- Title for Network connection request Dialog [CHAR LIMIT=60] -->
- <string name="network_connection_request_dialog_title">Device to use with <xliff:g id="appName" example="ThirdPartyAppName">%1$s</xliff:g></string>
+ <string name="network_connection_request_dialog_title">Connect to device</string>
+ <!-- Summary for Network connection request Dialog [CHAR LIMIT=NONE] -->
+ <string name="network_connection_request_dialog_summary">
+ <xliff:g id="appName" example="ThirdPartyAppName">%1$s</xliff:g>
+ app wants to use a temporary Wi\u2011Fi network to connect to your device
+ </string>
<!-- Message for Network connection timeout Dialog [CHAR LIMIT=NONE] -->
<string name="network_connection_timeout_dialog_message">No devices found. Make sure devices are turned on and available to connect.</string>
<!-- OK button for Network connection timeout Dialog [CHAR LIMIT=30] -->
@@ -11795,6 +11805,11 @@
<!-- Summary for the top level Privacy Settings [CHAR LIMIT=NONE]-->
<string name="privacy_dashboard_summary">Permissions, account activity, personal data</string>
+ <!-- UI debug setting: show media player on quick settings title [CHAR LIMIT=60] -->
+ <string name="quick_settings_media_player">Media resumption</string>
+ <!-- UI debug setting: show media player on quick settings summary [CHAR_LIMIT=NONE] -->
+ <string name="quick_settings_media_player_summary">Shows and persists media player in Quick Settings. Requires reboot.</string>
+
<!-- Label for button in contextual card for users to remove the card [CHAR LIMIT=30] -->
<string name="contextual_card_dismiss_remove">Remove</string>
<!-- Label for button in contextual card for users to keep the card [CHAR LIMIT=30] -->
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index 9931f35..e7e3c2c 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -43,6 +43,7 @@
android:summary="@string/connected_device_add_device_summary"
android:fragment="com.android.settings.bluetooth.BluetoothPairingDetail"
settings:allowDividerAbove="true"
+ settings:keywords="@string/keywords_add_bt_device"
settings:userRestriction="no_config_bluetooth"
settings:useAdminDisabledSummary="true"
settings:controller="com.android.settings.connecteddevice.AddDevicePreferenceController"/>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index bed838c..b781636 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -527,6 +527,11 @@
android:title="@string/usb_audio_disable_routing"
android:summary="@string/usb_audio_disable_routing_summary" />
+ <SwitchPreference
+ android:key="quick_settings_media_player"
+ android:title="@string/quick_settings_media_player"
+ android:summary="@string/quick_settings_media_player_summary" />
+
</PreferenceCategory>
<PreferenceCategory
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
index a063327..a86b441 100644
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
@@ -63,6 +63,7 @@
LifecycleObserver, OnStart, OnStop, OnDestroy, CachedBluetoothDevice.Callback {
private static final String TAG = "AdvancedBtHeaderCtrl";
private static final int LOW_BATTERY_LEVEL = 15;
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
@VisibleForTesting
LayoutPreference mLayoutPreference;
@@ -215,6 +216,11 @@
final int batteryLevel = BluetoothUtils.getIntMetaData(bluetoothDevice, batteryMetaKey);
final boolean charging = BluetoothUtils.getBooleanMetaData(bluetoothDevice, chargeMetaKey);
+ if (DBG) {
+ Log.d(TAG, "updateSubLayout() icon : " + iconMetaKey + ", battery : " + batteryMetaKey
+ + ", charge : " + chargeMetaKey + ", batteryLevel : " + batteryLevel
+ + ", charging : " + charging + ", iconUri : " + iconUri);
+ }
if (batteryLevel != BluetoothUtils.META_INT_ERROR) {
linearLayout.setVisibility(View.VISIBLE);
final TextView textView = linearLayout.findViewById(R.id.bt_battery_summary);
@@ -268,6 +274,9 @@
final BluetoothDevice bluetoothDevice = mCachedDevice.getDevice();
final String iconUri = BluetoothUtils.getStringMetaData(bluetoothDevice,
BluetoothDevice.METADATA_MAIN_ICON);
+ if (DBG) {
+ Log.d(TAG, "updateDisconnectLayout() iconUri : " + iconUri);
+ }
if (iconUri != null) {
final ImageView imageView = linearLayout.findViewById(R.id.header_icon);
updateIcon(imageView, iconUri);
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index aa4f869..27d63bf 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -33,7 +33,7 @@
implements Preference.OnPreferenceClickListener {
private static final String TAG = "AvailableMediaBluetoothDeviceUpdater";
- private static final boolean DBG = false;
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
private static final String PREF_KEY = "available_media_bt";
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
index 21312a5..8cb698f 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
@@ -52,7 +52,7 @@
public abstract class BluetoothDeviceUpdater implements BluetoothCallback,
LocalBluetoothProfileManager.ServiceListener {
private static final String TAG = "BluetoothDeviceUpdater";
- private static final boolean DBG = false;
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
protected final MetricsFeatureProvider mMetricsFeatureProvider;
protected final DevicePreferenceCallback mDevicePreferenceCallback;
diff --git a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index c7cae7f..fc1b9b7 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -33,7 +33,7 @@
public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {
private static final String TAG = "ConnBluetoothDeviceUpdater";
- private static final boolean DBG = false;
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
private static final String PREF_KEY = "connected_bt";
diff --git a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
index bbcd13c..466d60e 100644
--- a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
@@ -38,7 +38,7 @@
implements Preference.OnPreferenceClickListener {
private static final String TAG = "SavedBluetoothDeviceUpdater";
- private static final boolean DBG = false;
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
private static final String PREF_KEY = "saved_bt";
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
index b417c3d..4178f6c 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
@@ -47,8 +47,10 @@
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.net.DataUsageController;
+import com.android.settingslib.utils.ThreadUtils;
import java.util.List;
+import java.util.concurrent.Future;
/**
* This is the controller for a data usage header that retrieves carrier data from the new
@@ -99,6 +101,8 @@
private Intent mManageSubscriptionIntent;
+ private Future<Long> mHistoricalUsageLevel;
+
public DataUsageSummaryPreferenceController(Activity activity,
Lifecycle lifecycle, PreferenceFragmentCompat fragment, int subscriptionId) {
super(activity, KEY);
@@ -206,13 +210,13 @@
updateConfiguration(mContext, mSubId, subInfo);
}
+ mHistoricalUsageLevel = ThreadUtils.postOnBackgroundThread(() ->
+ mDataUsageController.getHistoricalUsageLevel(mDefaultTemplate));
+
final DataUsageController.DataUsageInfo info =
mDataUsageController.getDataUsageInfo(mDefaultTemplate);
long usageLevel = info.usageLevel;
- if (usageLevel <= 0L) {
- usageLevel = mDataUsageController.getHistoricalUsageLevel(mDefaultTemplate);
- }
if (subInfo != null) {
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
@@ -222,7 +226,7 @@
summaryPreference.setWifiMode(/* isWifiMode */ true, /* usagePeriod */
info.period, /* isSingleWifi */ false);
summaryPreference.setLimitInfo(null);
- summaryPreference.setUsageNumbers(usageLevel,
+ summaryPreference.setUsageNumbers(displayUsageLevel(usageLevel),
/* dataPlanSize */ -1L,
/* hasMobileData */ true);
summaryPreference.setChartEnabled(false);
@@ -235,11 +239,6 @@
}
refreshDataplanInfo(info, subInfo);
- if ((mDataplanUse <= 0L) && (mSnapshotTime < 0)) {
- Log.d(TAG, "Display data usage from history");
- mDataplanUse = usageLevel;
- mSnapshotTime = -1L;
- }
if (info.warningLevel > 0 && info.limitLevel > 0) {
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
@@ -258,6 +257,12 @@
summaryPreference.setLimitInfo(null);
}
+ if ((mDataplanUse <= 0L) && (mSnapshotTime < 0)) {
+ Log.d(TAG, "Display data usage from history");
+ mDataplanUse = displayUsageLevel(usageLevel);
+ mSnapshotTime = -1L;
+ }
+
summaryPreference.setUsageNumbers(mDataplanUse, mDataplanSize, mHasMobileData);
if (mDataBarSize <= 0) {
@@ -272,6 +277,17 @@
mDataplanCount, mManageSubscriptionIntent);
}
+ private long displayUsageLevel(long usageLevel) {
+ if (usageLevel > 0) {
+ return usageLevel;
+ }
+ try {
+ usageLevel = mHistoricalUsageLevel.get();
+ } catch (Exception ex) {
+ }
+ return usageLevel;
+ }
+
// TODO(b/70950124) add test for this method once the robolectric shadow run script is
// completed (b/3526807)
private void refreshDataplanInfo(DataUsageController.DataUsageInfo info,
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 7da58a7..4df641e 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -496,6 +496,7 @@
controllers.add(new DebugNonRectClipOperationsPreferenceController(context));
controllers.add(new ForceDarkPreferenceController(context));
controllers.add(new EnableBlursPreferenceController(context));
+ controllers.add(new QuickSettingsMediaPlayerPreferenceController(context));
controllers.add(new ForceMSAAPreferenceController(context));
controllers.add(new HardwareOverlaysPreferenceController(context));
controllers.add(new SimulateColorSpacePreferenceController(context));
diff --git a/src/com/android/settings/development/QuickSettingsMediaPlayerPreferenceController.java b/src/com/android/settings/development/QuickSettingsMediaPlayerPreferenceController.java
new file mode 100644
index 0000000..47f3adc
--- /dev/null
+++ b/src/com/android/settings/development/QuickSettingsMediaPlayerPreferenceController.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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.development;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+/**
+ * Controls whether the media player should be visible in quick settings.
+ */
+public class QuickSettingsMediaPlayerPreferenceController extends
+ DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
+ PreferenceControllerMixin {
+ private static final String PREFERENCE_KEY = "quick_settings_media_player";
+ @VisibleForTesting
+ static final String SETTING_NAME = Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS;
+ @VisibleForTesting
+ static final int SETTING_VALUE_ON = 1;
+ @VisibleForTesting
+ static final int SETTING_VALUE_OFF = 0;
+
+ public QuickSettingsMediaPlayerPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREFERENCE_KEY;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean isEnabled = (Boolean) newValue;
+ Settings.Global.putInt(mContext.getContentResolver(), SETTING_NAME,
+ isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(), SETTING_NAME,
+ SETTING_VALUE_OFF);
+ ((SwitchPreference) mPreference).setChecked(mode != SETTING_VALUE_OFF);
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ super.onDeveloperOptionsSwitchDisabled();
+ Settings.Global.putInt(mContext.getContentResolver(), SETTING_NAME, SETTING_VALUE_OFF);
+ ((SwitchPreference) mPreference).setChecked(false);
+ }
+}
diff --git a/src/com/android/settings/media/MediaDeviceUpdateWorker.java b/src/com/android/settings/media/MediaDeviceUpdateWorker.java
index c768257..52249ff 100644
--- a/src/com/android/settings/media/MediaDeviceUpdateWorker.java
+++ b/src/com/android/settings/media/MediaDeviceUpdateWorker.java
@@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
+import android.media.RoutingSessionInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
@@ -173,6 +174,10 @@
return mLocalMediaManager.getSelectedMediaDevice();
}
+ void adjustSessionVolume(String sessionId, int volume) {
+ mLocalMediaManager.adjustSessionVolume(sessionId, volume);
+ }
+
void adjustSessionVolume(int volume) {
mLocalMediaManager.adjustSessionVolume(volume);
}
@@ -189,15 +194,14 @@
return mLocalMediaManager.getSessionName();
}
- /**
- * Find the active MediaDevice.
- *
- * @param type the media device type.
- * @return MediaDevice list
- *
- */
- public List<MediaDevice> getActiveMediaDevice(@MediaDevice.MediaDeviceType int type) {
- return mLocalMediaManager.getActiveMediaDevice(type);
+ List<RoutingSessionInfo> getActiveRemoteMediaDevice() {
+ final List<RoutingSessionInfo> sessionInfos = new ArrayList<>();
+ for (RoutingSessionInfo info : mLocalMediaManager.getActiveMediaSession()) {
+ if (!info.isSystemSession()) {
+ sessionInfos.add(info);
+ }
+ }
+ return sessionInfos;
}
/**
diff --git a/src/com/android/settings/media/RemoteMediaSlice.java b/src/com/android/settings/media/RemoteMediaSlice.java
index 4e442b7..71a41b3 100644
--- a/src/com/android/settings/media/RemoteMediaSlice.java
+++ b/src/com/android/settings/media/RemoteMediaSlice.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.media.RoutingSessionInfo;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
@@ -41,7 +42,6 @@
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settings.slices.SliceBuilderUtils;
-import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaOutputSliceConstants;
import java.util.List;
@@ -67,7 +67,7 @@
final int newPosition = intent.getIntExtra(EXTRA_RANGE_VALUE, -1);
final String id = intent.getStringExtra(MEDIA_ID);
if (!TextUtils.isEmpty(id)) {
- getWorker().adjustVolume(getWorker().getMediaDeviceById(id), newPosition);
+ getWorker().adjustSessionVolume(id, newPosition);
}
}
@@ -80,9 +80,8 @@
return listBuilder.build();
}
// Only displaying remote devices
- final List<MediaDevice> mediaDevices = getWorker().getActiveMediaDevice(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
- if (mediaDevices.isEmpty()) {
+ final List<RoutingSessionInfo> infos = getWorker().getActiveRemoteMediaDevice();
+ if (infos.isEmpty()) {
Log.d(TAG, "No active remote media device");
return listBuilder.build();
}
@@ -93,27 +92,25 @@
// To create an empty icon to indent the row
final IconCompat emptyIcon = createEmptyIcon();
int requestCode = 0;
- for (MediaDevice mediaDevice : mediaDevices) {
- final int maxVolume = mediaDevice.getMaxVolume();
+ for (RoutingSessionInfo info : infos) {
+ final int maxVolume = info.getVolumeMax();
if (maxVolume <= 0) {
- Log.d(TAG, "Unable to add Slice. " + mediaDevice.getName() + ": max volume is "
+ Log.d(TAG, "Unable to add Slice. " + info.getName() + ": max volume is "
+ maxVolume);
continue;
}
- final String title = castVolume + " (" + mediaDevice.getClientAppLabel() + ")";
listBuilder.addInputRange(new InputRangeBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
- .setTitle(title)
- .setInputAction(getSliderInputAction(requestCode++, mediaDevice.getId()))
- .setPrimaryAction(getSoundSettingAction(title, icon, mediaDevice.getId()))
+ .setTitle(castVolume)
+ .setInputAction(getSliderInputAction(requestCode++, info.getId()))
+ .setPrimaryAction(getSoundSettingAction(castVolume, icon, info.getId()))
.setMax(maxVolume)
- .setValue(mediaDevice.getCurrentVolume()));
+ .setValue(info.getVolume()));
listBuilder.addRow(new ListBuilder.RowBuilder()
.setTitle(outputTitle)
- .setSubtitle(mediaDevice.getName())
+ .setSubtitle(info.getName())
.setTitleItem(emptyIcon, ListBuilder.ICON_IMAGE)
- .setPrimaryAction(getMediaOutputSliceAction(
- mediaDevice.getClientPackageName())));
+ .setPrimaryAction(getMediaOutputSliceAction(info.getClientPackageName())));
}
return listBuilder.build();
}
@@ -131,7 +128,8 @@
return PendingIntent.getBroadcast(mContext, requestCode, intent, 0);
}
- private SliceAction getSoundSettingAction(String actionTitle, IconCompat icon, String id) {
+ private SliceAction getSoundSettingAction(CharSequence actionTitle, IconCompat icon,
+ String id) {
final Uri contentUri = new Uri.Builder().appendPath(id).build();
final Intent intent = SliceBuilderUtils.buildSearchResultPageIntent(mContext,
SoundSettings.class.getName(),
diff --git a/src/com/android/settings/network/ActiveSubsciptionsListener.java b/src/com/android/settings/network/ActiveSubsciptionsListener.java
index 99dfd55..3d15025 100644
--- a/src/com/android/settings/network/ActiveSubsciptionsListener.java
+++ b/src/com/android/settings/network/ActiveSubsciptionsListener.java
@@ -73,6 +73,7 @@
* @param context {@code Context} of this listener
*/
public ActiveSubsciptionsListener(Looper looper, Context context) {
+ super(looper);
mLooper = looper;
mContext = context;
diff --git a/src/com/android/settings/network/ProxySubscriptionManager.java b/src/com/android/settings/network/ProxySubscriptionManager.java
index 0306b55..a89cc83 100644
--- a/src/com/android/settings/network/ProxySubscriptionManager.java
+++ b/src/com/android/settings/network/ProxySubscriptionManager.java
@@ -72,7 +72,7 @@
private static ProxySubscriptionManager sSingleton;
private ProxySubscriptionManager(Context context) {
- final Looper looper = Looper.getMainLooper();
+ final Looper looper = context.getMainLooper();
mActiveSubscriptionsListeners =
new ArrayList<OnActiveSubscriptionChangedListener>();
diff --git a/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java b/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java
new file mode 100644
index 0000000..889fbae
--- /dev/null
+++ b/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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.network.telephony;
+
+import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+abstract class AbstractMobileNetworkSettings extends RestrictedDashboardFragment {
+
+ private static final String LOG_TAG = "AbsNetworkSettings";
+
+ /**
+ * @param restrictionKey The restriction key to check before pin protecting
+ * this settings page. Pass in {@link RESTRICT_IF_OVERRIDABLE} if it should
+ * be protected whenever a restrictions provider is set. Pass in
+ * null if it should never be protected.
+ */
+ AbstractMobileNetworkSettings(String restrictionKey) {
+ super(restrictionKey);
+ }
+
+ List<AbstractPreferenceController> getPreferenceControllersAsList() {
+ final List<AbstractPreferenceController> result =
+ new ArrayList<AbstractPreferenceController>();
+ getPreferenceControllers().forEach(controllers -> result.addAll(controllers));
+ return result;
+ }
+
+ TelephonyStatusControlSession setTelephonyAvailabilityStatus(
+ Collection<AbstractPreferenceController> listOfPrefControllers) {
+ return (new TelephonyStatusControlSession.Builder(listOfPrefControllers))
+ .build();
+ }
+
+}
diff --git a/src/com/android/settings/network/telephony/ApnPreferenceController.java b/src/com/android/settings/network/telephony/ApnPreferenceController.java
index dd68129..8442de2 100644
--- a/src/com/android/settings/network/telephony/ApnPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ApnPreferenceController.java
@@ -93,6 +93,9 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
+ if (mPreference == null) {
+ return;
+ }
((RestrictedPreference) mPreference).setDisabledByAdmin(
MobileNetworkUtils.isDpcApnEnforced(mContext)
? RestrictedLockUtilsInternal.getDeviceOwner(mContext)
diff --git a/src/com/android/settings/network/telephony/DataDuringCallsPreferenceController.java b/src/com/android/settings/network/telephony/DataDuringCallsPreferenceController.java
index 1137e06..625f863 100644
--- a/src/com/android/settings/network/telephony/DataDuringCallsPreferenceController.java
+++ b/src/com/android/settings/network/telephony/DataDuringCallsPreferenceController.java
@@ -49,10 +49,6 @@
public DataDuringCallsPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
- mChangeListener = new SubscriptionsChangeListener(mContext, this);
- mMobileDataContentObserver = new MobileDataContentObserver(
- new Handler(Looper.getMainLooper()));
- mMobileDataContentObserver.setOnMobileDataChangedListener(()->refreshPreference());
}
public void init(Lifecycle lifecycle, int subId) {
@@ -63,14 +59,26 @@
@OnLifecycleEvent(ON_RESUME)
public void onResume() {
+ if (mChangeListener == null) {
+ mChangeListener = new SubscriptionsChangeListener(mContext, this);
+ }
mChangeListener.start();
+ if (mMobileDataContentObserver == null) {
+ mMobileDataContentObserver = new MobileDataContentObserver(
+ new Handler(Looper.getMainLooper()));
+ mMobileDataContentObserver.setOnMobileDataChangedListener(() -> refreshPreference());
+ }
mMobileDataContentObserver.register(mContext, mSubId);
}
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
- mChangeListener.stop();
- mMobileDataContentObserver.unRegister(mContext);
+ if (mChangeListener != null) {
+ mChangeListener.stop();
+ }
+ if (mMobileDataContentObserver != null) {
+ mMobileDataContentObserver.unRegister(mContext);
+ }
}
@Override
@@ -103,6 +111,9 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
+ if (preference == null) {
+ return;
+ }
preference.setVisible(isAvailable());
}
diff --git a/src/com/android/settings/network/telephony/DataUsagePreferenceController.java b/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
index 035a8c1..08524d6 100644
--- a/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
+++ b/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
@@ -45,6 +45,7 @@
private Future<NetworkTemplate> mTemplateFuture;
private AtomicReference<NetworkTemplate> mTemplate;
+ private Future<Long> mHistoricalUsageLevel;
public DataUsagePreferenceController(Context context, String key) {
super(context, key);
@@ -127,11 +128,17 @@
final DataUsageController controller = new DataUsageController(context);
controller.setSubscriptionId(subId);
+ mHistoricalUsageLevel = ThreadUtils.postOnBackgroundThread(() ->
+ controller.getHistoricalUsageLevel(getNetworkTemplate()));
+
final DataUsageController.DataUsageInfo usageInfo = getDataUsageInfo(controller);
long usageLevel = usageInfo.usageLevel;
if (usageLevel <= 0L) {
- usageLevel = controller.getHistoricalUsageLevel(getNetworkTemplate());
+ try {
+ usageLevel = mHistoricalUsageLevel.get();
+ } catch (Exception exception) {
+ }
}
if (usageLevel <= 0L) {
return null;
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index 650890e..779802a 100644
--- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -35,7 +35,6 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.SubscriptionsChangeListener;
@@ -47,8 +46,8 @@
* what mobile network subscription is used by default for some service controlled by the
* SubscriptionManager. This can be used for services such as Calls or SMS.
*/
-public abstract class DefaultSubscriptionController extends BasePreferenceController implements
- LifecycleObserver, Preference.OnPreferenceChangeListener,
+public abstract class DefaultSubscriptionController extends TelephonyBasePreferenceController
+ implements LifecycleObserver, Preference.OnPreferenceChangeListener,
SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
private static final String TAG = "DefaultSubController";
@@ -85,7 +84,7 @@
protected abstract void setDefaultSubscription(int subscriptionId);
@Override
- public int getAvailabilityStatus() {
+ public int getAvailabilityStatus(int subId) {
final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
if (subs.size() > 1) {
return AVAILABLE;
diff --git a/src/com/android/settings/network/telephony/DisableSimFooterPreferenceController.java b/src/com/android/settings/network/telephony/DisableSimFooterPreferenceController.java
index f5bcce7..d14c8d0 100644
--- a/src/com/android/settings/network/telephony/DisableSimFooterPreferenceController.java
+++ b/src/com/android/settings/network/telephony/DisableSimFooterPreferenceController.java
@@ -20,30 +20,37 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.SubscriptionUtil;
-public class DisableSimFooterPreferenceController extends BasePreferenceController {
- private int mSubId;
+/**
+ * Shows information about disable a physical SIM.
+ */
+public class DisableSimFooterPreferenceController extends TelephonyBasePreferenceController {
+ /**
+ * Constructor
+ */
public DisableSimFooterPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
- mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
+ /**
+ * re-init for SIM based on given subscription ID.
+ * @param subId is the given subscription ID
+ */
public void init(int subId) {
mSubId = subId;
}
@Override
- public int getAvailabilityStatus() {
- if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ public int getAvailabilityStatus(int subId) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return CONDITIONALLY_UNAVAILABLE;
}
SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) {
- if (info.getSubscriptionId() == mSubId) {
+ if (info.getSubscriptionId() == subId) {
if (info.isEmbedded() || SubscriptionUtil.showToggleForPhysicalSim(subManager)) {
return CONDITIONALLY_UNAVAILABLE;
}
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index 5343709..d5a192a 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -61,19 +61,6 @@
public EnabledNetworkModePreferenceController(Context context, String key) {
super(context, key);
- mPreferredNetworkModeObserver = new PreferredNetworkModeContentObserver(
- new Handler(Looper.getMainLooper()));
- mPreferredNetworkModeObserver.setPreferredNetworkModeChangedListener(
- () -> updatePreference());
- }
-
- private void updatePreference() {
- if (mPreferenceScreen != null) {
- displayPreference(mPreferenceScreen);
- }
- if (mPreference != null) {
- updateState(mPreference);
- }
}
@Override
@@ -100,11 +87,17 @@
@OnLifecycleEvent(ON_START)
public void onStart() {
+ if (mPreferredNetworkModeObserver == null) {
+ return;
+ }
mPreferredNetworkModeObserver.register(mContext, mSubId);
}
@OnLifecycleEvent(ON_STOP)
public void onStop() {
+ if (mPreferredNetworkModeObserver == null) {
+ return;
+ }
mPreferredNetworkModeObserver.unregister(mContext);
}
@@ -151,9 +144,25 @@
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
mBuilder = new PreferenceEntriesBuilder(mContext, mSubId);
+ if (mPreferredNetworkModeObserver == null) {
+ mPreferredNetworkModeObserver = new PreferredNetworkModeContentObserver(
+ new Handler(Looper.getMainLooper()));
+ mPreferredNetworkModeObserver.setPreferredNetworkModeChangedListener(
+ () -> updatePreference());
+ }
+
lifecycle.addObserver(this);
}
+ private void updatePreference() {
+ if (mPreferenceScreen != null) {
+ displayPreference(mPreferenceScreen);
+ }
+ if (mPreference != null) {
+ updateState(mPreference);
+ }
+ }
+
private final static class PreferenceEntriesBuilder {
private CarrierConfigManager mCarrierConfigManager;
private Context mContext;
diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
index 3a91616..91d01d3 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
@@ -69,10 +69,13 @@
public Enhanced4gBasePreferenceController(Context context, String key) {
super(context, key);
m4gLteListeners = new ArrayList<>();
- mPhoneStateListener = new PhoneCallStateListener();
}
public Enhanced4gBasePreferenceController init(int subId) {
+ if (mPhoneStateListener == null) {
+ mPhoneStateListener = new PhoneCallStateListener();
+ }
+
if (mSubId == subId) {
return this;
}
@@ -122,11 +125,17 @@
@Override
public void onStart() {
+ if (mPhoneStateListener == null) {
+ return;
+ }
mPhoneStateListener.register(mContext, mSubId);
}
@Override
public void onStop() {
+ if (mPhoneStateListener == null) {
+ return;
+ }
mPhoneStateListener.unregister();
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 54fe2c1..754dd05 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -36,8 +36,6 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settings.datausage.BillingCyclePreferenceController;
import com.android.settings.datausage.DataUsageSummaryPreferenceController;
import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController;
@@ -47,17 +45,14 @@
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
-public class MobileNetworkSettings extends RestrictedDashboardFragment {
+public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
private static final String LOG_TAG = "NetworkSettings";
public static final int REQUEST_CODE_EXIT_ECM = 17;
@@ -133,7 +128,11 @@
public void onAttach(Context context) {
super.onAttach(context);
- use(DataUsageSummaryPreferenceController.class).init(mSubId);
+ final DataUsageSummaryPreferenceController dataUsageSummaryPreferenceController =
+ use(DataUsageSummaryPreferenceController.class);
+ if (dataUsageSummaryPreferenceController != null) {
+ dataUsageSummaryPreferenceController.init(mSubId);
+ }
use(CallsDefaultSubscriptionController.class).init(getLifecycle());
use(SmsDefaultSubscriptionController.class).init(getLifecycle());
use(MobileNetworkSwitchController.class).init(getLifecycle(), mSubId);
@@ -189,11 +188,8 @@
public void onCreate(Bundle icicle) {
Log.i(LOG_TAG, "onCreate:+");
- final Collection<List<AbstractPreferenceController>> controllerLists =
- getPreferenceControllers();
- final Future<Boolean> result = ThreadUtils.postOnBackgroundThread(() ->
- setupAvailabilityStatus(controllerLists)
- );
+ final TelephonyStatusControlSession session =
+ setTelephonyAvailabilityStatus(getPreferenceControllersAsList());
super.onCreate(icicle);
final Context context = getContext();
@@ -201,46 +197,11 @@
mTelephonyManager = context.getSystemService(TelephonyManager.class)
.createForSubscriptionId(mSubId);
- //check the background thread is finished then unset the status of availability.
- try {
- result.get();
- } catch (ExecutionException | InterruptedException exception) {
- Log.e(LOG_TAG, "onCreate, setup availability status failed!", exception);
- }
- unsetAvailabilityStatus(controllerLists);
+ session.close();
onRestoreInstance(icicle);
}
- private Boolean setupAvailabilityStatus(
- Collection<List<AbstractPreferenceController>> controllerLists) {
- try {
- controllerLists.stream().flatMap(Collection::stream)
- .filter(controller -> controller instanceof TelephonyAvailabilityHandler)
- .map(TelephonyAvailabilityHandler.class::cast)
- .forEach(controller -> {
- int status = ((BasePreferenceController) controller)
- .getAvailabilityStatus();
- controller.unsetAvailabilityStatus(true);
- controller.setAvailabilityStatus(status);
- });
- return true;
- } catch (Exception exception) {
- Log.e(LOG_TAG, "Setup availability status failed!", exception);
- return false;
- }
- }
-
- private void unsetAvailabilityStatus(
- Collection<List<AbstractPreferenceController>> controllerLists) {
- controllerLists.stream().flatMap(Collection::stream)
- .filter(controller -> controller instanceof TelephonyAvailabilityHandler)
- .map(TelephonyAvailabilityHandler.class::cast)
- .forEach(controller -> {
- controller.unsetAvailabilityStatus(false);
- });
- }
-
@Override
public void onExpandButtonClick() {
final PreferenceScreen screen = getPreferenceScreen();
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index 584848f..7877063 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -217,16 +217,13 @@
switch (msg.what) {
case EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE:
final boolean isSucceed = (boolean) msg.obj;
- if (isSucceed) {
- // Don't enable screen here. Wait until result of network re-scan.
- startNetworkQuery();
- } else {
- stopNetworkQuery();
- setProgressBarVisible(false);
- getPreferenceScreen().setEnabled(true);
- // For failure case, only update the summary of selected item.
- mSelectedPreference.setSummary(R.string.network_could_not_connect);
- }
+ stopNetworkQuery();
+ setProgressBarVisible(false);
+ getPreferenceScreen().setEnabled(true);
+
+ mSelectedPreference.setSummary(isSucceed
+ ? R.string.network_connected
+ : R.string.network_could_not_connect);
break;
case EVENT_NETWORK_SCAN_RESULTS:
final List<CellInfo> results = (List<CellInfo>) msg.obj;
@@ -418,6 +415,7 @@
// (it would be quite confusing why the connected network has no signal)
pref.setIcon(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
mPreferenceCategory.addPreference(pref);
+ break;
}
}
}
diff --git a/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java b/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java
index 50dd26b..c1acd91 100644
--- a/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java
+++ b/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java
@@ -25,14 +25,16 @@
public interface TelephonyAvailabilityHandler {
/**
- * Set availability to preference controller.
+ * Set availability status of preference controller to a fixed value.
+ * @param status is the given status. Which will be reported from
+ * {@link BasePreferenceController#getAvailabilityStatus()}
*/
- public void setAvailabilityStatus(int status);
+ void setAvailabilityStatus(int status);
/**
* Do not set availability, use
* {@link MobileNetworkUtils#getAvailability(Context, int, TelephonyAvailabilityCallback)}
* to get the availability.
*/
- public void unsetAvailabilityStatus(boolean enable);
+ void unsetAvailabilityStatus();
}
diff --git a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
index 678209d..2bd7de9 100644
--- a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
@@ -23,7 +23,6 @@
import com.android.settings.core.BasePreferenceController;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -33,7 +32,7 @@
implements TelephonyAvailabilityCallback, TelephonyAvailabilityHandler {
protected int mSubId;
private AtomicInteger mAvailabilityStatus = new AtomicInteger(0);
- private AtomicBoolean mUnsetAvailabilityStatus = new AtomicBoolean(false);
+ private AtomicInteger mSetSessionCount = new AtomicInteger(0);
public TelephonyBasePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -42,7 +41,7 @@
@Override
public int getAvailabilityStatus() {
- if (!mUnsetAvailabilityStatus.get()) {
+ if (mSetSessionCount.get() <= 0) {
mAvailabilityStatus.set(MobileNetworkUtils
.getAvailability(mContext, mSubId, this::getAvailabilityStatus));
}
@@ -52,11 +51,12 @@
@Override
public void setAvailabilityStatus(int status) {
mAvailabilityStatus.set(status);
+ mSetSessionCount.getAndIncrement();
}
@Override
- public void unsetAvailabilityStatus(boolean enable) {
- mUnsetAvailabilityStatus.set(enable);
+ public void unsetAvailabilityStatus() {
+ mSetSessionCount.getAndDecrement();
}
/**
diff --git a/src/com/android/settings/network/telephony/TelephonyStatusControlSession.java b/src/com/android/settings/network/telephony/TelephonyStatusControlSession.java
new file mode 100644
index 0000000..12c9bee
--- /dev/null
+++ b/src/com/android/settings/network/telephony/TelephonyStatusControlSession.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 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.network.telephony;
+
+import android.util.Log;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.Collection;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * Session for controlling the status of TelephonyPreferenceController(s).
+ *
+ * Within this session, result of {@link BasePreferenceController#availabilityStatus()}
+ * would be under control.
+ */
+public class TelephonyStatusControlSession implements AutoCloseable {
+
+ private static final String LOG_TAG = "TelephonyStatusControlSS";
+
+ private Collection<AbstractPreferenceController> mControllers;
+ private Future<Boolean> mResult;
+
+ /**
+ * Buider of session
+ */
+ public static class Builder {
+ private Collection<AbstractPreferenceController> mControllers;
+
+ /**
+ * Constructor
+ *
+ * @param controllers is a collection of {@link AbstractPreferenceController}
+ * which would have {@link BasePreferenceController#availabilityStatus()}
+ * under control within this session.
+ */
+ public Builder(Collection<AbstractPreferenceController> controllers) {
+ mControllers = controllers;
+ }
+
+ /**
+ * Method to build this session.
+ * @return {@link TelephonyStatusControlSession} session been setup.
+ */
+ public TelephonyStatusControlSession build() {
+ return new TelephonyStatusControlSession(mControllers);
+ }
+ }
+
+ private TelephonyStatusControlSession(Collection<AbstractPreferenceController> controllers) {
+ mControllers = controllers;
+ mResult = ThreadUtils.postOnBackgroundThread(() ->
+ setupAvailabilityStatus(controllers)
+ );
+ }
+
+ /**
+ * Close the session.
+ *
+ * No longer control the status.
+ */
+ public void close() {
+ //check the background thread is finished then unset the status of availability.
+ try {
+ mResult.get();
+ } catch (ExecutionException | InterruptedException exception) {
+ Log.e(LOG_TAG, "setup availability status failed!", exception);
+ }
+ unsetAvailabilityStatus(mControllers);
+ }
+
+ private Boolean setupAvailabilityStatus(
+ Collection<AbstractPreferenceController> controllerLists) {
+ try {
+ controllerLists.stream()
+ .filter(controller -> controller instanceof TelephonyAvailabilityHandler)
+ .map(TelephonyAvailabilityHandler.class::cast)
+ .forEach(controller -> {
+ int status = ((BasePreferenceController) controller)
+ .getAvailabilityStatus();
+ controller.setAvailabilityStatus(status);
+ });
+ return true;
+ } catch (Exception exception) {
+ Log.e(LOG_TAG, "Setup availability status failed!", exception);
+ return false;
+ }
+ }
+
+ private void unsetAvailabilityStatus(
+ Collection<AbstractPreferenceController> controllerLists) {
+ controllerLists.stream()
+ .filter(controller -> controller instanceof TelephonyAvailabilityHandler)
+ .map(TelephonyAvailabilityHandler.class::cast)
+ .forEach(controller -> {
+ controller.unsetAvailabilityStatus();
+ });
+ }
+}
diff --git a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java
index 56d51eb..84aa0cb 100644
--- a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java
+++ b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java
@@ -23,7 +23,6 @@
import com.android.settings.core.TogglePreferenceController;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -33,8 +32,7 @@
implements TelephonyAvailabilityCallback, TelephonyAvailabilityHandler {
protected int mSubId;
private AtomicInteger mAvailabilityStatus = new AtomicInteger(0);
- private AtomicBoolean mUnsetAvailabilityStatus = new AtomicBoolean(false);
-
+ private AtomicInteger mSetSessionCount = new AtomicInteger(0);
public TelephonyTogglePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -43,7 +41,7 @@
@Override
public int getAvailabilityStatus() {
- if (!mUnsetAvailabilityStatus.get()) {
+ if (mSetSessionCount.get() <= 0) {
mAvailabilityStatus.set(MobileNetworkUtils
.getAvailability(mContext, mSubId, this::getAvailabilityStatus));
}
@@ -53,11 +51,12 @@
@Override
public void setAvailabilityStatus(int status) {
mAvailabilityStatus.set(status);
+ mSetSessionCount.getAndIncrement();
}
@Override
- public void unsetAvailabilityStatus(boolean enable) {
- mUnsetAvailabilityStatus.set(enable);
+ public void unsetAvailabilityStatus() {
+ mSetSessionCount.getAndDecrement();
}
/**
diff --git a/src/com/android/settings/notification/RemoteVolumeGroupController.java b/src/com/android/settings/notification/RemoteVolumeGroupController.java
index c36035a..137f780 100644
--- a/src/com/android/settings/notification/RemoteVolumeGroupController.java
+++ b/src/com/android/settings/notification/RemoteVolumeGroupController.java
@@ -18,6 +18,8 @@
import android.content.Context;
import android.content.Intent;
+import android.media.RoutingSessionInfo;
+import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -51,7 +53,7 @@
static final String SWITCHER_PREFIX = "OUTPUT_SWITCHER";
private PreferenceCategory mPreferenceCategory;
- private List<MediaDevice> mActiveRemoteMediaDevices = new ArrayList<>();
+ private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@VisibleForTesting
LocalMediaManager mLocalMediaManager;
@@ -67,7 +69,7 @@
@Override
public int getAvailabilityStatus() {
- if (mActiveRemoteMediaDevices.isEmpty()) {
+ if (mRoutingSessionInfos.isEmpty()) {
return CONDITIONALLY_UNAVAILABLE;
}
return AVAILABLE_UNSEARCHABLE;
@@ -77,12 +79,19 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceCategory = screen.findPreference(getPreferenceKey());
- mActiveRemoteMediaDevices.clear();
- mActiveRemoteMediaDevices.addAll(mLocalMediaManager.getActiveMediaDevice(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE));
+ initRemoteMediaSession();
refreshPreference();
}
+ private void initRemoteMediaSession() {
+ mRoutingSessionInfos.clear();
+ for (RoutingSessionInfo info : mLocalMediaManager.getActiveMediaSession()) {
+ if (!info.isSystemSession()) {
+ mRoutingSessionInfos.add(info);
+ }
+ }
+ }
+
/**
* onDestroy()
* {@link androidx.lifecycle.OnLifecycleEvent}
@@ -102,27 +111,27 @@
final CharSequence outputTitle = mContext.getText(R.string.media_output_title);
final CharSequence castVolume = mContext.getText(R.string.remote_media_volume_option_title);
mPreferenceCategory.setVisible(true);
- int i = 0;
- for (MediaDevice device : mActiveRemoteMediaDevices) {
- if (mPreferenceCategory.findPreference(device.getId()) != null) {
+
+ for (RoutingSessionInfo info : mRoutingSessionInfos) {
+ if (mPreferenceCategory.findPreference(info.getId()) != null) {
continue;
}
// Add slider
final RemoteVolumeSeekBarPreference seekBarPreference =
new RemoteVolumeSeekBarPreference(mContext);
- seekBarPreference.setKey(device.getId());
- seekBarPreference.setTitle(castVolume + " (" + device.getClientAppLabel() + ")");
- seekBarPreference.setMax(device.getMaxVolume());
- seekBarPreference.setProgress(device.getCurrentVolume());
+ seekBarPreference.setKey(info.getId());
+ seekBarPreference.setTitle(castVolume);
+ seekBarPreference.setMax(info.getVolumeMax());
+ seekBarPreference.setProgress(info.getVolume());
seekBarPreference.setMin(0);
seekBarPreference.setOnPreferenceChangeListener(this);
seekBarPreference.setIcon(R.drawable.ic_volume_remote);
mPreferenceCategory.addPreference(seekBarPreference);
// Add output indicator
final Preference preference = new Preference(mContext);
- preference.setKey(SWITCHER_PREFIX + device.getId());
+ preference.setKey(SWITCHER_PREFIX + info.getId());
preference.setTitle(outputTitle);
- preference.setSummary(device.getName());
+ preference.setSummary(info.getName());
mPreferenceCategory.addPreference(preference);
}
}
@@ -135,7 +144,7 @@
return false;
}
ThreadUtils.postOnBackgroundThread(() -> {
- device.requestSetVolume((int) newValue);
+ mLocalMediaManager.adjustSessionVolume(preference.getKey(), (int) newValue);
});
return true;
}
@@ -145,18 +154,19 @@
if (!preference.getKey().startsWith(SWITCHER_PREFIX)) {
return false;
}
- final String key = preference.getKey().substring(SWITCHER_PREFIX.length());
- final MediaDevice device = mLocalMediaManager.getMediaDeviceById(key);
- if (device == null) {
- return false;
+ for (RoutingSessionInfo info : mRoutingSessionInfos) {
+ if (TextUtils.equals(info.getId(),
+ preference.getKey().substring(SWITCHER_PREFIX.length()))) {
+ final Intent intent = new Intent()
+ .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+ info.getClientPackageName());
+ mContext.startActivity(intent);
+ return true;
+ }
}
- final Intent intent = new Intent()
- .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
- device.getClientPackageName());
- mContext.startActivity(intent);
- return true;
+ return false;
}
@Override
@@ -170,9 +180,7 @@
// Preference group is not ready.
return;
}
- mActiveRemoteMediaDevices.clear();
- mActiveRemoteMediaDevices.addAll(mLocalMediaManager.getActiveMediaDevice(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE));
+ initRemoteMediaSession();
refreshPreference();
}
diff --git a/src/com/android/settings/notification/app/BlockPreferenceController.java b/src/com/android/settings/notification/app/BlockPreferenceController.java
index 37563c0..f55ea8c 100644
--- a/src/com/android/settings/notification/app/BlockPreferenceController.java
+++ b/src/com/android/settings/notification/app/BlockPreferenceController.java
@@ -137,7 +137,7 @@
} else {
fieldContextName = mAppRow.label;
}
- return mContext.getString(R.string.notification_switch_label, fieldContextName);
+ return mContext.getString(R.string.notification_app_switch_label, fieldContextName);
}
}
}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java
index eda3204..c17bacd 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java
@@ -23,10 +23,13 @@
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
+
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
+
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
import java.util.List;
/**
@@ -39,16 +42,7 @@
final static String EXTRA_APP_NAME = "com.android.settings.wifi.extra.APP_NAME";
NetworkRequestDialogActivity mActivity = null;
-
- protected String getTitle() {
- final Intent intent = getActivity().getIntent();
- String appName = "";
- if (intent != null) {
- appName = intent.getStringExtra(EXTRA_APP_NAME);
- }
-
- return getString(R.string.network_connection_request_dialog_title, appName);
- }
+ private String mAppName = "";
@Override
public int getMetricsCategory() {
@@ -61,6 +55,11 @@
if (context instanceof NetworkRequestDialogActivity) {
mActivity = (NetworkRequestDialogActivity) context;
}
+
+ final Intent intent = getActivity().getIntent();
+ if (intent != null) {
+ mAppName = intent.getStringExtra(EXTRA_APP_NAME);
+ }
}
@Override
@@ -78,6 +77,14 @@
}
}
+ protected String getTitle() {
+ return getString(R.string.network_connection_request_dialog_title);
+ }
+
+ protected String getSummary() {
+ return getString(R.string.network_connection_request_dialog_summary, mAppName);
+ }
+
protected void onUserSelectionCallbackRegistration(
NetworkRequestUserSelectionCallback userSelectionCallback) {
}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index ee032ed..edaa4d9 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -86,6 +86,8 @@
final TextView title = customTitle.findViewById(R.id.network_request_title_text);
title.setText(getTitle());
+ final TextView summary = customTitle.findViewById(R.id.network_request_summary_text);
+ summary.setText(getSummary());
final ProgressBar progressBar = customTitle.findViewById(
R.id.network_request_title_progress);
diff --git a/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java
index 7a0ccbe..ec91927 100644
--- a/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java
@@ -7,7 +7,9 @@
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
+
import androidx.appcompat.app.AlertDialog;
+
import com.android.settings.R;
/**
@@ -33,6 +35,8 @@
final View customTitle = inflater.inflate(R.layout.network_request_dialog_title, null);
final TextView title = customTitle.findViewById(R.id.network_request_title_text);
title.setText(getTitle());
+ final TextView summary = customTitle.findViewById(R.id.network_request_summary_text);
+ summary.setText(getSummary());
final ProgressBar progressBar = customTitle
.findViewById(R.id.network_request_title_progress);
progressBar.setVisibility(View.GONE);
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
index 65395a0..b22b156 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
@@ -49,6 +49,7 @@
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.testutils.shadow.ShadowAccountManager;
import com.android.settings.testutils.shadow.ShadowContentResolver;
+import com.android.settings.testutils.shadow.ShadowSettingsLibUtils;
import com.android.settingslib.search.SearchIndexableRaw;
import org.junit.After;
@@ -67,7 +68,8 @@
import java.util.List;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class,
+ ShadowSettingsLibUtils.class})
public class AccountPreferenceControllerTest {
@Mock(answer = RETURNS_DEEP_STUBS)
@@ -95,7 +97,7 @@
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mAccountManager.getAuthenticatorTypesAsUser(anyInt()))
- .thenReturn(new AuthenticatorDescription[0]);
+ .thenReturn(new AuthenticatorDescription[0]);
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
mController = new AccountPreferenceController(mContext, mFragment, null, mAccountHelper,
ProfileSelectFragment.ProfileType.ALL);
@@ -341,8 +343,8 @@
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
Account[] accountType1 = {
- new Account("Account11", "com.acct1"),
- new Account("Account12", "com.acct1")
+ new Account("Account11", "com.acct1"),
+ new Account("Account12", "com.acct1")
};
when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
.thenReturn(accountType1);
@@ -535,8 +537,8 @@
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
Account[] accountType1 = {
- new Account("Acct11", "com.acct1"),
- new Account("Acct12", "com.acct1")
+ new Account("Acct11", "com.acct1"),
+ new Account("Acct12", "com.acct1")
};
when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
.thenReturn(accountType1);
@@ -555,7 +557,7 @@
mController.onResume();
// remove an account
- accountType1 = new Account[] {new Account("Acct11", "com.acct1")};
+ accountType1 = new Account[]{new Account("Acct11", "com.acct1")};
when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
.thenReturn(accountType1);
@@ -577,19 +579,19 @@
Account[] accounts = {new Account("Acct1", "com.acct1")};
when(mAccountManager.getAccountsAsUser(1)).thenReturn(accounts);
when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
- .thenReturn(accounts);
+ .thenReturn(accounts);
AuthenticatorDescription[] authDescs = {
- new AuthenticatorDescription("com.acct1", "com.android.settings",
- R.string.account_settings_title, 0 /* iconId */, 0 /* smallIconId */,
- 0 /* prefId */, false /* customTokens */)
+ new AuthenticatorDescription("com.acct1", "com.android.settings",
+ R.string.account_settings_title, 0 /* iconId */, 0 /* smallIconId */,
+ 0 /* prefId */, false /* customTokens */)
};
when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class)))
- .thenReturn(preferenceGroup);
+ .thenReturn(preferenceGroup);
// First time resume will build the UI with no account
mController.onResume();
diff --git a/tests/robotests/src/com/android/settings/development/QuickSettingsMediaPlayerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/QuickSettingsMediaPlayerPreferenceControllerTest.java
new file mode 100644
index 0000000..10eed2f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/QuickSettingsMediaPlayerPreferenceControllerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 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.development;
+
+import static com.android.settings.development.QuickSettingsMediaPlayerPreferenceController.SETTING_NAME;
+import static com.android.settings.development.QuickSettingsMediaPlayerPreferenceController.SETTING_VALUE_OFF;
+import static com.android.settings.development.QuickSettingsMediaPlayerPreferenceController.SETTING_VALUE_ON;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public class QuickSettingsMediaPlayerPreferenceControllerTest {
+ @Mock
+ private SwitchPreference mPreference;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ @Rule
+ public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ private Context mContext;
+ private QuickSettingsMediaPlayerPreferenceController mController;
+
+ @Before
+ public void setup() {
+ mContext = RuntimeEnvironment.application;
+ mController = new QuickSettingsMediaPlayerPreferenceController(mContext);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+ .thenReturn(mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void onPreferenceChanged_turnOnPreference_shouldEnable() {
+ mController.onPreferenceChange(mPreference, true /* new value */);
+
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ SETTING_NAME, -1 /* default */);
+
+ assertThat(mode).isEqualTo(SETTING_VALUE_ON);
+ }
+
+ @Test
+ public void onPreferenceChanged_turnOffPreference_shouldDisable() {
+ mController.onPreferenceChange(mPreference, false /* new value */);
+
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ SETTING_NAME, -1 /* default */);
+
+ assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
+ }
+
+ @Test
+ public void updateState_settingEnabled_preferenceShouldBeChecked() {
+ Settings.Global.putInt(mContext.getContentResolver(), SETTING_NAME, SETTING_VALUE_ON);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
+ Settings.Global.putInt(mContext.getContentResolver(), SETTING_NAME, SETTING_VALUE_OFF);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void onDeveloperOptionsSwitchDisabled_shouldDisable() {
+ mController.onDeveloperOptionsSwitchDisabled();
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ SETTING_NAME, -1 /* default */);
+
+ assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
+ verify(mPreference).setEnabled(false);
+ verify(mPreference).setChecked(false);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java b/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java
index 8014e56..e8f7027 100644
--- a/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java
@@ -31,6 +31,7 @@
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaRoute2ProviderService;
+import android.media.RoutingSessionInfo;
import android.net.Uri;
import com.android.settings.testutils.shadow.ShadowAudioManager;
@@ -191,4 +192,21 @@
verify(mResolver, never()).notifyChange(URI, null);
}
+
+ @Test
+ public void getActiveRemoteMediaSession_verifyList() {
+ mMediaDeviceUpdateWorker.mLocalMediaManager = mock(LocalMediaManager.class);
+ final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+ final RoutingSessionInfo remoteSessionInfo = mock(RoutingSessionInfo.class);
+ final RoutingSessionInfo localSessionInfo = mock(RoutingSessionInfo.class);
+ when(remoteSessionInfo.isSystemSession()).thenReturn(false);
+ when(localSessionInfo.isSystemSession()).thenReturn(true);
+ routingSessionInfos.add(remoteSessionInfo);
+ routingSessionInfos.add(localSessionInfo);
+ when(mMediaDeviceUpdateWorker.mLocalMediaManager.getActiveMediaSession()).thenReturn(
+ routingSessionInfos);
+
+ assertThat(mMediaDeviceUpdateWorker.getActiveRemoteMediaDevice()).containsExactly(
+ remoteSessionInfo);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/media/RemoteMediaSliceTest.java b/tests/robotests/src/com/android/settings/media/RemoteMediaSliceTest.java
index b719a9e..017faa5 100644
--- a/tests/robotests/src/com/android/settings/media/RemoteMediaSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/RemoteMediaSliceTest.java
@@ -24,7 +24,7 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -32,6 +32,7 @@
import android.content.Context;
import android.content.Intent;
+import android.media.RoutingSessionInfo;
import android.net.Uri;
import androidx.slice.Slice;
@@ -43,7 +44,6 @@
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settingslib.media.LocalMediaManager;
-import com.android.settingslib.media.MediaDevice;
import org.junit.Before;
import org.junit.Test;
@@ -64,19 +64,16 @@
public class RemoteMediaSliceTest {
private static final String MEDIA_ID = "media_id";
- private static final String TEST_PACKAGE_LABEL = "music";
- private static final String TEST_DEVICE_1_ID = "test_device_1_id";
- private static final String TEST_DEVICE_1_NAME = "test_device_1_name";
+ private static final String TEST_SESSION_1_ID = "test_session_1_id";
+ private static final String TEST_SESSION_1_NAME = "test_session_1_name";
private static final int TEST_VOLUME = 3;
private static MediaDeviceUpdateWorker sMediaDeviceUpdateWorker;
@Mock
private LocalMediaManager mLocalMediaManager;
- @Mock
- private MediaDevice mDevice;
- private final List<MediaDevice> mDevices = new ArrayList<>();
+ private final List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
private Context mContext;
private RemoteMediaSlice mRemoteMediaSlice;
@@ -93,44 +90,42 @@
sMediaDeviceUpdateWorker = spy(new MediaDeviceUpdateWorker(mContext,
REMOTE_MEDIA_SLICE_URI));
sMediaDeviceUpdateWorker.mLocalMediaManager = mLocalMediaManager;
- when(sMediaDeviceUpdateWorker.getActiveMediaDevice(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE)).thenReturn(mDevices);
- when(mDevice.getId()).thenReturn(TEST_DEVICE_1_ID);
- when(mDevice.getName()).thenReturn(TEST_DEVICE_1_NAME);
- when(mDevice.getMaxVolume()).thenReturn(100);
- when(mDevice.getCurrentVolume()).thenReturn(10);
- when(mDevice.getClientAppLabel()).thenReturn(TEST_PACKAGE_LABEL);
+ final RoutingSessionInfo remoteSessionInfo = mock(RoutingSessionInfo.class);
+ when(remoteSessionInfo.getId()).thenReturn(TEST_SESSION_1_ID);
+ when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME);
+ when(remoteSessionInfo.getVolumeMax()).thenReturn(100);
+ when(remoteSessionInfo.getVolume()).thenReturn(10);
+ when(remoteSessionInfo.isSystemSession()).thenReturn(false);
+ mRoutingSessionInfos.add(remoteSessionInfo);
+ when(sMediaDeviceUpdateWorker.getActiveRemoteMediaDevice()).thenReturn(
+ mRoutingSessionInfos);
}
@Test
public void onNotifyChange_noId_doNothing() {
- mDevices.add(mDevice);
- when(mLocalMediaManager.getMediaDeviceById(mDevices, TEST_DEVICE_1_ID)).thenReturn(mDevice);
- sMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
final Intent intent = new Intent();
intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME);
mRemoteMediaSlice.onNotifyChange(intent);
- verify(mDevice, never()).requestSetVolume(anyInt());
+ verify(sMediaDeviceUpdateWorker, never())
+ .adjustSessionVolume(TEST_SESSION_1_ID, TEST_VOLUME);
}
@Test
public void onNotifyChange_verifyAdjustVolume() {
- mDevices.add(mDevice);
- when(mLocalMediaManager.getMediaDeviceById(mDevices, TEST_DEVICE_1_ID)).thenReturn(mDevice);
- sMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
final Intent intent = new Intent();
- intent.putExtra(MEDIA_ID, TEST_DEVICE_1_ID);
+ intent.putExtra(MEDIA_ID, TEST_SESSION_1_ID);
intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME);
mRemoteMediaSlice.onNotifyChange(intent);
- verify(mDevice).requestSetVolume(TEST_VOLUME);
+ verify(sMediaDeviceUpdateWorker).adjustSessionVolume(TEST_SESSION_1_ID, TEST_VOLUME);
}
@Test
- public void getSlice_noActiveDevice_checkRowNumber() {
+ public void getSlice_noActiveSession_checkRowNumber() {
+ mRoutingSessionInfos.clear();
final Slice slice = mRemoteMediaSlice.getSlice();
final int rows = SliceQuery.findAll(slice, FORMAT_SLICE, HINT_LIST_ITEM, null).size();
@@ -138,8 +133,7 @@
}
@Test
- public void getSlice_withActiveDevice_checkRowNumber() {
- mDevices.add(mDevice);
+ public void getSlice_withActiveSession_checkRowNumber() {
final Slice slice = mRemoteMediaSlice.getSlice();
final int rows = SliceQuery.findAll(slice, FORMAT_SLICE, HINT_LIST_ITEM, null).size();
@@ -148,15 +142,13 @@
}
@Test
- public void getSlice_withActiveDevice_checkTitle() {
- mDevices.add(mDevice);
+ public void getSlice_withActiveSession_checkTitle() {
final Slice slice = mRemoteMediaSlice.getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
final SliceAction primaryAction = metadata.getPrimaryAction();
assertThat(primaryAction.getTitle().toString()).isEqualTo(mContext.getText(
- com.android.settings.R.string.remote_media_volume_option_title)
- + " (" + TEST_PACKAGE_LABEL + ")");
+ com.android.settings.R.string.remote_media_volume_option_title));
}
@Implements(SliceBackgroundWorker.class)
diff --git a/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java b/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java
index d81f30f..9e140ce 100644
--- a/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java
@@ -21,11 +21,13 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.SharedPreferences;
+import android.media.RoutingSessionInfo;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -36,7 +38,6 @@
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.media.LocalMediaManager;
-import com.android.settingslib.media.MediaDevice;
import org.junit.Before;
import org.junit.Test;
@@ -55,24 +56,21 @@
public class RemoteVolumeGroupControllerTest {
private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group";
- private static final String TEST_PACKAGE_LABEL = "music";
- private static final String TEST_DEVICE_1_ID = "test_device_1_id";
- private static final String TEST_DEVICE_1_NAME = "test_device_1_name";
+ private static final String TEST_SESSION_1_ID = "test_session_1_id";
+ private static final String TEST_SESSION_1_NAME = "test_session_1_name";
private static final int CURRENT_VOLUME = 30;
private static final int MAX_VOLUME = 100;
@Mock
private LocalMediaManager mLocalMediaManager;
@Mock
- private MediaDevice mDevice;
- @Mock
private PreferenceScreen mScreen;
@Mock
private PreferenceManager mPreferenceManager;
@Mock
private SharedPreferences mSharedPreferences;
- private final List<MediaDevice> mDevices = new ArrayList<>();
+ private final List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
private Context mContext;
private RemoteVolumeGroupController mController;
@@ -89,92 +87,88 @@
when(mPreferenceCategory.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mPreferenceManager.getSharedPreferences()).thenReturn(mSharedPreferences);
- when(mLocalMediaManager.getActiveMediaDevice(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE)).thenReturn(mDevices);
- when(mDevice.getId()).thenReturn(TEST_DEVICE_1_ID);
- when(mDevice.getName()).thenReturn(TEST_DEVICE_1_NAME);
- when(mDevice.getMaxVolume()).thenReturn(MAX_VOLUME);
- when(mDevice.getCurrentVolume()).thenReturn(CURRENT_VOLUME);
- when(mDevice.getClientAppLabel()).thenReturn(TEST_PACKAGE_LABEL);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(
mPreferenceCategory);
+ final RoutingSessionInfo remoteSessionInfo = mock(RoutingSessionInfo.class);
+ when(remoteSessionInfo.getId()).thenReturn(TEST_SESSION_1_ID);
+ when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME);
+ when(remoteSessionInfo.getVolumeMax()).thenReturn(MAX_VOLUME);
+ when(remoteSessionInfo.getVolume()).thenReturn(CURRENT_VOLUME);
+ when(remoteSessionInfo.isSystemSession()).thenReturn(false);
+ mRoutingSessionInfos.add(remoteSessionInfo);
+ when(mLocalMediaManager.getActiveMediaSession()).thenReturn(mRoutingSessionInfos);
}
@Test
- public void getAvailabilityStatus_withActiveDevice_returnAvailableUnsearchable() {
- mDevices.add(mDevice);
+ public void getAvailabilityStatus_withActiveSession_returnAvailableUnsearchable() {
mController.displayPreference(mScreen);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
- public void getAvailabilityStatus_noActiveDevice_returnConditionallyUnavailable() {
+ public void getAvailabilityStatus_noActiveSession_returnConditionallyUnavailable() {
+ mRoutingSessionInfos.clear();
mController.displayPreference(mScreen);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
- public void displayPreference_noActiveDevice_checkPreferenceCount() {
+ public void displayPreference_noActiveSession_checkPreferenceCount() {
+ mRoutingSessionInfos.clear();
mController.displayPreference(mScreen);
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(0);
}
@Test
- public void displayPreference_withActiveDevice_checkPreferenceCount() {
- mDevices.add(mDevice);
+ public void displayPreference_withActiveSession_checkPreferenceCount() {
mController.displayPreference(mScreen);
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
}
@Test
- public void displayPreference_withActiveDevice_checkSeekBarTitle() {
- mDevices.add(mDevice);
+ public void displayPreference_withActiveSession_checkSeekBarTitle() {
mController.displayPreference(mScreen);
- final Preference preference = mPreferenceCategory.findPreference(TEST_DEVICE_1_ID);
+ final Preference preference = mPreferenceCategory.findPreference(TEST_SESSION_1_ID);
assertThat(preference.getTitle()).isEqualTo(mContext.getText(
- R.string.remote_media_volume_option_title) + " (" + TEST_PACKAGE_LABEL + ")");
+ R.string.remote_media_volume_option_title));
}
@Test
- public void displayPreference_withActiveDevice_checkSeekBarMaxVolume() {
- mDevices.add(mDevice);
+ public void displayPreference_withActiveSession_checkSeekBarMaxVolume() {
mController.displayPreference(mScreen);
- final SeekBarPreference preference = mPreferenceCategory.findPreference(TEST_DEVICE_1_ID);
+ final SeekBarPreference preference = mPreferenceCategory.findPreference(TEST_SESSION_1_ID);
assertThat(preference.getMax()).isEqualTo(MAX_VOLUME);
}
@Test
- public void displayPreference_withActiveDevice_checkSeekBarCurrentVolume() {
- mDevices.add(mDevice);
+ public void displayPreference_withActiveSession_checkSeekBarCurrentVolume() {
mController.displayPreference(mScreen);
- final SeekBarPreference preference = mPreferenceCategory.findPreference(TEST_DEVICE_1_ID);
+ final SeekBarPreference preference = mPreferenceCategory.findPreference(TEST_SESSION_1_ID);
assertThat(preference.getProgress()).isEqualTo(CURRENT_VOLUME);
}
@Test
- public void displayPreference_withActiveDevice_checkSwitcherPreferenceTitle() {
- mDevices.add(mDevice);
+ public void displayPreference_withActiveSession_checkSwitcherPreferenceTitle() {
mController.displayPreference(mScreen);
final Preference preference = mPreferenceCategory.findPreference(
- RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_DEVICE_1_ID);
+ RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_SESSION_1_ID);
assertThat(preference.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title));
}
@Test
- public void displayPreference_withActiveDevice_checkSwitcherPreferenceSummary() {
- mDevices.add(mDevice);
+ public void displayPreference_withActiveSession_checkSwitcherPreferenceSummary() {
mController.displayPreference(mScreen);
final Preference preference = mPreferenceCategory.findPreference(
- RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_DEVICE_1_ID);
+ RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_SESSION_1_ID);
- assertThat(preference.getSummary()).isEqualTo(TEST_DEVICE_1_NAME);
+ assertThat(preference.getSummary()).isEqualTo(TEST_SESSION_1_NAME);
}
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsLibUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsLibUtils.java
index 2fce5ad..8f4b786 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsLibUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSettingsLibUtils.java
@@ -20,6 +20,7 @@
import android.content.pm.ApplicationInfo;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import com.android.settingslib.Utils;
@@ -30,6 +31,11 @@
public class ShadowSettingsLibUtils {
@Implementation
+ protected static Drawable getBadgedIcon(Context context, Drawable icon, UserHandle user) {
+ return new ColorDrawable(0);
+ }
+
+ @Implementation
protected static Drawable getBadgedIcon(Context context, ApplicationInfo appInfo) {
return new ColorDrawable(0);
}