• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.deviceinfo.simstatus;
18 
19 import android.content.Context;
20 import android.os.UserManager;
21 import android.telephony.SubscriptionInfo;
22 import android.telephony.SubscriptionManager;
23 import android.text.TextUtils;
24 
25 import androidx.annotation.VisibleForTesting;
26 import androidx.fragment.app.Fragment;
27 import androidx.lifecycle.LifecycleOwner;
28 import androidx.lifecycle.LiveData;
29 import androidx.lifecycle.Observer;
30 import androidx.preference.Preference;
31 import androidx.preference.PreferenceCategory;
32 import androidx.preference.PreferenceScreen;
33 
34 import com.android.settings.R;
35 import com.android.settings.core.BasePreferenceController;
36 import com.android.settings.network.SubscriptionUtil;
37 import com.android.settingslib.Utils;
38 import com.android.settingslib.search.SearchIndexableRaw;
39 
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 public class SimStatusPreferenceController extends BasePreferenceController {
44 
45     private static final String KEY_PREFERENCE_CATEGORY = "device_detail_category";
46 
47     private Fragment mFragment;
48     private SlotSimStatus mSlotSimStatus;
49     private Observer<LifecycleOwner> mLifecycleOwnerObserver;
50     private Observer mSimChangeObserver;
51 
SimStatusPreferenceController(Context context, String prefKey)52     public SimStatusPreferenceController(Context context, String prefKey) {
53         super(context, prefKey);
54     }
55 
56     /**
57      * Initialize this preference controller.
58      * @param fragment parent fragment
59      * @param slotSimStatus SlotSimStatus object
60      */
init(Fragment fragment, SlotSimStatus slotSimStatus)61     public void init(Fragment fragment, SlotSimStatus slotSimStatus) {
62         mFragment = fragment;
63         mSlotSimStatus = slotSimStatus;
64     }
65 
66     /**
67      * Get the index of slot for this subscription.
68      * @return index of slot
69      */
getSimSlotIndex()70     public int getSimSlotIndex() {
71         return mSlotSimStatus == null ? SubscriptionManager.INVALID_SIM_SLOT_INDEX :
72                 mSlotSimStatus.findSlotIndexByKey(getPreferenceKey());
73     }
74 
75     @Override
getAvailabilityStatus()76     public int getAvailabilityStatus() {
77         if (getSimSlotIndex() == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
78             return UNSUPPORTED_ON_DEVICE;
79         }
80         boolean isAvailable = SubscriptionUtil.isSimHardwareVisible(mContext) &&
81                 mContext.getSystemService(UserManager.class).isAdminUser() &&
82                 !Utils.isWifiOnly(mContext);
83         return isAvailable ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
84     }
85 
86     @Override
displayPreference(PreferenceScreen screen)87     public void displayPreference(PreferenceScreen screen) {
88         super.displayPreference(screen);
89         if ((!SubscriptionUtil.isSimHardwareVisible(mContext)) || (mSlotSimStatus == null)) {
90             return;
91         }
92         String basePreferenceKey = mSlotSimStatus.getPreferenceKey(
93                 SubscriptionManager.INVALID_SIM_SLOT_INDEX);
94         final Preference preference = screen.findPreference(basePreferenceKey);
95         if (!isAvailable() || preference == null || !preference.isVisible()) {
96             return;
97         }
98         final PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY);
99 
100         mSlotSimStatus.setBasePreferenceOrdering(preference.getOrder());
101         screen.removePreference(preference);
102         preference.setVisible(false);
103 
104         // Add additional preferences for each sim in the device
105         for (int simSlotNumber = 0; simSlotNumber < mSlotSimStatus.size(); simSlotNumber++) {
106             final Preference multiSimPreference = createNewPreference(screen.getContext());
107             multiSimPreference.setOrder(mSlotSimStatus.getPreferenceOrdering(simSlotNumber));
108             multiSimPreference.setKey(mSlotSimStatus.getPreferenceKey(simSlotNumber));
109             category.addPreference(multiSimPreference);
110         }
111     }
112 
113     @Override
updateState(Preference preference)114     public void updateState(Preference preference) {
115         if (mFragment == null) {
116             return;
117         }
118         if (mLifecycleOwnerObserver == null) {
119             final LiveData<LifecycleOwner> dataLifecycleOwner
120                     = mFragment.getViewLifecycleOwnerLiveData();
121             mLifecycleOwnerObserver = owner -> {
122                 if (owner != null) {
123                     final int simSlot = getSimSlotIndex();
124                     mSimChangeObserver = x -> updateStateBySlot(preference, simSlot);
125                     mSlotSimStatus.observe(owner, mSimChangeObserver);
126                 } else {
127                     if (mSimChangeObserver != null) {
128                         mSlotSimStatus.removeObserver(mSimChangeObserver);
129                         mSimChangeObserver = null;
130                     }
131                     dataLifecycleOwner.removeObserver(mLifecycleOwnerObserver);
132                 }
133             };
134             dataLifecycleOwner.observeForever(mLifecycleOwnerObserver);
135         } else if (mSimChangeObserver != null) {
136             final int simSlot = getSimSlotIndex();
137             updateStateBySlot(preference, simSlot);
138         }
139     }
140 
updateStateBySlot(Preference preference, int simSlot)141     protected void updateStateBySlot(Preference preference, int simSlot) {
142         SubscriptionInfo subInfo = getSubscriptionInfo(simSlot);
143         preference.setEnabled(subInfo != null);
144         preference.setCopyingEnabled(subInfo != null);
145         preference.setTitle(getPreferenceTitle(simSlot));
146         preference.setSummary(getCarrierName(simSlot));
147     }
148 
149     @Override
handlePreferenceTreeClick(Preference preference)150     public boolean handlePreferenceTreeClick(Preference preference) {
151         if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
152             return false;
153         }
154         final int simSlot = getSimSlotIndex();
155         if (simSlot == -1) {
156             return false;
157         }
158 
159         SimStatusDialogFragment.show(mFragment, simSlot, getPreferenceTitle(simSlot));
160         return true;
161     }
162 
getPreferenceTitle(int simSlot)163     private String getPreferenceTitle(int simSlot) {
164         return mSlotSimStatus.size() > 1 ? mContext.getString(
165                 R.string.sim_status_title_sim_slot, simSlot + 1) : mContext.getString(
166                 R.string.sim_status_title);
167     }
168 
getSubscriptionInfo(int simSlot)169     private SubscriptionInfo getSubscriptionInfo(int simSlot) {
170         return (mSlotSimStatus == null) ? null : mSlotSimStatus.getSubscriptionInfo(simSlot);
171     }
172 
getCarrierName(int simSlot)173     private CharSequence getCarrierName(int simSlot) {
174         SubscriptionInfo subInfo = getSubscriptionInfo(simSlot);
175         return (subInfo != null) ? subInfo.getCarrierName() :
176                 mContext.getText(R.string.device_info_not_available);
177     }
178 
179     @VisibleForTesting
createNewPreference(Context context)180     Preference createNewPreference(Context context) {
181         return new Preference(context);
182     }
183 
184     @Override
updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData)185     public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) {
186         int simSlot = getSimSlotIndex();
187         SubscriptionInfo subInfo = getSubscriptionInfo(simSlot);
188         if (subInfo == null) {
189             /**
190              * Only add to search when SIM is active
191              * (presented in SIM Slot Status as availavle.)
192              */
193             return;
194         }
195 
196         /* Have different search keywork when comes to eSIM */
197         int keywordId = subInfo.isEmbedded() ?
198                 R.string.keywords_sim_status_esim : R.string.keywords_sim_status;
199 
200         SearchIndexableRaw data = new SearchIndexableRaw(mContext);
201         data.key = getPreferenceKey();
202         data.title = getPreferenceTitle(simSlot);
203         data.screenTitle = mContext.getString(R.string.about_settings);
204         data.keywords = mContext.getString(keywordId).toString();
205         rawData.add(data);
206     }
207 }
208