1 /* 2 * Copyright (C) 2020 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.settings.network.telephony; 18 19 import static com.android.settings.network.InternetUpdater.INTERNET_ETHERNET; 20 import static com.android.settingslib.mobile.MobileMappings.getIconKey; 21 import static com.android.settingslib.mobile.MobileMappings.mapIconSets; 22 23 import android.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.database.ContentObserver; 28 import android.net.Uri; 29 import android.os.Handler; 30 import android.os.Looper; 31 import android.telephony.ServiceState; 32 import android.telephony.SubscriptionManager; 33 import android.telephony.TelephonyCallback; 34 import android.telephony.TelephonyDisplayInfo; 35 import android.telephony.TelephonyManager; 36 import android.util.Log; 37 38 import androidx.annotation.VisibleForTesting; 39 40 import com.android.settings.network.InternetUpdater; 41 import com.android.settings.network.MobileDataContentObserver; 42 import com.android.settings.network.MobileDataEnabledListener; 43 import com.android.settings.network.SubscriptionsChangeListener; 44 import com.android.settings.wifi.slice.WifiScanWorker; 45 import com.android.settingslib.SignalIcon.MobileIconGroup; 46 import com.android.settingslib.mobile.MobileMappings; 47 import com.android.settingslib.mobile.MobileMappings.Config; 48 import com.android.settingslib.mobile.TelephonyIcons; 49 50 import java.util.Collections; 51 52 /** 53 * BackgroundWorker for Provider Model slice. 54 */ 55 public class NetworkProviderWorker extends WifiScanWorker implements 56 SignalStrengthListener.Callback, MobileDataEnabledListener.Client, 57 DataConnectivityListener.Client, InternetUpdater.InternetChangeListener, 58 SubscriptionsChangeListener.SubscriptionsChangeListenerClient { 59 private static final String TAG = "NetworkProviderWorker"; 60 private static final int PROVIDER_MODEL_DEFAULT_EXPANDED_ROW_COUNT = 6; 61 private DataContentObserver mMobileDataObserver; 62 private SignalStrengthListener mSignalStrengthListener; 63 private SubscriptionsChangeListener mSubscriptionsListener; 64 private MobileDataEnabledListener mDataEnabledListener; 65 private DataConnectivityListener mConnectivityListener; 66 private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 67 private final Context mContext; 68 final Handler mHandler; 69 @VisibleForTesting 70 final NetworkProviderTelephonyCallback mTelephonyCallback; 71 private final BroadcastReceiver mConnectionChangeReceiver = new BroadcastReceiver() { 72 @Override 73 public void onReceive(Context context, Intent intent) { 74 final String action = intent.getAction(); 75 if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) { 76 Log.d(TAG, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED"); 77 updateListener(); 78 } 79 } 80 }; 81 82 private TelephonyManager mTelephonyManager; 83 private Config mConfig = null; 84 private TelephonyDisplayInfo mTelephonyDisplayInfo = 85 new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN, 86 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE); 87 private InternetUpdater mInternetUpdater; 88 private @InternetUpdater.InternetType int mInternetType; 89 NetworkProviderWorker(Context context, Uri uri)90 public NetworkProviderWorker(Context context, Uri uri) { 91 super(context, uri); 92 // Mobile data worker 93 mHandler = new Handler(Looper.getMainLooper()); 94 mMobileDataObserver = new DataContentObserver(mHandler, this); 95 96 mContext = context; 97 mDefaultDataSubId = getDefaultDataSubscriptionId(); 98 Log.d(TAG, "Init, SubId: " + mDefaultDataSubId); 99 mTelephonyManager = mContext.getSystemService( 100 TelephonyManager.class).createForSubscriptionId(mDefaultDataSubId); 101 mTelephonyCallback = new NetworkProviderTelephonyCallback(); 102 mSubscriptionsListener = new SubscriptionsChangeListener(context, this); 103 mDataEnabledListener = new MobileDataEnabledListener(context, this); 104 mConnectivityListener = new DataConnectivityListener(context, this); 105 mSignalStrengthListener = new SignalStrengthListener(context, this); 106 mConfig = getConfig(mContext); 107 108 mInternetUpdater = new InternetUpdater(mContext, getLifecycle(), this); 109 mInternetType = mInternetUpdater.getInternetType(); 110 } 111 112 @Override onSlicePinned()113 protected void onSlicePinned() { 114 Log.d(TAG, "onSlicePinned"); 115 mMobileDataObserver.register(mContext, mDefaultDataSubId); 116 mSubscriptionsListener.start(); 117 mDataEnabledListener.start(mDefaultDataSubId); 118 mConnectivityListener.start(); 119 mSignalStrengthListener.resume(); 120 mTelephonyManager.registerTelephonyCallback(mHandler::post, mTelephonyCallback); 121 IntentFilter filter = new IntentFilter(); 122 filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); 123 mContext.registerReceiver(mConnectionChangeReceiver, filter); 124 super.onSlicePinned(); 125 } 126 127 @Override onSliceUnpinned()128 protected void onSliceUnpinned() { 129 Log.d(TAG, "onSliceUnpinned"); 130 mMobileDataObserver.unregister(mContext); 131 mSubscriptionsListener.stop(); 132 mDataEnabledListener.stop(); 133 mConnectivityListener.stop(); 134 mSignalStrengthListener.pause(); 135 mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); 136 if (mConnectionChangeReceiver != null) { 137 mContext.unregisterReceiver(mConnectionChangeReceiver); 138 } 139 super.onSliceUnpinned(); 140 } 141 142 @Override close()143 public void close() { 144 mMobileDataObserver = null; 145 super.close(); 146 } 147 148 @Override getApRowCount()149 public int getApRowCount() { 150 return PROVIDER_MODEL_DEFAULT_EXPANDED_ROW_COUNT; 151 } 152 153 /** 154 * To update the Slice. 155 */ updateSlice()156 public void updateSlice() { 157 notifySliceChange(); 158 } 159 updateListener()160 private void updateListener() { 161 int defaultDataSubId = getDefaultDataSubscriptionId(); 162 if (mDefaultDataSubId == defaultDataSubId) { 163 Log.d(TAG, "DDS: no change"); 164 return; 165 } 166 mDefaultDataSubId = defaultDataSubId; 167 Log.d(TAG, "DDS: defaultDataSubId:" + mDefaultDataSubId); 168 if (SubscriptionManager.isUsableSubscriptionId(defaultDataSubId)) { 169 mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); 170 mMobileDataObserver.unregister(mContext); 171 172 mSignalStrengthListener.updateSubscriptionIds(Collections.singleton(defaultDataSubId)); 173 mTelephonyManager = mTelephonyManager.createForSubscriptionId(defaultDataSubId); 174 mTelephonyManager.registerTelephonyCallback(mHandler::post, mTelephonyCallback); 175 mMobileDataObserver.register(mContext, defaultDataSubId); 176 mConfig = getConfig(mContext); 177 } else { 178 mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet()); 179 } 180 updateSlice(); 181 } 182 183 @Override onSubscriptionsChanged()184 public void onSubscriptionsChanged() { 185 Log.d(TAG, "onSubscriptionsChanged"); 186 updateListener(); 187 } 188 189 @Override onSignalStrengthChanged()190 public void onSignalStrengthChanged() { 191 Log.d(TAG, "onSignalStrengthChanged"); 192 updateSlice(); 193 } 194 195 @Override onAirplaneModeChanged(boolean airplaneModeEnabled)196 public void onAirplaneModeChanged(boolean airplaneModeEnabled) { 197 Log.d(TAG, "onAirplaneModeChanged"); 198 updateSlice(); 199 } 200 201 @Override onMobileDataEnabledChange()202 public void onMobileDataEnabledChange() { 203 Log.d(TAG, "onMobileDataEnabledChange"); 204 updateSlice(); 205 } 206 207 @Override onDataConnectivityChange()208 public void onDataConnectivityChange() { 209 Log.d(TAG, "onDataConnectivityChange"); 210 updateSlice(); 211 } 212 213 /** 214 * Listen to update of mobile data change. 215 */ 216 public class DataContentObserver extends ContentObserver { 217 private final NetworkProviderWorker mNetworkProviderWorker; 218 DataContentObserver(Handler handler, NetworkProviderWorker backgroundWorker)219 public DataContentObserver(Handler handler, NetworkProviderWorker backgroundWorker) { 220 super(handler); 221 Log.d(TAG, "DataContentObserver: init"); 222 mNetworkProviderWorker = backgroundWorker; 223 } 224 225 @Override onChange(boolean selfChange)226 public void onChange(boolean selfChange) { 227 Log.d(TAG, "DataContentObserver: onChange"); 228 mNetworkProviderWorker.updateSlice(); 229 } 230 231 /** 232 * To register the observer for mobile data changed. 233 * 234 * @param context the Context object. 235 * @param subId the default data subscription id. 236 */ register(Context context, int subId)237 public void register(Context context, int subId) { 238 final Uri uri = MobileDataContentObserver.getObservableUri(context, subId); 239 Log.d(TAG, "DataContentObserver: register uri:" + uri); 240 context.getContentResolver().registerContentObserver(uri, false, this); 241 } 242 243 /** 244 * To unregister the observer for mobile data changed. 245 * 246 * @param context the Context object. 247 */ unregister(Context context)248 public void unregister(Context context) { 249 Log.d(TAG, "DataContentObserver: unregister"); 250 context.getContentResolver().unregisterContentObserver(this); 251 } 252 } 253 254 class NetworkProviderTelephonyCallback extends TelephonyCallback implements 255 TelephonyCallback.DataConnectionStateListener, 256 TelephonyCallback.DisplayInfoListener, 257 TelephonyCallback.ServiceStateListener { 258 @Override onServiceStateChanged(ServiceState state)259 public void onServiceStateChanged(ServiceState state) { 260 Log.d(TAG, "onServiceStateChanged voiceState=" + state.getState() 261 + " dataState=" + state.getDataRegistrationState()); 262 updateSlice(); 263 } 264 265 @Override onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo)266 public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) { 267 Log.d(TAG, "onDisplayInfoChanged: telephonyDisplayInfo=" + telephonyDisplayInfo); 268 mTelephonyDisplayInfo = telephonyDisplayInfo; 269 updateSlice(); 270 } 271 272 @Override onDataConnectionStateChanged(int state, int networkType)273 public void onDataConnectionStateChanged(int state, int networkType) { 274 Log.d(TAG, 275 "onDataConnectionStateChanged: networkType=" + networkType + " state=" + state); 276 updateSlice(); 277 } 278 } 279 280 @VisibleForTesting getDefaultDataSubscriptionId()281 int getDefaultDataSubscriptionId() { 282 return SubscriptionManager.getDefaultDataSubscriptionId(); 283 } 284 updateNetworkTypeName(Context context, Config config, TelephonyDisplayInfo telephonyDisplayInfo, int subId)285 private String updateNetworkTypeName(Context context, Config config, 286 TelephonyDisplayInfo telephonyDisplayInfo, int subId) { 287 String iconKey = getIconKey(telephonyDisplayInfo); 288 int resId = mapIconSets(config).get(iconKey).dataContentDescription; 289 if (mWifiPickerTrackerHelper != null 290 && mWifiPickerTrackerHelper.isCarrierNetworkActive()) { 291 MobileIconGroup carrierMergedWifiIconGroup = TelephonyIcons.CARRIER_MERGED_WIFI; 292 resId = carrierMergedWifiIconGroup.dataContentDescription; 293 return resId != 0 294 ? SubscriptionManager.getResourcesForSubId(context, subId) 295 .getString(resId) : ""; 296 } 297 298 return resId != 0 299 ? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : ""; 300 } 301 302 @VisibleForTesting getConfig(Context context)303 Config getConfig(Context context) { 304 return MobileMappings.Config.readConfig(context); 305 } 306 307 /** 308 * Get currently description of mobile network type. 309 */ getNetworkTypeDescription()310 public String getNetworkTypeDescription() { 311 return updateNetworkTypeName(mContext, mConfig, mTelephonyDisplayInfo, 312 mDefaultDataSubId); 313 } 314 315 /** 316 * Called when internet type is changed. 317 * 318 * @param internetType the internet type 319 */ onInternetTypeChanged(@nternetUpdater.InternetType int internetType)320 public void onInternetTypeChanged(@InternetUpdater.InternetType int internetType) { 321 if (mInternetType == internetType) { 322 return; 323 } 324 boolean changeWithEthernet = 325 mInternetType == INTERNET_ETHERNET || internetType == INTERNET_ETHERNET; 326 mInternetType = internetType; 327 if (changeWithEthernet) { 328 updateSlice(); 329 } 330 } 331 332 /** 333 * Returns the internet type. 334 */ getInternetType()335 public @InternetUpdater.InternetType int getInternetType() { 336 return mInternetType; 337 } 338 } 339