1 /*
2  * Copyright (C) 2021 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.car.settings.qc;
18 
19 import android.car.drivingstate.CarUxRestrictions;
20 import android.car.drivingstate.CarUxRestrictionsManager.OnUxRestrictionsChangedListener;
21 import android.content.Context;
22 import android.database.ContentObserver;
23 import android.net.Uri;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.provider.Settings;
27 import android.telephony.SignalStrength;
28 import android.telephony.SubscriptionManager;
29 import android.telephony.TelephonyCallback;
30 import android.telephony.TelephonyManager;
31 
32 import com.android.car.datasubscription.DataSubscription;
33 import com.android.car.settings.common.CarUxRestrictionsHelper;
34 
35 import java.io.IOException;
36 
37 /**
38  * Base background worker for mobile data QCItems.
39  * @param <E> The {@link SettingsQCItem} the background worker is associated with.
40  */
41 public abstract class MobileDataBaseWorker<E extends SettingsQCItem>
42         extends SettingsQCBackgroundWorker<E> implements OnUxRestrictionsChangedListener,
43         DataSubscription.DataSubscriptionChangeListener {
44 
45     private final TelephonyManager mTelephonyManager;
46     private final int mSubId;
47     private final SignalStrengthsListener mSignalStrengthsListener;
48     private CarUxRestrictionsHelper mUxRestrictionsHelper;
49     private DataSubscription mSubscription;
50     private boolean mCallbacksRegistered;
51 
52     private final ContentObserver mMobileDataChangeObserver = new ContentObserver(
53             new Handler(Looper.getMainLooper())) {
54         @Override
55         public void onChange(boolean selfChange) {
56             super.onChange(selfChange);
57             notifyQCItemChange();
58         }
59     };
60 
MobileDataBaseWorker(Context context, Uri uri)61     protected MobileDataBaseWorker(Context context, Uri uri) {
62         super(context, uri);
63         mTelephonyManager = context.getSystemService(TelephonyManager.class);
64         mSubId = SubscriptionManager.getDefaultDataSubscriptionId();
65         mSignalStrengthsListener = new SignalStrengthsListener();
66         mSubscription = new DataSubscription(context);
67         mUxRestrictionsHelper = new CarUxRestrictionsHelper(/* context= */ context, /* listener= */
68                 this);
69     }
70 
71     @Override
onQCItemSubscribe()72     protected void onQCItemSubscribe() {
73         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && !mCallbacksRegistered) {
74             mTelephonyManager.registerTelephonyCallback(getContext().getMainExecutor(),
75                     mSignalStrengthsListener);
76             getContext().getContentResolver().registerContentObserver(getObservableUri(mSubId),
77                     /* notifyForDescendants= */ false, mMobileDataChangeObserver);
78             mCallbacksRegistered = true;
79         }
80         mSubscription.addDataSubscriptionListener(this);
81         ((MobileDataRow) getQCItem()).setCarUxRestrictions(
82                 mUxRestrictionsHelper.getCarUxRestrictions());
83     }
84 
85     @Override
onQCItemUnsubscribe()86     protected void onQCItemUnsubscribe() {
87         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
88             unregisterCallbacks();
89         }
90         mSubscription.removeDataSubscriptionListener();
91     }
92 
93     @Override
close()94     public void close() throws IOException {
95         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
96             unregisterCallbacks();
97         }
98         mUxRestrictionsHelper.destroy();
99     }
100 
unregisterCallbacks()101     private void unregisterCallbacks() {
102         if (mCallbacksRegistered) {
103             mTelephonyManager.unregisterTelephonyCallback(mSignalStrengthsListener);
104             getContext().getContentResolver().unregisterContentObserver(mMobileDataChangeObserver);
105             mCallbacksRegistered = false;
106         }
107     }
108 
getObservableUri(int subId)109     private Uri getObservableUri(int subId) {
110         Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
111         if (TelephonyManager.from(getContext()).getSimCount() != 1) {
112             uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
113         }
114         return uri;
115     }
116 
117     private class SignalStrengthsListener extends TelephonyCallback
118             implements TelephonyCallback.SignalStrengthsListener {
119 
120         @Override
onSignalStrengthsChanged(SignalStrength signalStrength)121         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
122             notifyQCItemChange();
123         }
124     }
125     @Override
onUxRestrictionsChanged(CarUxRestrictions restrictionInfo)126     public void onUxRestrictionsChanged(CarUxRestrictions restrictionInfo) {
127         if (getQCItem() != null) {
128             ((MobileDataRow) getQCItem()).setCarUxRestrictions(restrictionInfo);
129             notifyQCItemChange();
130         }
131     }
132 
133     @Override
onChange(int value)134     public void onChange(int value) {
135         if (getQCItem() != null) {
136             notifyQCItemChange();
137         }
138     }
139 }