1 /* 2 * Copyright (C) 2020 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.PersistableBundle; 23 import android.provider.Telephony; 24 import android.telephony.CarrierConfigManager; 25 import android.telephony.SubscriptionInfo; 26 import android.telephony.ims.ImsManager; 27 import android.util.Log; 28 29 import androidx.annotation.VisibleForTesting; 30 import androidx.fragment.app.FragmentManager; 31 import androidx.lifecycle.Lifecycle; 32 import androidx.lifecycle.LifecycleObserver; 33 import androidx.lifecycle.OnLifecycleEvent; 34 import androidx.preference.Preference; 35 import androidx.preference.PreferenceScreen; 36 import androidx.preference.TwoStatePreference; 37 38 import com.android.settings.network.CarrierConfigCache; 39 import com.android.settings.network.SubscriptionUtil; 40 41 /** 42 * Controller for the "Contact Discovery" option present in MobileNetworkSettings. 43 */ 44 public class ContactDiscoveryPreferenceController extends TelephonyTogglePreferenceController 45 implements LifecycleObserver { 46 private static final String TAG = "ContactDiscoveryPref"; 47 private static final Uri UCE_URI = Uri.withAppendedPath(Telephony.SimInfo.CONTENT_URI, 48 Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED); 49 50 private ImsManager mImsManager; 51 private CarrierConfigCache mCarrierConfigCache; 52 private ContentObserver mUceSettingObserver; 53 private FragmentManager mFragmentManager; 54 55 @VisibleForTesting 56 public Preference preference; 57 ContactDiscoveryPreferenceController(Context context, String key)58 public ContactDiscoveryPreferenceController(Context context, String key) { 59 super(context, key); 60 mImsManager = mContext.getSystemService(ImsManager.class); 61 mCarrierConfigCache = CarrierConfigCache.getInstance(context); 62 } 63 init(FragmentManager fragmentManager, int subId)64 void init(FragmentManager fragmentManager, int subId) { 65 mFragmentManager = fragmentManager; 66 mSubId = subId; 67 } 68 69 @Override isChecked()70 public boolean isChecked() { 71 return MobileNetworkUtils.isContactDiscoveryEnabled(mImsManager, mSubId); 72 } 73 74 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) onResume()75 public void onResume() { 76 registerUceObserver(); 77 } 78 79 @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) onPause()80 public void onPause() { 81 unregisterUceObserver(); 82 } 83 84 @Override setChecked(boolean isChecked)85 public boolean setChecked(boolean isChecked) { 86 if (isChecked) { 87 showContentDiscoveryDialog(); 88 // launch dialog and wait for activity to return and ContentObserver to fire to update. 89 return false; 90 } 91 MobileNetworkUtils.setContactDiscoveryEnabled(mImsManager, mSubId, false /*isEnabled*/); 92 return true; 93 } 94 95 @Override getAvailabilityStatus(int subId)96 public int getAvailabilityStatus(int subId) { 97 PersistableBundle bundle = mCarrierConfigCache.getConfigForSubId(subId); 98 boolean shouldShowPresence = bundle != null 99 && (bundle.getBoolean( 100 CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false /*default*/) 101 || bundle.getBoolean( 102 CarrierConfigManager.Ims.KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false /*default*/)); 103 return shouldShowPresence ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; 104 } 105 106 @Override displayPreference(PreferenceScreen screen)107 public void displayPreference(PreferenceScreen screen) { 108 super.displayPreference(screen); 109 preference = screen.findPreference(getPreferenceKey()); 110 } 111 registerUceObserver()112 private void registerUceObserver() { 113 mUceSettingObserver = new ContentObserver(mContext.getMainThreadHandler()) { 114 @Override 115 public void onChange(boolean selfChange) { 116 onChange(selfChange, null /*uri*/); 117 } 118 119 @Override 120 public void onChange(boolean selfChange, Uri uri) { 121 Log.d(TAG, "UCE setting changed, re-evaluating."); 122 TwoStatePreference switchPref = (TwoStatePreference) preference; 123 switchPref.setChecked(isChecked()); 124 } 125 }; 126 mContext.getContentResolver().registerContentObserver(UCE_URI, true /*notifyForDecendants*/, 127 mUceSettingObserver); 128 } 129 unregisterUceObserver()130 private void unregisterUceObserver() { 131 mContext.getContentResolver().unregisterContentObserver(mUceSettingObserver); 132 } 133 showContentDiscoveryDialog()134 private void showContentDiscoveryDialog() { 135 ContactDiscoveryDialogFragment dialog = ContactDiscoveryDialogFragment.newInstance( 136 mSubId, getCarrierDisplayName(preference.getContext())); 137 dialog.show(mFragmentManager, ContactDiscoveryDialogFragment.getFragmentTag(mSubId)); 138 } 139 getCarrierDisplayName(Context context)140 private CharSequence getCarrierDisplayName(Context context) { 141 CharSequence result = ""; 142 143 for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(context)) { 144 if (mSubId == info.getSubscriptionId()) { 145 result = SubscriptionUtil.getUniqueSubscriptionDisplayName(info, context); 146 break; 147 } 148 } 149 return result; 150 } 151 } 152