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