[Settings] Apply proxy design to data usage

Enable proxy to subscription manager in data usage UI.

Bug: 141833767
Test: manual
make RunSettingsRoboTests -j ROBOTEST_FILTER=BillingCyclePreferenceTest
make RunSettingsRoboTests -j ROBOTEST_FILTER=CellDataPreferenceTest
make RunSettingsRoboTests -j ROBOTEST_FILTER=DataUsageListTest
make RunSettingsRoboTests -j ROBOTEST_FILTER=DataUsageSummaryTest
make RunSettingsRoboTests -j ROBOTEST_FILTER=DataUsageUtilsTest
make RunSettingsRoboTests -j ROBOTEST_FILTER=MobileDataEnabledListenerTest

Change-Id: Id119738dc16ece8767c088b9a0794997e4b0334f
This commit is contained in:
Bonian Chen
2019-11-08 07:40:35 +08:00
parent adfdb0ddf1
commit 5e65da0c2f
12 changed files with 285 additions and 191 deletions

View File

@@ -85,6 +85,7 @@ public abstract class ActiveSubsciptionsListener
@VisibleForTesting
BroadcastReceiver mSubscriptionChangeReceiver;
private Integer mMaxActiveSubscriptionInfos;
private List<SubscriptionInfo> mCachedActiveSubscriptionInfo;
/**
@@ -125,6 +126,24 @@ public abstract class ActiveSubsciptionsListener
return mSubscriptionManager;
}
/**
* Get current max. number active subscription info(s) been setup within device
*
* @return max. number of active subscription info(s)
*/
public int getActiveSubscriptionInfoCountMax() {
int count = 0;
if (mMaxActiveSubscriptionInfos == null) {
count = getSubscriptionManager().getActiveSubscriptionInfoCountMax();
if (mIsMonitoringDataChange) {
mMaxActiveSubscriptionInfos = count;
}
} else {
count = mMaxActiveSubscriptionInfos.intValue();
}
return count;
}
/**
* Get a list of active subscription info
*
@@ -134,7 +153,7 @@ public abstract class ActiveSubsciptionsListener
if (mIsCachedDataAvailable) {
return mCachedActiveSubscriptionInfo;
}
mIsCachedDataAvailable = true;
mIsCachedDataAvailable = mIsMonitoringDataChange;
mCachedActiveSubscriptionInfo = getSubscriptionManager().getActiveSubscriptionInfoList();
return mCachedActiveSubscriptionInfo;
}
@@ -163,6 +182,7 @@ public abstract class ActiveSubsciptionsListener
*/
public void clearCache() {
mIsCachedDataAvailable = false;
mMaxActiveSubscriptionInfos = null;
mCachedActiveSubscriptionInfo = null;
}

View File

@@ -33,7 +33,8 @@ import androidx.lifecycle.OnLifecycleEvent;
/**
* A listener for Settings.Global configuration change, with support of Lifecycle
*/
abstract class GlobalSettingsChangeListener extends ContentObserver implements LifecycleObserver {
public abstract class GlobalSettingsChangeListener extends ContentObserver
implements LifecycleObserver, AutoCloseable {
/**
* Constructor
@@ -41,7 +42,7 @@ abstract class GlobalSettingsChangeListener extends ContentObserver implements L
* @param context of this listener
* @param field field of Global Settings
*/
GlobalSettingsChangeListener(Context context, String field) {
public GlobalSettingsChangeListener(Context context, String field) {
super(new Handler());
mContext = context;
mField = field;
@@ -92,6 +93,13 @@ abstract class GlobalSettingsChangeListener extends ContentObserver implements L
@OnLifecycleEvent(ON_DESTROY)
void onDestroy() {
close();
}
/**
* Implementation of AutoCloseable
*/
public void close() {
monitorUri(false);
notifyChangeBasedOn(null);
}

View File

@@ -17,53 +17,98 @@
package com.android.settings.network;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
/** Helper class to listen for changes in the enabled state of mobile data. */
public class MobileDataEnabledListener extends ContentObserver {
public class MobileDataEnabledListener {
private Context mContext;
private Client mClient;
private int mSubId;
/**
* There're 2 listeners both activated at the same time.
* For project that access MOBILE_DATA, only first listener is functional.
* For project that access "MOBILE_DATA + subId", first listener will be stopped when receiving
* any onChange from second listener.
*/
private GlobalSettingsChangeListener mListener;
private GlobalSettingsChangeListener mListenerForSubId;
public interface Client {
void onMobileDataEnabledChange();
}
/**
* Constructor
*
* @param context of this listener
* @param client callback when configuration changed
*/
public MobileDataEnabledListener(Context context, Client client) {
super(new Handler());
mContext = context;
mClient = client;
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
/** Starts listening to changes in the enabled state for data on the given subscription id. */
/**
* Starts listening to changes in the enabled state for data on the given subscription id.
*
* @param subId subscription id for enabled state of data subscription
*/
public void start(int subId) {
mSubId = subId;
Uri uri;
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
} else {
uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + mSubId);
if (mListener == null) {
mListener = new GlobalSettingsChangeListener(mContext,
Settings.Global.MOBILE_DATA) {
public void onChanged(String field) {
mClient.onMobileDataEnabledChange();
}
};
}
mContext.getContentResolver().registerContentObserver(uri, true /*notifyForDescendants*/,
this);
stopMonitorSubIdSpecific();
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return;
}
mListenerForSubId = new GlobalSettingsChangeListener(mContext,
Settings.Global.MOBILE_DATA + mSubId) {
public void onChanged(String field) {
stopMonitor();
mClient.onMobileDataEnabledChange();
}
};
}
/**
* Get latest subscription id configured for listening
*
* @return subscription id
*/
public int getSubId() {
return mSubId;
}
public MobileDataEnabledListener stop() {
mContext.getContentResolver().unregisterContentObserver(this);
return this;
/**
* Stop listening to changes in the enabled state for data.
*/
public void stop() {
stopMonitor();
stopMonitorSubIdSpecific();
}
@Override
public void onChange(boolean selfChange) {
mClient.onMobileDataEnabledChange();
private void stopMonitor() {
if (mListener != null) {
mListener.close();
mListener = null;
}
}
private void stopMonitorSubIdSpecific() {
if (mListenerForSubId != null) {
mListenerForSubId.close();
mListenerForSubId = null;
}
}
}

View File

@@ -82,7 +82,6 @@ public class ProxySubscriptionManager extends SubscriptionManager.OnSubscription
}
};
mKeepCacheWhenOnStart = true;
mSubsciptionsMonitor.start();
}
@@ -90,7 +89,6 @@ public class ProxySubscriptionManager extends SubscriptionManager.OnSubscription
private Context mContext;
private ActiveSubsciptionsListener mSubsciptionsMonitor;
private GlobalSettingsChangeListener mAirplaneModeMonitor;
private boolean mKeepCacheWhenOnStart;
private List<OnActiveSubscriptionChangedListener> mActiveSubscriptionsListeners;
@@ -100,6 +98,12 @@ public class ProxySubscriptionManager extends SubscriptionManager.OnSubscription
}
}
@Override
public void onSubscriptionsChanged() {
clearCache();
notifyAllListeners();
}
/**
* Lifecycle for data within proxy
*
@@ -118,15 +122,11 @@ public class ProxySubscriptionManager extends SubscriptionManager.OnSubscription
@OnLifecycleEvent(ON_START)
void onStart() {
if (!mKeepCacheWhenOnStart) {
mSubsciptionsMonitor.clearCache();
}
mSubsciptionsMonitor.start();
}
@OnLifecycleEvent(ON_STOP)
void onStop() {
mKeepCacheWhenOnStart = false;
mSubsciptionsMonitor.stop();
}
@@ -151,6 +151,15 @@ public class ProxySubscriptionManager extends SubscriptionManager.OnSubscription
return mSubsciptionsMonitor.getSubscriptionManager();
}
/**
* Get current max. number active subscription info(s) been setup within device
*
* @return max. number of active subscription info(s)
*/
public int getActiveSubscriptionInfoCountMax() {
return mSubsciptionsMonitor.getActiveSubscriptionInfoCountMax();
}
/**
* Get a list of active subscription info
*
@@ -183,6 +192,9 @@ public class ProxySubscriptionManager extends SubscriptionManager.OnSubscription
* @param listener listener to active subscriptions change
*/
public void addActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) {
if (mActiveSubscriptionsListeners.contains(listener)) {
return;
}
mActiveSubscriptionsListeners.add(listener);
}