• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.developeroptions.network.telephony;
18 
19 import android.content.Context;
20 import android.database.ContentObserver;
21 import android.net.Uri;
22 import android.os.Handler;
23 import android.os.Looper;
24 import android.os.PersistableBundle;
25 import android.provider.Settings;
26 import android.telephony.CarrierConfigManager;
27 import android.telephony.PhoneStateListener;
28 import android.telephony.SubscriptionManager;
29 import android.telephony.TelephonyManager;
30 
31 import androidx.annotation.VisibleForTesting;
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceScreen;
34 import androidx.preference.SwitchPreference;
35 
36 import com.android.ims.ImsManager;
37 import com.android.settingslib.core.lifecycle.LifecycleObserver;
38 import com.android.settingslib.core.lifecycle.events.OnStart;
39 import com.android.settingslib.core.lifecycle.events.OnStop;
40 
41 /**
42  * Preference controller for "Video Calling"
43  */
44 public class VideoCallingPreferenceController extends TelephonyTogglePreferenceController implements
45         LifecycleObserver, OnStart, OnStop,
46         Enhanced4gLtePreferenceController.On4gLteUpdateListener {
47 
48     private Preference mPreference;
49     private TelephonyManager mTelephonyManager;
50     private CarrierConfigManager mCarrierConfigManager;
51     @VisibleForTesting
52     ImsManager mImsManager;
53     private PhoneCallStateListener mPhoneStateListener;
54     private DataContentObserver mDataContentObserver;
55 
VideoCallingPreferenceController(Context context, String key)56     public VideoCallingPreferenceController(Context context, String key) {
57         super(context, key);
58         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
59         mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
60         mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
61     }
62 
63     @Override
getAvailabilityStatus(int subId)64     public int getAvailabilityStatus(int subId) {
65         return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
66                 && MobileNetworkUtils.isWifiCallingEnabled(mContext,
67                 SubscriptionManager.getPhoneId(subId))
68                 && isVideoCallEnabled(subId)
69                 ? AVAILABLE
70                 : CONDITIONALLY_UNAVAILABLE;
71     }
72 
73     @Override
displayPreference(PreferenceScreen screen)74     public void displayPreference(PreferenceScreen screen) {
75         super.displayPreference(screen);
76         mPreference = screen.findPreference(getPreferenceKey());
77     }
78 
79     @Override
onStart()80     public void onStart() {
81         mPhoneStateListener.register(mSubId);
82         mDataContentObserver.register(mContext, mSubId);
83     }
84 
85     @Override
onStop()86     public void onStop() {
87         mPhoneStateListener.unregister();
88         mDataContentObserver.unRegister(mContext);
89     }
90 
91     @Override
updateState(Preference preference)92     public void updateState(Preference preference) {
93         super.updateState(preference);
94         final SwitchPreference switchPreference = (SwitchPreference) preference;
95         final boolean videoCallEnabled = isVideoCallEnabled(mSubId, mImsManager);
96         switchPreference.setVisible(videoCallEnabled);
97         if (videoCallEnabled) {
98             final boolean is4gLteEnabled = mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
99                     && mImsManager.isNonTtyOrTtyOnVolteEnabled();
100             preference.setEnabled(is4gLteEnabled &&
101                     mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE);
102             switchPreference.setChecked(is4gLteEnabled && mImsManager.isVtEnabledByUser());
103         }
104     }
105 
106     @Override
setChecked(boolean isChecked)107     public boolean setChecked(boolean isChecked) {
108         mImsManager.setVtSetting(isChecked);
109         return true;
110     }
111 
112     @Override
isChecked()113     public boolean isChecked() {
114         return mImsManager.isVtEnabledByUser();
115     }
116 
init(int subId)117     public VideoCallingPreferenceController init(int subId) {
118         mSubId = subId;
119         mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
120         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
121             mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
122         }
123 
124         return this;
125     }
126 
isVideoCallEnabled(int subId)127     private boolean isVideoCallEnabled(int subId) {
128         final ImsManager imsManager = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
129                 ? ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(subId))
130                 : null;
131         return isVideoCallEnabled(subId, imsManager);
132     }
133 
134     @VisibleForTesting
isVideoCallEnabled(int subId, ImsManager imsManager)135     boolean isVideoCallEnabled(int subId, ImsManager imsManager) {
136         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
137         final TelephonyManager telephonyManager = TelephonyManager
138                 .from(mContext).createForSubscriptionId(subId);
139         return carrierConfig != null && imsManager != null
140                 && imsManager.isVtEnabledByPlatform()
141                 && imsManager.isVtProvisionedOnDevice()
142                 && MobileNetworkUtils.isImsServiceStateReady(imsManager)
143                 && (carrierConfig.getBoolean(
144                 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
145                 || telephonyManager.isDataEnabled());
146     }
147 
148     @Override
on4gLteUpdated()149     public void on4gLteUpdated() {
150         updateState(mPreference);
151     }
152 
153     private class PhoneCallStateListener extends PhoneStateListener {
154 
PhoneCallStateListener(Looper looper)155         public PhoneCallStateListener(Looper looper) {
156             super(looper);
157         }
158 
159         @Override
onCallStateChanged(int state, String incomingNumber)160         public void onCallStateChanged(int state, String incomingNumber) {
161             updateState(mPreference);
162         }
163 
register(int subId)164         public void register(int subId) {
165             mSubId = subId;
166             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
167         }
168 
unregister()169         public void unregister() {
170             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
171         }
172     }
173 
174     /**
175      * Listener that listens mobile data state change.
176      */
177     public class DataContentObserver extends ContentObserver {
178 
DataContentObserver(Handler handler)179         public DataContentObserver(Handler handler) {
180             super(handler);
181         }
182 
183         @Override
onChange(boolean selfChange)184         public void onChange(boolean selfChange) {
185             super.onChange(selfChange);
186             updateState(mPreference);
187         }
188 
register(Context context, int subId)189         public void register(Context context, int subId) {
190             Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
191             if (TelephonyManager.getDefault().getSimCount() != 1) {
192                 uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
193             }
194             context.getContentResolver().registerContentObserver(uri,
195                     false /* notifyForDescendants */, this /* observer */);
196         }
197 
unRegister(Context context)198         public void unRegister(Context context) {
199             context.getContentResolver().unregisterContentObserver(this);
200         }
201     }
202 }
203