1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony.dataconnection; 18 19 20 import android.content.ContentResolver; 21 import android.os.Handler; 22 import android.os.RegistrantList; 23 import android.os.SystemProperties; 24 import android.provider.Settings; 25 import android.telephony.Rlog; 26 import android.telephony.SubscriptionManager; 27 import android.telephony.TelephonyManager; 28 import android.util.LocalLog; 29 import android.util.Pair; 30 31 import com.android.internal.telephony.Phone; 32 33 import java.io.FileDescriptor; 34 import java.io.PrintWriter; 35 36 /** 37 * The class to hold different data enabled/disabled settings. Also it allows clients to register 38 * for overall data enabled setting changed event. 39 * @hide 40 */ 41 public class DataEnabledSettings { 42 43 private static final String LOG_TAG = "DataEnabledSettings"; 44 45 public static final int REASON_REGISTERED = 0; 46 47 public static final int REASON_INTERNAL_DATA_ENABLED = 1; 48 49 public static final int REASON_USER_DATA_ENABLED = 2; 50 51 public static final int REASON_POLICY_DATA_ENABLED = 3; 52 53 public static final int REASON_DATA_ENABLED_BY_CARRIER = 4; 54 55 /** 56 * responds to the setInternalDataEnabled call - used internally to turn off data. 57 * For example during emergency calls 58 */ 59 private boolean mInternalDataEnabled = true; 60 61 /** 62 * Flag indicating data allowed by network policy manager or not. 63 */ 64 private boolean mPolicyDataEnabled = true; 65 66 /** 67 * Indicate if metered APNs are enabled by the carrier. set false to block all the metered APNs 68 * from continuously sending requests, which causes undesired network load. 69 */ 70 private boolean mCarrierDataEnabled = true; 71 72 private Phone mPhone = null; 73 private ContentResolver mResolver = null; 74 75 private final RegistrantList mDataEnabledChangedRegistrants = new RegistrantList(); 76 77 private final LocalLog mSettingChangeLocalLog = new LocalLog(50); 78 79 @Override toString()80 public String toString() { 81 return "[mInternalDataEnabled=" + mInternalDataEnabled 82 + ", isUserDataEnabled=" + isUserDataEnabled() 83 + ", isProvisioningDataEnabled=" + isProvisioningDataEnabled() 84 + ", mPolicyDataEnabled=" + mPolicyDataEnabled 85 + ", mCarrierDataEnabled=" + mCarrierDataEnabled + "]"; 86 } 87 DataEnabledSettings(Phone phone)88 public DataEnabledSettings(Phone phone) { 89 mPhone = phone; 90 mResolver = mPhone.getContext().getContentResolver(); 91 } 92 setInternalDataEnabled(boolean enabled)93 public synchronized void setInternalDataEnabled(boolean enabled) { 94 localLog("InternalDataEnabled", enabled); 95 boolean prevDataEnabled = isDataEnabled(); 96 mInternalDataEnabled = enabled; 97 if (prevDataEnabled != isDataEnabled()) { 98 notifyDataEnabledChanged(!prevDataEnabled, REASON_INTERNAL_DATA_ENABLED); 99 } 100 } isInternalDataEnabled()101 public synchronized boolean isInternalDataEnabled() { 102 return mInternalDataEnabled; 103 } 104 setUserDataEnabled(boolean enabled)105 public synchronized void setUserDataEnabled(boolean enabled) { 106 localLog("UserDataEnabled", enabled); 107 boolean prevDataEnabled = isDataEnabled(); 108 109 Settings.Global.putInt(mResolver, getMobileDataSettingName(), enabled ? 1 : 0); 110 111 if (prevDataEnabled != isDataEnabled()) { 112 notifyDataEnabledChanged(!prevDataEnabled, REASON_USER_DATA_ENABLED); 113 } 114 } isUserDataEnabled()115 public synchronized boolean isUserDataEnabled() { 116 boolean defaultVal = "true".equalsIgnoreCase(SystemProperties.get( 117 "ro.com.android.mobiledata", "true")); 118 119 return (Settings.Global.getInt(mResolver, getMobileDataSettingName(), 120 defaultVal ? 1 : 0) != 0); 121 } 122 getMobileDataSettingName()123 private String getMobileDataSettingName() { 124 // For single SIM phones, this is a per phone property. Or if it's invalid subId, we 125 // read default setting. 126 int subId = mPhone.getSubId(); 127 if (TelephonyManager.getDefault().getSimCount() == 1 128 || !SubscriptionManager.isValidSubscriptionId(subId)) { 129 return Settings.Global.MOBILE_DATA; 130 } else { 131 return Settings.Global.MOBILE_DATA + mPhone.getSubId(); 132 } 133 } 134 setPolicyDataEnabled(boolean enabled)135 public synchronized void setPolicyDataEnabled(boolean enabled) { 136 localLog("PolicyDataEnabled", enabled); 137 boolean prevDataEnabled = isDataEnabled(); 138 mPolicyDataEnabled = enabled; 139 if (prevDataEnabled != isDataEnabled()) { 140 notifyDataEnabledChanged(!prevDataEnabled, REASON_POLICY_DATA_ENABLED); 141 } 142 } isPolicyDataEnabled()143 public synchronized boolean isPolicyDataEnabled() { 144 return mPolicyDataEnabled; 145 } 146 setCarrierDataEnabled(boolean enabled)147 public synchronized void setCarrierDataEnabled(boolean enabled) { 148 localLog("CarrierDataEnabled", enabled); 149 boolean prevDataEnabled = isDataEnabled(); 150 mCarrierDataEnabled = enabled; 151 if (prevDataEnabled != isDataEnabled()) { 152 notifyDataEnabledChanged(!prevDataEnabled, REASON_DATA_ENABLED_BY_CARRIER); 153 } 154 } isCarrierDataEnabled()155 public synchronized boolean isCarrierDataEnabled() { 156 return mCarrierDataEnabled; 157 } 158 isDataEnabled()159 public synchronized boolean isDataEnabled() { 160 if (isProvisioning()) { 161 return isProvisioningDataEnabled(); 162 } else { 163 return mInternalDataEnabled && isUserDataEnabled() 164 && mPolicyDataEnabled && mCarrierDataEnabled; 165 } 166 } 167 isProvisioning()168 public boolean isProvisioning() { 169 return Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0; 170 } 171 /** 172 * In provisioning, we might want to have enable mobile data during provisioning. It depends 173 * on value of Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED which is set by 174 * setupwizard. It only matters if it's in provisioning stage. 175 * @return whether we are enabling userData during provisioning stage. 176 */ isProvisioningDataEnabled()177 public boolean isProvisioningDataEnabled() { 178 final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata", 179 "false"); 180 boolean retVal = "true".equalsIgnoreCase(prov_property); 181 182 final int prov_mobile_data = Settings.Global.getInt(mResolver, 183 Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 184 retVal ? 1 : 0); 185 retVal = prov_mobile_data != 0; 186 log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property 187 + ", " + prov_mobile_data + ")"); 188 189 return retVal; 190 } 191 notifyDataEnabledChanged(boolean enabled, int reason)192 private void notifyDataEnabledChanged(boolean enabled, int reason) { 193 mDataEnabledChangedRegistrants.notifyResult(new Pair<>(enabled, reason)); 194 } 195 registerForDataEnabledChanged(Handler h, int what, Object obj)196 public void registerForDataEnabledChanged(Handler h, int what, Object obj) { 197 mDataEnabledChangedRegistrants.addUnique(h, what, obj); 198 notifyDataEnabledChanged(isDataEnabled(), REASON_REGISTERED); 199 } 200 unregisterForDataEnabledChanged(Handler h)201 public void unregisterForDataEnabledChanged(Handler h) { 202 mDataEnabledChangedRegistrants.remove(h); 203 } 204 log(String s)205 private void log(String s) { 206 Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s); 207 } 208 localLog(String name, boolean value)209 private void localLog(String name, boolean value) { 210 mSettingChangeLocalLog.log(name + " change to " + value); 211 } 212 dump(FileDescriptor fd, PrintWriter pw, String[] args)213 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 214 pw.println(" DataEnabledSettings="); 215 mSettingChangeLocalLog.dump(fd, pw, args); 216 } 217 } 218