1 /*
2  * Copyright (C) 2009 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.phone;
18 
19 import android.content.Context;
20 import android.os.Bundle;
21 import android.os.PersistableBundle;
22 import android.os.UserManager;
23 import android.preference.Preference;
24 import android.preference.PreferenceScreen;
25 import android.telephony.CarrierConfigManager;
26 import android.telephony.SubscriptionManager;
27 import android.telephony.ims.ImsException;
28 import android.telephony.ims.ImsManager;
29 import android.telephony.ims.ImsMmTelManager;
30 import android.telephony.ims.feature.MmTelFeature;
31 import android.util.Log;
32 import android.view.MenuItem;
33 
34 import com.android.internal.telephony.PhoneConstants;
35 import com.android.internal.telephony.flags.Flags;
36 
37 public class CdmaCallOptions extends TimeConsumingPreferenceActivity {
38     private static final String LOG_TAG = "CdmaCallOptions";
39 
40     private static final String BUTTON_VP_KEY = "button_voice_privacy_key";
41     private static final String CALL_FORWARDING_KEY = "call_forwarding_key";
42     private static final String CALL_WAITING_KEY = "call_waiting_key";
43 
44     private class UtCallback extends ImsMmTelManager.CapabilityCallback {
45         @Override
onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities)46         public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
47             boolean isUtAvailable = capabilities.isCapable(
48                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
49             updatePreferencesEnabled(isUtAvailable);
50         }
51     }
52 
53     private Preference mCallForwardingPref;
54     private CdmaCallWaitingPreference mCallWaitingPref;
55     private UtCallback mUtCallback;
56     private ImsMmTelManager mMmTelManager;
57 
58     @Override
onCreate(Bundle icicle)59     protected void onCreate(Bundle icicle) {
60         super.onCreate(icicle);
61 
62         addPreferencesFromResource(R.xml.cdma_call_privacy);
63 
64         SubscriptionInfoHelper subInfoHelper = new SubscriptionInfoHelper(this, getIntent());
65         subInfoHelper.setActionBarTitle(
66                 getActionBar(), getResources(), R.string.labelCdmaMore_with_label);
67 
68         CdmaVoicePrivacySwitchPreference buttonVoicePrivacy =
69                 (CdmaVoicePrivacySwitchPreference) findPreference(BUTTON_VP_KEY);
70         buttonVoicePrivacy.setPhone(subInfoHelper.getPhone());
71         PersistableBundle carrierConfig;
72         int subId;
73         if (subInfoHelper.hasSubId()) {
74             subId = subInfoHelper.getSubId();
75         } else {
76             subId = SubscriptionManager.getDefaultSubscriptionId();
77         }
78         carrierConfig = PhoneGlobals.getInstance().getCarrierConfigForSubId(subId);
79         if (subInfoHelper.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_CDMA
80                 || carrierConfig.getBoolean(CarrierConfigManager.KEY_VOICE_PRIVACY_DISABLE_UI_BOOL)) {
81             buttonVoicePrivacy.setEnabled(false);
82         }
83 
84         // If mobile network configs are restricted, then hide the mCallForwardingPref and
85         // mCallWaitingPref.
86         UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
87         boolean mobileNetworkConfigsRestricted =
88                 userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
89         if (Flags.ensureAccessToCallSettingsIsRestricted() && mobileNetworkConfigsRestricted) {
90             Log.i(LOG_TAG, "Mobile network configs are restricted, hiding CDMA call forwarding "
91                     + "and CDMA call waiting options.");
92         }
93 
94         mCallForwardingPref = getPreferenceScreen().findPreference(CALL_FORWARDING_KEY);
95         if (carrierConfig != null && carrierConfig.getBoolean(
96                 CarrierConfigManager.KEY_CALL_FORWARDING_VISIBILITY_BOOL) &&
97                 (!mobileNetworkConfigsRestricted ||
98                         !Flags.ensureAccessToCallSettingsIsRestricted())) {
99             mCallForwardingPref.setIntent(
100                     subInfoHelper.getIntent(CdmaCallForwardOptions.class));
101         } else {
102             getPreferenceScreen().removePreference(mCallForwardingPref);
103             mCallForwardingPref = null;
104         }
105 
106         mCallWaitingPref = (CdmaCallWaitingPreference) getPreferenceScreen()
107                 .findPreference(CALL_WAITING_KEY);
108         if (carrierConfig == null || !carrierConfig.getBoolean(
109                 CarrierConfigManager.KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL) ||
110                 (Flags.ensureAccessToCallSettingsIsRestricted() &&
111                         mobileNetworkConfigsRestricted)) {
112             getPreferenceScreen().removePreference(mCallWaitingPref);
113             mCallWaitingPref = null;
114         }
115         // Do not go further if the preferences are removed.
116         if (mCallForwardingPref == null && mCallWaitingPref == null) return;
117 
118         boolean isSsOverCdmaEnabled = carrierConfig != null && carrierConfig.getBoolean(
119                 CarrierConfigManager.KEY_SUPPORT_SS_OVER_CDMA_BOOL);
120         boolean isSsOverUtEnabled = carrierConfig != null && carrierConfig.getBoolean(
121                 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL);
122 
123         if (isSsOverCdmaEnabled && mCallWaitingPref != null) {
124             // If SS over CDMA is enabled, then the preference will always be enabled,
125             // independent of SS over UT status. Initialize it now.
126             mCallWaitingPref.init(this, subInfoHelper.getPhone());
127             return;
128         }
129         // Since SS over UT availability can change, first disable the preferences that rely on it
130         // and only enable it if UT is available.
131         updatePreferencesEnabled(false);
132         if (isSsOverUtEnabled) {
133             // Register a callback to listen to SS over UT state. This will enable the preferences
134             // once the callback notifies settings that UT is enabled.
135             registerMmTelCapsCallback(subId);
136         } else {
137             Log.w(LOG_TAG, "SS over UT and CDMA disabled, but preferences are visible.");
138         }
139     }
140 
141     @Override
onStop()142     public void onStop() {
143         super.onStop();
144         unregisterMmTelCapsCallback();
145     }
146 
unregisterMmTelCapsCallback()147     private void unregisterMmTelCapsCallback() {
148         if (mMmTelManager == null || mUtCallback == null) return;
149         mMmTelManager.unregisterMmTelCapabilityCallback(mUtCallback);
150         mUtCallback = null;
151         Log.d(LOG_TAG, "unregisterMmTelCapsCallback: UT availability callback unregistered");
152     }
153 
registerMmTelCapsCallback(int subId)154     private void registerMmTelCapsCallback(int subId) {
155         if (!SubscriptionManager.isValidSubscriptionId(subId)) return;
156         ImsManager imsManager = getSystemService(ImsManager.class);
157         try {
158             if (imsManager != null) {
159                 mUtCallback = new UtCallback();
160                 mMmTelManager = imsManager.getImsMmTelManager(subId);
161                 // Callback will call back with the state as soon as it is available.
162                 mMmTelManager.registerMmTelCapabilityCallback(getMainExecutor(), mUtCallback);
163                 Log.d(LOG_TAG, "registerMmTelCapsCallback: UT availability callback "
164                         + "registered");
165             } else {
166                 Log.w(LOG_TAG, "registerMmTelCapsCallback: couldn't get ImsManager, assuming "
167                         + "UT is not available: ");
168                 updatePreferencesEnabled(false);
169             }
170         } catch (IllegalArgumentException | ImsException e) {
171             Log.w(LOG_TAG, "registerMmTelCapsCallback: couldn't register callback, assuming "
172                     + "UT is not available: " + e);
173             updatePreferencesEnabled(false);
174         }
175     }
176 
updatePreferencesEnabled(boolean isEnabled)177     private void updatePreferencesEnabled(boolean isEnabled) {
178         Log.d(LOG_TAG, "updatePreferencesEnabled: " + isEnabled);
179         if (mCallForwardingPref != null) mCallForwardingPref.setEnabled(isEnabled);
180 
181         if (mCallWaitingPref == null || mCallWaitingPref.isEnabled() == isEnabled) return;
182         mCallWaitingPref.setActionAvailable(isEnabled);
183         if (isEnabled) {
184             SubscriptionInfoHelper subInfoHelper = new SubscriptionInfoHelper(this, getIntent());
185             // kick off the normal process to populate the Call Waiting status.
186             mCallWaitingPref.init(this, subInfoHelper.getPhone());
187         }
188     }
189 
190     @Override
onOptionsItemSelected(MenuItem item)191     public boolean onOptionsItemSelected(MenuItem item) {
192         final int itemId = item.getItemId();
193         if (itemId == android.R.id.home) {
194             onBackPressed();
195             return true;
196         }
197         return super.onOptionsItemSelected(item);
198     }
199 
200     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)201     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
202         if (preference.getKey().equals(BUTTON_VP_KEY)) {
203             return true;
204         }
205         return false;
206     }
207 }
208