diff --git a/res/layout/network_request_dialog_title.xml b/res/layout/network_request_dialog_title.xml
index b61a7db4d23..4385a883e30 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">
-
+
-
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 18673e490c5..e3335e45361 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8470,7 +8470,7 @@
Priority
- Shows at top of conversation section and appears as a bubble.
+ Shows at top of conversation section and appears as a bubble
%1$s does not support conversation-specific settings.
@@ -8491,6 +8491,9 @@
All \"%1$s\" notifications
+
+ All %1$s notifications
+
Adaptive Notifications
@@ -11736,7 +11739,12 @@
See less
- Device to use with %1$s
+ Connect to device
+
+
+ %1$s
+ app wants to use a temporary Wi\u2011Fi network to connect to your device
+
No devices found. Make sure devices are turned on and available to connect.
@@ -11795,6 +11803,11 @@
Permissions, account activity, personal data
+
+ Media resumption
+
+ Shows and persists media player in Quick Settings. Requires reboot.
+
Remove
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 6dcc125fe1c..39a130cf750 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -525,6 +525,11 @@
android:title="@string/usb_audio_disable_routing"
android:summary="@string/usb_audio_disable_routing_summary" />
+
+
getActiveMediaDevice(@MediaDevice.MediaDeviceType int type) {
- return mLocalMediaManager.getActiveMediaDevice(type);
+ List getActiveRemoteMediaDevice() {
+ final List 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 4e442b77a6b..71a41b36964 100644
--- a/src/com/android/settings/media/RemoteMediaSlice.java
+++ b/src/com/android/settings/media/RemoteMediaSlice.java
@@ -24,6 +24,7 @@ import android.app.PendingIntent;
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.CustomSliceable;
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 @@ public class RemoteMediaSlice implements CustomSliceable {
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 @@ public class RemoteMediaSlice implements CustomSliceable {
return listBuilder.build();
}
// Only displaying remote devices
- final List mediaDevices = getWorker().getActiveMediaDevice(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
- if (mediaDevices.isEmpty()) {
+ final List infos = getWorker().getActiveRemoteMediaDevice();
+ if (infos.isEmpty()) {
Log.d(TAG, "No active remote media device");
return listBuilder.build();
}
@@ -93,27 +92,25 @@ public class RemoteMediaSlice implements CustomSliceable {
// 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 @@ public class RemoteMediaSlice implements CustomSliceable {
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 99dfd55415b..3d150258418 100644
--- a/src/com/android/settings/network/ActiveSubsciptionsListener.java
+++ b/src/com/android/settings/network/ActiveSubsciptionsListener.java
@@ -73,6 +73,7 @@ public abstract class ActiveSubsciptionsListener
* @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 0306b55abd6..a89cc83d75f 100644
--- a/src/com/android/settings/network/ProxySubscriptionManager.java
+++ b/src/com/android/settings/network/ProxySubscriptionManager.java
@@ -72,7 +72,7 @@ public class ProxySubscriptionManager implements LifecycleObserver {
private static ProxySubscriptionManager sSingleton;
private ProxySubscriptionManager(Context context) {
- final Looper looper = Looper.getMainLooper();
+ final Looper looper = context.getMainLooper();
mActiveSubscriptionsListeners =
new ArrayList();
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 00000000000..889fbaec4e9
--- /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 getPreferenceControllersAsList() {
+ final List result =
+ new ArrayList();
+ getPreferenceControllers().forEach(controllers -> result.addAll(controllers));
+ return result;
+ }
+
+ TelephonyStatusControlSession setTelephonyAvailabilityStatus(
+ Collection 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 dd681290fc8..8442de2a9b4 100644
--- a/src/com/android/settings/network/telephony/ApnPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ApnPreferenceController.java
@@ -93,6 +93,9 @@ public class ApnPreferenceController extends TelephonyBasePreferenceController i
@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/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index 650890e434e..779802a22ac 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.Preference;
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 @@ import java.util.List;
* 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 @@ public abstract class DefaultSubscriptionController extends BasePreferenceContro
protected abstract void setDefaultSubscription(int subscriptionId);
@Override
- public int getAvailabilityStatus() {
+ public int getAvailabilityStatus(int subId) {
final List 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 f5bcce79f42..d14c8d09e44 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.content.Context;
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 5343709208e..d5a192a5456 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -61,19 +61,6 @@ public class EnabledNetworkModePreferenceController extends
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 @@ public class EnabledNetworkModePreferenceController extends
@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 @@ public class EnabledNetworkModePreferenceController extends
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 3a91616a3c6..91d01d36a1d 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
@@ -69,10 +69,13 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc
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 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc
@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 54fe2c16eef..754dd058c72 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.Preference;
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.network.telephony.gsm.OpenNetworkSelectPagePreferenc
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 class MobileNetworkSettings extends RestrictedDashboardFragment {
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 class MobileNetworkSettings extends RestrictedDashboardFragment {
public void onCreate(Bundle icicle) {
Log.i(LOG_TAG, "onCreate:+");
- final Collection> controllerLists =
- getPreferenceControllers();
- final Future result = ThreadUtils.postOnBackgroundThread(() ->
- setupAvailabilityStatus(controllerLists)
- );
+ final TelephonyStatusControlSession session =
+ setTelephonyAvailabilityStatus(getPreferenceControllersAsList());
super.onCreate(icicle);
final Context context = getContext();
@@ -201,46 +197,11 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment {
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> 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> 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 584848f842e..dd236c55a67 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -217,16 +217,13 @@ public class NetworkSelectSettings extends DashboardFragment {
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 results = (List) msg.obj;
diff --git a/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java b/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java
index 50dd26bc1b5..c1acd91667e 100644
--- a/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java
+++ b/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java
@@ -25,14 +25,16 @@ import android.content.Context;
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 678209d9358..2bd7de9d500 100644
--- a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
@@ -23,7 +23,6 @@ import android.telephony.SubscriptionManager;
import com.android.settings.core.BasePreferenceController;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -33,7 +32,7 @@ public abstract class TelephonyBasePreferenceController extends BasePreferenceCo
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 @@ public abstract class TelephonyBasePreferenceController extends BasePreferenceCo
@Override
public int getAvailabilityStatus() {
- if (!mUnsetAvailabilityStatus.get()) {
+ if (mSetSessionCount.get() <= 0) {
mAvailabilityStatus.set(MobileNetworkUtils
.getAvailability(mContext, mSubId, this::getAvailabilityStatus));
}
@@ -52,11 +51,12 @@ public abstract class TelephonyBasePreferenceController extends BasePreferenceCo
@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 00000000000..12c9beeef67
--- /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 mControllers;
+ private Future mResult;
+
+ /**
+ * Buider of session
+ */
+ public static class Builder {
+ private Collection mControllers;
+
+ /**
+ * Constructor
+ *
+ * @param controllers is a collection of {@link AbstractPreferenceController}
+ * which would have {@link BasePreferenceController#availabilityStatus()}
+ * under control within this session.
+ */
+ public Builder(Collection controllers) {
+ mControllers = controllers;
+ }
+
+ /**
+ * Method to build this session.
+ * @return {@link TelephonyStatusControlSession} session been setup.
+ */
+ public TelephonyStatusControlSession build() {
+ return new TelephonyStatusControlSession(mControllers);
+ }
+ }
+
+ private TelephonyStatusControlSession(Collection 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 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 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 56d51eb3809..84aa0cb065a 100644
--- a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java
+++ b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java
@@ -23,7 +23,6 @@ import android.telephony.SubscriptionManager;
import com.android.settings.core.TogglePreferenceController;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -33,8 +32,7 @@ public abstract class TelephonyTogglePreferenceController extends TogglePreferen
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 @@ public abstract class TelephonyTogglePreferenceController extends TogglePreferen
@Override
public int getAvailabilityStatus() {
- if (!mUnsetAvailabilityStatus.get()) {
+ if (mSetSessionCount.get() <= 0) {
mAvailabilityStatus.set(MobileNetworkUtils
.getAvailability(mContext, mSubId, this::getAvailabilityStatus));
}
@@ -53,11 +51,12 @@ public abstract class TelephonyTogglePreferenceController extends TogglePreferen
@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 c36035aa20e..137f7803d8b 100644
--- a/src/com/android/settings/notification/RemoteVolumeGroupController.java
+++ b/src/com/android/settings/notification/RemoteVolumeGroupController.java
@@ -18,6 +18,8 @@ package com.android.settings.notification;
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 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
static final String SWITCHER_PREFIX = "OUTPUT_SWITCHER";
private PreferenceCategory mPreferenceCategory;
- private List mActiveRemoteMediaDevices = new ArrayList<>();
+ private List mRoutingSessionInfos = new ArrayList<>();
@VisibleForTesting
LocalMediaManager mLocalMediaManager;
@@ -67,7 +69,7 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
@Override
public int getAvailabilityStatus() {
- if (mActiveRemoteMediaDevices.isEmpty()) {
+ if (mRoutingSessionInfos.isEmpty()) {
return CONDITIONALLY_UNAVAILABLE;
}
return AVAILABLE_UNSEARCHABLE;
@@ -77,12 +79,19 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
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 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
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 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
return false;
}
ThreadUtils.postOnBackgroundThread(() -> {
- device.requestSetVolume((int) newValue);
+ mLocalMediaManager.adjustSessionVolume(preference.getKey(), (int) newValue);
});
return true;
}
@@ -145,18 +154,19 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
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 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
// 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 37563c0905a..f55ea8c609b 100644
--- a/src/com/android/settings/notification/app/BlockPreferenceController.java
+++ b/src/com/android/settings/notification/app/BlockPreferenceController.java
@@ -137,7 +137,7 @@ public class BlockPreferenceController extends NotificationPreferenceController
} 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 eda3204a715..c17bacdc9f7 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java
@@ -23,10 +23,13 @@ import android.content.Intent;
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 @@ abstract public class NetworkRequestDialogBaseFragment extends InstrumentedDialo
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 @@ abstract public class NetworkRequestDialogBaseFragment extends InstrumentedDialo
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 @@ abstract public class NetworkRequestDialogBaseFragment extends InstrumentedDialo
}
}
+ 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 ee032ede6c0..edaa4d913dc 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -86,6 +86,8 @@ public class NetworkRequestDialogFragment extends NetworkRequestDialogBaseFragme
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 7a0ccbea58a..ec919276f6c 100644
--- a/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java
@@ -7,7 +7,9 @@ import android.view.LayoutInflater;
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 @@ public class NetworkRequestSingleSsidDialogFragment extends
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 65395a0b632..b22b1562be2 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.SettingsPreferenceFragment;
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.ArrayList;
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 @@ public class AccountPreferenceControllerTest {
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 @@ public class AccountPreferenceControllerTest {
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 @@ public class AccountPreferenceControllerTest {
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 @@ public class AccountPreferenceControllerTest {
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 @@ public class AccountPreferenceControllerTest {
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 00000000000..10eed2fcbc5
--- /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 8014e5639b3..e8f70271487 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.Context;
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 @@ public class MediaDeviceUpdateWorkerTest {
verify(mResolver, never()).notifyChange(URI, null);
}
+
+ @Test
+ public void getActiveRemoteMediaSession_verifyList() {
+ mMediaDeviceUpdateWorker.mLocalMediaManager = mock(LocalMediaManager.class);
+ final List 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 b719a9e8f93..017faa5568f 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.android.settings.slices.CustomSliceRegistry.REMOTE_MEDIA_SLICE
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 static org.mockito.Mockito.when;
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 androidx.slice.widget.SliceLiveData;
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 @@ import java.util.List;
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 mDevices = new ArrayList<>();
+ private final List mRoutingSessionInfos = new ArrayList<>();
private Context mContext;
private RemoteMediaSlice mRemoteMediaSlice;
@@ -93,44 +90,42 @@ public class RemoteMediaSliceTest {
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 @@ public class RemoteMediaSliceTest {
}
@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 @@ public class RemoteMediaSliceTest {
}
@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 d81f30fc6b0..9e140ce3b4e 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.android.settings.core.BasePreferenceController.CONDITIONALLY_U
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.R;
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 @@ import java.util.List;
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 mDevices = new ArrayList<>();
+ private final List mRoutingSessionInfos = new ArrayList<>();
private Context mContext;
private RemoteVolumeGroupController mController;
@@ -89,92 +87,88 @@ public class RemoteVolumeGroupControllerTest {
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 2fce5ad80fb..8f4b7866699 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.Context;
import android.content.pm.ApplicationInfo;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import com.android.settingslib.Utils;
@@ -29,6 +30,11 @@ import org.robolectric.annotation.Implements;
@Implements(Utils.class)
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);