Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63aae521 authored by Malcolm Chen's avatar Malcolm Chen
Browse files

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
parent fe1fdf59
Loading
Loading
Loading
Loading
+41 −19
Original line number Diff line number Diff line
@@ -52,6 +52,10 @@ public class DataEnabledSettings {

    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 @@ public class DataEnabledSettings {
     */
    private boolean mCarrierDataEnabled = true;

    private boolean mIsDataEnabled = false;

    private Phone mPhone = null;
    private ContentResolver mResolver = null;

@@ -88,15 +94,14 @@ public class DataEnabledSettings {
    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 class DataEnabledSettings {

    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 class DataEnabledSettings {

    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;
        }
    }
+19 −1
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ public class DcTracker extends Handler {
                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 @@ public class DcTracker extends Handler {
    }

    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 @@ public class DcTracker extends Handler {
        }
    }

    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 @@ public class DcTracker extends Handler {
                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);
+57 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static org.mockito.Matchers.anyInt;
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.NetworkCapabilities;
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.MediumTest;
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 @@ public class DcTrackerTest extends TelephonyTest {
            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 @@ public class DcTrackerTest extends TelephonyTest {
    DataConnection mDataConnection;
    @Mock
    PackageManagerService mMockPackageManagerInternal;
    @Mock
    Handler mHandler;

    private DcTracker mDct;
    private DcTrackerTestHandler mDcTrackerTestHandler;
@@ -158,6 +164,8 @@ public class DcTrackerTest extends TelephonyTest {
    private final ApnSettingContentProvider mApnSettingContentProvider =
            new ApnSettingContentProvider();

    private Message mMessage;

    private void addDataService() {
        CellularDataService cellularDataService = new CellularDataService();
        ServiceInfo serviceInfo = new ServiceInfo();
@@ -1443,7 +1451,6 @@ public class DcTrackerTest extends TelephonyTest {
        assertTrue(mDct.isDataEnabled());
        assertTrue(mDct.isUserDataEnabled());


        mDct.setUserDataEnabled(false);
        waitForMs(200);

@@ -1453,6 +1460,8 @@ public class DcTrackerTest extends TelephonyTest {

        // 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 @@ public class DcTrackerTest extends TelephonyTest {
        // 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);
    }
}