Make sure registrants are notified when provisionDataEnabled changes
When DEVICE_PROVISIONED or DEVICE_PROVISIONING_MOBILE_DATA_ENABLED
value change in Settings.Global, make sure DcTracker and
DataEnabledSettings updates isDataEnabled and notify registrants.
Test: unittest
Bug: 112020101
Change-Id: I01a2dce51e0ea7e5481cf65b56070030be286b34
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index 3b856a7..87521b1 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -52,6 +52,10 @@
public static final int REASON_DATA_ENABLED_BY_CARRIER = 4;
+ public static final int REASON_PROVISIONED_CHANGED = 5;
+
+ public static final int REASON_PROVISIONING_DATA_ENABLED_CHANGED = 6;
+
/**
* responds to the setInternalDataEnabled call - used internally to turn off data.
* For example during emergency calls
@@ -69,6 +73,8 @@
*/
private boolean mCarrierDataEnabled = true;
+ private boolean mIsDataEnabled = false;
+
private Phone mPhone = null;
private ContentResolver mResolver = null;
@@ -88,15 +94,14 @@
public DataEnabledSettings(Phone phone) {
mPhone = phone;
mResolver = mPhone.getContext().getContentResolver();
+ updateDataEnabled();
}
public synchronized void setInternalDataEnabled(boolean enabled) {
localLog("InternalDataEnabled", enabled);
- boolean prevDataEnabled = isDataEnabled();
mInternalDataEnabled = enabled;
- if (prevDataEnabled != isDataEnabled()) {
- notifyDataEnabledChanged(!prevDataEnabled, REASON_INTERNAL_DATA_ENABLED);
- }
+
+ updateDataEnabledAndNotify(REASON_INTERNAL_DATA_ENABLED);
}
public synchronized boolean isInternalDataEnabled() {
return mInternalDataEnabled;
@@ -104,14 +109,11 @@
public synchronized void setUserDataEnabled(boolean enabled) {
localLog("UserDataEnabled", enabled);
- boolean prevDataEnabled = isDataEnabled();
-
Settings.Global.putInt(mResolver, getMobileDataSettingName(), enabled ? 1 : 0);
- if (prevDataEnabled != isDataEnabled()) {
- notifyDataEnabledChanged(!prevDataEnabled, REASON_USER_DATA_ENABLED);
- }
+ updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
}
+
public synchronized boolean isUserDataEnabled() {
boolean defaultVal = "true".equalsIgnoreCase(SystemProperties.get(
"ro.com.android.mobiledata", "true"));
@@ -134,33 +136,53 @@
public synchronized void setPolicyDataEnabled(boolean enabled) {
localLog("PolicyDataEnabled", enabled);
- boolean prevDataEnabled = isDataEnabled();
mPolicyDataEnabled = enabled;
- if (prevDataEnabled != isDataEnabled()) {
- notifyDataEnabledChanged(!prevDataEnabled, REASON_POLICY_DATA_ENABLED);
- }
+
+ updateDataEnabledAndNotify(REASON_POLICY_DATA_ENABLED);
}
+
public synchronized boolean isPolicyDataEnabled() {
return mPolicyDataEnabled;
}
public synchronized void setCarrierDataEnabled(boolean enabled) {
localLog("CarrierDataEnabled", enabled);
- boolean prevDataEnabled = isDataEnabled();
mCarrierDataEnabled = enabled;
- if (prevDataEnabled != isDataEnabled()) {
- notifyDataEnabledChanged(!prevDataEnabled, REASON_DATA_ENABLED_BY_CARRIER);
- }
+
+ updateDataEnabledAndNotify(REASON_DATA_ENABLED_BY_CARRIER);
}
+
public synchronized boolean isCarrierDataEnabled() {
return mCarrierDataEnabled;
}
+ public synchronized void updateProvisionedChanged() {
+ updateDataEnabledAndNotify(REASON_PROVISIONED_CHANGED);
+ }
+
+ public synchronized void updateProvisioningDataEnabled() {
+ updateDataEnabledAndNotify(REASON_PROVISIONING_DATA_ENABLED_CHANGED);
+ }
+
public synchronized boolean isDataEnabled() {
+ return mIsDataEnabled;
+ }
+
+ private synchronized void updateDataEnabledAndNotify(int reason) {
+ boolean prevDataEnabled = mIsDataEnabled;
+
+ updateDataEnabled();
+
+ if (prevDataEnabled != mIsDataEnabled) {
+ notifyDataEnabledChanged(!prevDataEnabled, reason);
+ }
+ }
+
+ private synchronized void updateDataEnabled() {
if (isProvisioning()) {
- return isProvisioningDataEnabled();
+ mIsDataEnabled = isProvisioningDataEnabled();
} else {
- return mInternalDataEnabled && isUserDataEnabled()
+ mIsDataEnabled = mInternalDataEnabled && isUserDataEnabled()
&& mPolicyDataEnabled && mCarrierDataEnabled;
}
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 9a682e0..25dcb6a 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -329,7 +329,7 @@
DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
mSettingsObserver.observe(
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
- DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
+ DctConstants.EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE);
}
/**
@@ -864,6 +864,9 @@
}
private void onDeviceProvisionedChange() {
+ mDataEnabledSettings.updateProvisionedChanged();
+ // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
+ // handle the rest from there.
if (isDataEnabled()) {
reevaluateDataConnections();
onTrySetupData(Phone.REASON_DATA_ENABLED);
@@ -872,6 +875,17 @@
}
}
+ private void onDeviceProvisioningDataChange() {
+ mDataEnabledSettings.updateProvisioningDataEnabled();
+ // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
+ // handle the rest from there.
+ if (isDataEnabled()) {
+ reevaluateDataConnections();
+ onTrySetupData(Phone.REASON_DATA_ENABLED);
+ } else {
+ onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
+ }
+ }
public long getSubId() {
return mPhone.getSubId();
@@ -3718,6 +3732,10 @@
onDeviceProvisionedChange();
break;
+ case DctConstants.EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE:
+ onDeviceProvisioningDataChange();
+ break;
+
case DctConstants.EVENT_REDIRECTION_DETECTED:
String url = (String) msg.obj;
log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index ae1a4dd..3dede43 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -29,6 +29,7 @@
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -51,6 +52,7 @@
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.AsyncResult;
+import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
@@ -73,6 +75,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
import android.util.LocalLog;
+import android.util.Pair;
import com.android.internal.R;
import com.android.internal.telephony.DctConstants;
@@ -128,6 +131,7 @@
1 << (TelephonyManager.NETWORK_TYPE_EHRPD - 1);
private static final Uri PREFERAPN_URI = Uri.parse(
Telephony.Carriers.CONTENT_URI + "/preferapn");
+ private static final int DATA_ENABLED_CHANGED = 0;
@Mock
ISub mIsub;
@@ -145,6 +149,8 @@
DataConnection mDataConnection;
@Mock
PackageManagerService mMockPackageManagerInternal;
+ @Mock
+ Handler mHandler;
private DcTracker mDct;
private DcTrackerTestHandler mDcTrackerTestHandler;
@@ -158,6 +164,8 @@
private final ApnSettingContentProvider mApnSettingContentProvider =
new ApnSettingContentProvider();
+ private Message mMessage;
+
private void addDataService() {
CellularDataService cellularDataService = new CellularDataService();
ServiceInfo serviceInfo = new ServiceInfo();
@@ -1443,7 +1451,6 @@
assertTrue(mDct.isDataEnabled());
assertTrue(mDct.isUserDataEnabled());
-
mDct.setUserDataEnabled(false);
waitForMs(200);
@@ -1453,6 +1460,8 @@
// Changing provisioned to 0.
Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0);
+ mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE, null));
+ waitForMs(200);
assertTrue(mDct.isDataEnabled());
assertTrue(mDct.isUserDataEnabled());
@@ -1461,10 +1470,57 @@
// Settings.Global.MOBILE_DATA and keep data enabled when provisioned.
mDct.setUserDataEnabled(true);
Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 1);
+ mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE, null));
waitForMs(200);
assertTrue(mDct.isDataEnabled());
assertTrue(mDct.isUserDataEnabled());
assertEquals(1, Settings.Global.getInt(resolver, Settings.Global.MOBILE_DATA));
}
+
+ @Test
+ @SmallTest
+ public void testNotifyDataEnabledChanged() throws Exception {
+ doAnswer(invocation -> {
+ mMessage = (Message) invocation.getArguments()[0];
+ return true;
+ }).when(mHandler).sendMessageDelayed(any(), anyLong());
+
+ // Test registration.
+ mDct.registerForDataEnabledChanged(mHandler, DATA_ENABLED_CHANGED, null);
+ verifyDataEnabledChangedMessage(true, DataEnabledSettings.REASON_REGISTERED);
+
+ // Disable user data. Should receive data enabled change to false.
+ mDct.setUserDataEnabled(false);
+ waitForMs(200);
+ verifyDataEnabledChangedMessage(false, DataEnabledSettings.REASON_USER_DATA_ENABLED);
+
+ // Changing provisioned to 0. Shouldn't receive any message, as data enabled remains false.
+ ContentResolver resolver = mContext.getContentResolver();
+ Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0);
+ Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
+ 0);
+ mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE, null));
+ waitForMs(200);
+ assertFalse(mDct.isDataEnabled());
+ verify(mHandler, never()).sendMessageDelayed(any(), anyLong());
+
+ // Changing provisioningDataEnabled to 1. It should trigger data enabled change to true.
+ Settings.Global.putInt(resolver,
+ Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1);
+ mDct.sendMessage(mDct.obtainMessage(
+ DctConstants.EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE, null));
+ waitForMs(200);
+ verifyDataEnabledChangedMessage(
+ true, DataEnabledSettings.REASON_PROVISIONING_DATA_ENABLED_CHANGED);
+ }
+
+ private void verifyDataEnabledChangedMessage(boolean enabled, int reason) {
+ verify(mHandler, times(1)).sendMessageDelayed(any(), anyLong());
+ Pair<Boolean, Integer> result = (Pair) ((AsyncResult) mMessage.obj).result;
+ assertEquals(DATA_ENABLED_CHANGED, mMessage.what);
+ assertEquals(enabled, result.first);
+ assertEquals(reason, (int) result.second);
+ clearInvocations(mHandler);
+ }
}