• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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