• 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.os.Looper;
21 import android.os.PersistableBundle;
22 import android.telephony.CarrierConfigManager;
23 import android.telephony.PhoneStateListener;
24 import android.telephony.SubscriptionManager;
25 import android.telephony.TelephonyManager;
26 import android.telephony.ims.ImsMmTelManager;
27 import android.util.Log;
28 
29 import androidx.annotation.VisibleForTesting;
30 import androidx.preference.Preference;
31 import androidx.preference.PreferenceScreen;
32 import androidx.preference.SwitchPreference;
33 
34 import com.android.settings.network.MobileDataEnabledListener;
35 import com.android.settings.network.ims.VolteQueryImsState;
36 import com.android.settings.network.ims.VtQueryImsState;
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         MobileDataEnabledListener.Client,
47         Enhanced4gBasePreferenceController.On4gLteUpdateListener {
48 
49     private static final String TAG = "VideoCallingPreference";
50 
51     private Preference mPreference;
52     private CarrierConfigManager mCarrierConfigManager;
53     private PhoneCallStateListener mPhoneStateListener;
54     @VisibleForTesting
55     Integer mCallState;
56     private MobileDataEnabledListener mDataContentObserver;
57 
VideoCallingPreferenceController(Context context, String key)58     public VideoCallingPreferenceController(Context context, String key) {
59         super(context, key);
60         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
61         mDataContentObserver = new MobileDataEnabledListener(context, this);
62         mPhoneStateListener = new PhoneCallStateListener();
63     }
64 
65     @Override
getAvailabilityStatus(int subId)66     public int getAvailabilityStatus(int subId) {
67         return SubscriptionManager.isValidSubscriptionId(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(mContext, mSubId);
82         mDataContentObserver.start(mSubId);
83     }
84 
85     @Override
onStop()86     public void onStop() {
87         mPhoneStateListener.unregister();
88         mDataContentObserver.stop();
89     }
90 
91     @Override
updateState(Preference preference)92     public void updateState(Preference preference) {
93         super.updateState(preference);
94         if ((mCallState == null) || (preference == null)) {
95             Log.d(TAG, "Skip update under mCallState=" + mCallState);
96             return;
97         }
98         final SwitchPreference switchPreference = (SwitchPreference) preference;
99         final boolean videoCallEnabled = isVideoCallEnabled(mSubId);
100         switchPreference.setVisible(videoCallEnabled);
101         if (videoCallEnabled) {
102             final boolean videoCallEditable = queryVoLteState(mSubId).isEnabledByUser()
103                     && queryImsState(mSubId).isAllowUserControl();
104             preference.setEnabled(videoCallEditable
105                     && mCallState == TelephonyManager.CALL_STATE_IDLE);
106             switchPreference.setChecked(videoCallEditable && isChecked());
107         }
108     }
109 
110     @Override
setChecked(boolean isChecked)111     public boolean setChecked(boolean isChecked) {
112         if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
113             return false;
114         }
115         final ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(mSubId);
116         if (imsMmTelManager == null) {
117             return false;
118         }
119         try {
120             imsMmTelManager.setVtSettingEnabled(isChecked);
121             return true;
122         } catch (IllegalArgumentException exception) {
123             Log.w(TAG, "Unable to set VT status " + isChecked + ". subId=" + mSubId,
124                     exception);
125         }
126         return false;
127     }
128 
129     @Override
isChecked()130     public boolean isChecked() {
131         return queryImsState(mSubId).isEnabledByUser();
132     }
133 
init(int subId)134     public VideoCallingPreferenceController init(int subId) {
135         mSubId = subId;
136 
137         return this;
138     }
139 
140     @VisibleForTesting
isVideoCallEnabled(int subId)141     boolean isVideoCallEnabled(int subId) {
142         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
143             return false;
144         }
145 
146         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
147         if (carrierConfig == null) {
148             return false;
149         }
150 
151         if (!carrierConfig.getBoolean(
152                 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
153                 && (!mContext.getSystemService(TelephonyManager.class)
154                     .createForSubscriptionId(subId).isDataEnabled())) {
155             return false;
156         }
157 
158         return queryImsState(subId).isReadyToVideoCall();
159     }
160 
161     @Override
on4gLteUpdated()162     public void on4gLteUpdated() {
163         updateState(mPreference);
164     }
165 
166     private class PhoneCallStateListener extends PhoneStateListener {
167 
PhoneCallStateListener()168         PhoneCallStateListener() {
169             super(Looper.getMainLooper());
170         }
171 
172         private TelephonyManager mTelephonyManager;
173 
174         @Override
onCallStateChanged(int state, String incomingNumber)175         public void onCallStateChanged(int state, String incomingNumber) {
176             mCallState = state;
177             updateState(mPreference);
178         }
179 
register(Context context, int subId)180         public void register(Context context, int subId) {
181             mTelephonyManager = context.getSystemService(TelephonyManager.class);
182             if (SubscriptionManager.isValidSubscriptionId(subId)) {
183                 mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
184             }
185             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
186         }
187 
unregister()188         public void unregister() {
189             mCallState = null;
190             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
191         }
192     }
193 
194     /**
195      * Implementation of MobileDataEnabledListener.Client
196      */
onMobileDataEnabledChange()197     public void onMobileDataEnabledChange() {
198         updateState(mPreference);
199     }
200 
201     @VisibleForTesting
queryImsState(int subId)202     VtQueryImsState queryImsState(int subId) {
203         return new VtQueryImsState(mContext, subId);
204     }
205 
206     @VisibleForTesting
queryVoLteState(int subId)207     VolteQueryImsState queryVoLteState(int subId) {
208         return new VolteQueryImsState(mContext, subId);
209     }
210 }
211