• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.applications.specialaccess.premiumsms;
18 
19 import android.annotation.Nullable;
20 import android.app.Application;
21 import android.app.settings.SettingsEnums;
22 import android.content.Context;
23 import android.os.Bundle;
24 import android.provider.SearchIndexableResource;
25 import android.view.View;
26 
27 import androidx.annotation.VisibleForTesting;
28 import androidx.preference.DropDownPreference;
29 import androidx.preference.Preference;
30 import androidx.preference.Preference.OnPreferenceChangeListener;
31 import androidx.preference.PreferenceScreen;
32 import androidx.preference.PreferenceViewHolder;
33 
34 import com.android.internal.telephony.SmsUsageMonitor;
35 import com.android.settings.R;
36 import com.android.settings.applications.AppStateBaseBridge.Callback;
37 import com.android.settings.applications.AppStateSmsPremBridge;
38 import com.android.settings.applications.AppStateSmsPremBridge.SmsState;
39 import com.android.settings.overlay.FeatureFactory;
40 import com.android.settings.search.BaseSearchIndexProvider;
41 import com.android.settings.search.Indexable;
42 import com.android.settings.widget.EmptyTextSettings;
43 import com.android.settingslib.applications.ApplicationsState;
44 import com.android.settingslib.applications.ApplicationsState.AppEntry;
45 import com.android.settingslib.applications.ApplicationsState.Callbacks;
46 import com.android.settingslib.applications.ApplicationsState.Session;
47 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
48 import com.android.settingslib.search.SearchIndexable;
49 import com.android.settingslib.widget.FooterPreference;
50 
51 import java.util.ArrayList;
52 import java.util.List;
53 
54 @SearchIndexable
55 public class PremiumSmsAccess extends EmptyTextSettings
56         implements Callback, Callbacks, OnPreferenceChangeListener {
57 
58     private ApplicationsState mApplicationsState;
59     private AppStateSmsPremBridge mSmsBackend;
60     private Session mSession;
61 
62     @Override
onCreate(Bundle icicle)63     public void onCreate(Bundle icicle) {
64         super.onCreate(icicle);
65         mApplicationsState = ApplicationsState.getInstance((Application)
66                 getContext().getApplicationContext());
67         mSession = mApplicationsState.newSession(this, getSettingsLifecycle());
68         mSmsBackend = new AppStateSmsPremBridge(getContext(), mApplicationsState, this);
69     }
70 
71     @Override
onViewCreated(View view, @Nullable Bundle savedInstanceState)72     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
73         super.onViewCreated(view, savedInstanceState);
74         setLoading(true, false);
75     }
76 
77     @Override
onResume()78     public void onResume() {
79         super.onResume();
80         mSmsBackend.resume();
81     }
82 
83     @Override
onPause()84     public void onPause() {
85         mSmsBackend.pause();
86         super.onPause();
87     }
88 
89     @Override
onDestroy()90     public void onDestroy() {
91         mSmsBackend.release();
92         super.onDestroy();
93     }
94 
95     @Override
getPreferenceScreenResId()96     protected int getPreferenceScreenResId() {
97         return R.xml.premium_sms_settings;
98     }
99 
100     @Override
getMetricsCategory()101     public int getMetricsCategory() {
102         return SettingsEnums.PREMIUM_SMS_ACCESS;
103     }
104 
105     @Override
onPreferenceChange(Preference preference, Object newValue)106     public boolean onPreferenceChange(Preference preference, Object newValue) {
107         PremiumSmsPreference pref = (PremiumSmsPreference) preference;
108         int smsState = Integer.parseInt((String) newValue);
109         logSpecialPermissionChange(smsState, pref.mAppEntry.info.packageName);
110         mSmsBackend.setSmsState(pref.mAppEntry.info.packageName, smsState);
111         return true;
112     }
113 
114     @VisibleForTesting
logSpecialPermissionChange(int smsState, String packageName)115     void logSpecialPermissionChange(int smsState, String packageName) {
116         int category = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN;
117         switch (smsState) {
118             case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER:
119                 category = SettingsEnums.APP_SPECIAL_PERMISSION_PREMIUM_SMS_ASK;
120                 break;
121             case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW:
122                 category = SettingsEnums.APP_SPECIAL_PERMISSION_PREMIUM_SMS_DENY;
123                 break;
124             case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW:
125                 category = SettingsEnums.
126                         APP_SPECIAL_PERMISSION_PREMIUM_SMS_ALWAYS_ALLOW;
127                 break;
128         }
129         if (category != SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) {
130             // TODO(117860032): Category is wrong. It should be defined in SettingsEnums.
131             final MetricsFeatureProvider metricsFeatureProvider =
132                     FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider();
133             metricsFeatureProvider.action(
134                     metricsFeatureProvider.getAttribution(getActivity()),
135                     category,
136                     getMetricsCategory(),
137                     packageName,
138                     smsState);
139         }
140     }
141 
updatePrefs(ArrayList<AppEntry> apps)142     private void updatePrefs(ArrayList<AppEntry> apps) {
143         if (apps == null) return;
144         setEmptyText(R.string.premium_sms_none);
145         setLoading(false, true);
146         final PreferenceScreen screen = getPreferenceScreen();
147         screen.removeAll();
148         screen.setOrderingAsAdded(true);
149 
150         for (int i = 0; i < apps.size(); i++) {
151             final PremiumSmsPreference smsPreference =
152                     new PremiumSmsPreference(apps.get(i), getPrefContext());
153             smsPreference.setOnPreferenceChangeListener(this);
154             screen.addPreference(smsPreference);
155         }
156         if (apps.size() != 0) {
157             FooterPreference footer = new FooterPreference(getPrefContext());
158             footer.setTitle(R.string.premium_sms_warning);
159             screen.addPreference(footer);
160         }
161     }
162 
update()163     private void update() {
164         updatePrefs(mSession.rebuild(AppStateSmsPremBridge.FILTER_APP_PREMIUM_SMS,
165                 ApplicationsState.ALPHA_COMPARATOR));
166     }
167 
168     @Override
onExtraInfoUpdated()169     public void onExtraInfoUpdated() {
170         update();
171     }
172 
173     @Override
onRebuildComplete(ArrayList<AppEntry> apps)174     public void onRebuildComplete(ArrayList<AppEntry> apps) {
175         updatePrefs(apps);
176     }
177 
178     @Override
onRunningStateChanged(boolean running)179     public void onRunningStateChanged(boolean running) {
180 
181     }
182 
183     @Override
onPackageListChanged()184     public void onPackageListChanged() {
185 
186     }
187 
188     @Override
onPackageIconChanged()189     public void onPackageIconChanged() {
190 
191     }
192 
193     @Override
onPackageSizeChanged(String packageName)194     public void onPackageSizeChanged(String packageName) {
195 
196     }
197 
198     @Override
onAllSizesComputed()199     public void onAllSizesComputed() {
200 
201     }
202 
203     @Override
onLauncherInfoChanged()204     public void onLauncherInfoChanged() {
205 
206     }
207 
208     @Override
onLoadEntriesCompleted()209     public void onLoadEntriesCompleted() {
210 
211     }
212 
213     private class PremiumSmsPreference extends DropDownPreference {
214         private final AppEntry mAppEntry;
215 
PremiumSmsPreference(AppEntry appEntry, Context context)216         public PremiumSmsPreference(AppEntry appEntry, Context context) {
217             super(context);
218             mAppEntry = appEntry;
219             mAppEntry.ensureLabel(context);
220             setTitle(mAppEntry.label);
221             if (mAppEntry.icon != null) {
222                 setIcon(mAppEntry.icon);
223             }
224             setEntries(R.array.security_settings_premium_sms_values);
225             setEntryValues(new CharSequence[]{
226                     String.valueOf(SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER),
227                     String.valueOf(SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW),
228                     String.valueOf(SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW),
229             });
230             setValue(String.valueOf(getCurrentValue()));
231             setSummary("%s");
232         }
233 
getCurrentValue()234         private int getCurrentValue() {
235             return mAppEntry.extraInfo instanceof SmsState
236                     ? ((SmsState) mAppEntry.extraInfo).smsState
237                     : SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN;
238         }
239 
240         @Override
onBindViewHolder(PreferenceViewHolder holder)241         public void onBindViewHolder(PreferenceViewHolder holder) {
242             if (getIcon() == null) {
243                 holder.itemView.post(new Runnable() {
244                     @Override
245                     public void run() {
246                         mApplicationsState.ensureIcon(mAppEntry);
247                         setIcon(mAppEntry.icon);
248                     }
249                 });
250             }
251             super.onBindViewHolder(holder);
252         }
253     }
254 
255     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
256             new BaseSearchIndexProvider() {
257                 @Override
258                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
259                         boolean enabled) {
260                     final ArrayList<SearchIndexableResource> result = new ArrayList<>();
261 
262                     final SearchIndexableResource sir = new SearchIndexableResource(context);
263                     sir.xmlResId = R.xml.premium_sms_settings;
264                     result.add(sir);
265                     return result;
266                 }
267             };
268 }
269