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.SwitchPreference;
37 
38 import com.android.settings.network.SubscriptionUtil;
39 
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 CarrierConfigManager mCarrierConfigManager;
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         mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
62     }
63 
init(FragmentManager fragmentManager, int subId, Lifecycle lifecycle)64     public ContactDiscoveryPreferenceController init(FragmentManager fragmentManager, int subId,
65             Lifecycle lifecycle) {
66         mFragmentManager = fragmentManager;
67         mSubId = subId;
68         lifecycle.addObserver(this);
69         return this;
70     }
71 
72     @Override
isChecked()73     public boolean isChecked() {
74         return MobileNetworkUtils.isContactDiscoveryEnabled(mImsManager, mSubId);
75     }
76 
77     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
onResume()78     public void onResume() {
79         registerUceObserver();
80     }
81 
82     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
onPause()83     public void onPause() {
84         unregisterUceObserver();
85     }
86 
87     @Override
setChecked(boolean isChecked)88     public boolean setChecked(boolean isChecked) {
89         if (isChecked) {
90             showContentDiscoveryDialog();
91             // launch dialog and wait for activity to return and ContentObserver to fire to update.
92             return false;
93         }
94         MobileNetworkUtils.setContactDiscoveryEnabled(mImsManager, mSubId, false /*isEnabled*/);
95         return true;
96     }
97 
98     @Override
getAvailabilityStatus(int subId)99     public int getAvailabilityStatus(int subId) {
100         PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(subId);
101         boolean shouldShowPresence = bundle != null && bundle.getBoolean(
102                 CarrierConfigManager.KEY_USE_RCS_PRESENCE_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                 SwitchPreference switchPref = (SwitchPreference) 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 = info.getDisplayName();
146                 break;
147             }
148         }
149         return result;
150     }
151 }
152