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