• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 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, subId)
67                 && isVideoCallEnabled(subId)
68                 ? AVAILABLE
69                 : CONDITIONALLY_UNAVAILABLE;
70     }
71 
72     @Override
displayPreference(PreferenceScreen screen)73     public void displayPreference(PreferenceScreen screen) {
74         super.displayPreference(screen);
75         mPreference = screen.findPreference(getPreferenceKey());
76     }
77 
78     @Override
onStart()79     public void onStart() {
80         mPhoneStateListener.register(mSubId);
81         mDataContentObserver.register(mContext, mSubId);
82     }
83 
84     @Override
onStop()85     public void onStop() {
86         mPhoneStateListener.unregister();
87         mDataContentObserver.unRegister(mContext);
88     }
89 
90     @Override
updateState(Preference preference)91     public void updateState(Preference preference) {
92         super.updateState(preference);
93         final SwitchPreference switchPreference = (SwitchPreference) preference;
94         final boolean videoCallEnabled = isVideoCallEnabled(mSubId, mImsManager);
95         switchPreference.setVisible(videoCallEnabled);
96         if (videoCallEnabled) {
97             final boolean is4gLteEnabled = mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
98                     && mImsManager.isNonTtyOrTtyOnVolteEnabled();
99             preference.setEnabled(is4gLteEnabled &&
100                     mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE);
101             switchPreference.setChecked(is4gLteEnabled && mImsManager.isVtEnabledByUser());
102         }
103     }
104 
105     @Override
setChecked(boolean isChecked)106     public boolean setChecked(boolean isChecked) {
107         mImsManager.setVtSetting(isChecked);
108         return true;
109     }
110 
111     @Override
isChecked()112     public boolean isChecked() {
113         return mImsManager.isVtEnabledByUser();
114     }
115 
init(int subId)116     public VideoCallingPreferenceController init(int subId) {
117         mSubId = subId;
118         mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
119         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
120             mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
121         }
122 
123         return this;
124     }
125 
isVideoCallEnabled(int subId)126     private boolean isVideoCallEnabled(int subId) {
127         final ImsManager imsManager = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
128                 ? ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(subId))
129                 : null;
130         return isVideoCallEnabled(subId, imsManager);
131     }
132 
133     @VisibleForTesting
isVideoCallEnabled(int subId, ImsManager imsManager)134     boolean isVideoCallEnabled(int subId, ImsManager imsManager) {
135         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
136         final TelephonyManager telephonyManager = TelephonyManager
137                 .from(mContext).createForSubscriptionId(subId);
138         return carrierConfig != null && imsManager != null
139                 && imsManager.isVtEnabledByPlatform()
140                 && imsManager.isVtProvisionedOnDevice()
141                 && MobileNetworkUtils.isImsServiceStateReady(imsManager)
142                 && (carrierConfig.getBoolean(
143                 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
144                 || telephonyManager.isDataEnabled());
145     }
146 
147     @Override
on4gLteUpdated()148     public void on4gLteUpdated() {
149         updateState(mPreference);
150     }
151 
152     private class PhoneCallStateListener extends PhoneStateListener {
153 
PhoneCallStateListener(Looper looper)154         public PhoneCallStateListener(Looper looper) {
155             super(looper);
156         }
157 
158         @Override
onCallStateChanged(int state, String incomingNumber)159         public void onCallStateChanged(int state, String incomingNumber) {
160             updateState(mPreference);
161         }
162 
register(int subId)163         public void register(int subId) {
164             mSubId = subId;
165             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
166         }
167 
unregister()168         public void unregister() {
169             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
170         }
171     }
172 
173     /**
174      * Listener that listens mobile data state change.
175      */
176     public class DataContentObserver extends ContentObserver {
177 
DataContentObserver(Handler handler)178         public DataContentObserver(Handler handler) {
179             super(handler);
180         }
181 
182         @Override
onChange(boolean selfChange)183         public void onChange(boolean selfChange) {
184             super.onChange(selfChange);
185             updateState(mPreference);
186         }
187 
register(Context context, int subId)188         public void register(Context context, int subId) {
189             Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
190             if (TelephonyManager.getDefault().getSimCount() != 1) {
191                 uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
192             }
193             context.getContentResolver().registerContentObserver(uri,
194                     false /* notifyForDescendants */, this /* observer */);
195         }
196 
unRegister(Context context)197         public void unRegister(Context context) {
198             context.getContentResolver().unregisterContentObserver(this);
199         }
200     }
201 }
202