--- /dev/null
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.applications;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import com.android.internal.telephony.ISms;
+import com.android.internal.telephony.SmsUsageMonitor;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
+
+import java.util.ArrayList;
+
+/**
+ * Connects the info provided by ApplicationsState and premium sms permission state.
+ */
+public class AppStateSmsPremBridge extends AppStateBaseBridge {
+
+ private final Context mContext;
+ private final ISms mSmsManager;
+
+ public AppStateSmsPremBridge(Context context, ApplicationsState appState, Callback callback) {
+ super(appState, callback);
+ mContext = context;
+ mSmsManager = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ }
+
+ @Override
+ protected void loadAllExtraInfo() {
+ ArrayList<AppEntry> apps = mAppSession.getAllApps();
+ final int N = apps.size();
+ for (int i = 0; i < N; i++) {
+ AppEntry app = apps.get(i);
+ updateExtraInfo(app, app.info.packageName, app.info.uid);
+ }
+ }
+
+ @Override
+ protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
+ app.extraInfo = getState(pkg);
+ }
+
+ public SmsState getState(String pkg) {
+ final SmsState state = new SmsState();
+ state.smsState = getSmsState(pkg);
+ return state;
+ }
+
+ private int getSmsState(String pkg) {
+ try {
+ return mSmsManager.getPremiumSmsPermission(pkg);
+ } catch (RemoteException e) {
+ return SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN;
+ }
+ }
+
+ public void setSmsState(String pkg, int state) {
+ try {
+ mSmsManager.setPremiumSmsPermission(pkg, state);
+ } catch (RemoteException e) {
+ }
+ }
+
+ public static class SmsState {
+ public int smsState;
+
+ public boolean isGranted() {
+ return smsState == SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW;
+ }
+ }
+
+ public static final AppFilter FILTER_APP_PREMIUM_SMS = new AppFilter() {
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public boolean filterApp(AppEntry info) {
+ return info.extraInfo instanceof SmsState && ((SmsState) info.extraInfo).smsState
+ != SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN;
+ }
+ };
+}
--- /dev/null
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.annotation.Nullable;
+import android.app.Application;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.DropDownPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.View;
+import com.android.internal.logging.MetricsProto;
+import com.android.internal.telephony.SmsUsageMonitor;
+import com.android.settings.DividerPreference;
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
+import com.android.settings.applications.AppStateBaseBridge.Callback;
+import com.android.settings.applications.AppStateSmsPremBridge.SmsState;
+import com.android.settings.notification.EmptyTextSettings;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.Callbacks;
+import com.android.settingslib.applications.ApplicationsState.Session;
+
+import java.util.ArrayList;
+
+public class PremiumSmsAccess extends EmptyTextSettings implements Callback, Callbacks, OnPreferenceChangeListener {
+
+ private ApplicationsState mApplicationsState;
+ private AppStateSmsPremBridge mSmsBackend;
+ private Session mSession;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mApplicationsState = ApplicationsState.getInstance((Application)
+ getContext().getApplicationContext());
+ mSession = mApplicationsState.newSession(this);
+ mSmsBackend = new AppStateSmsPremBridge(getContext(), mApplicationsState, this);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ setLoading(true, false);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mSession.resume();
+ mSmsBackend.resume();
+ }
+
+ @Override
+ public void onPause() {
+ mSmsBackend.pause();
+ mSession.pause();
+ super.onPause();
+ }
+
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.PREMIUM_SMS_ACCESS;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ PremiumSmsPreference pref = (PremiumSmsPreference) preference;
+ mSmsBackend.setSmsState(pref.mAppEntry.info.packageName,
+ Integer.parseInt((String) newValue));
+ return true;
+ }
+
+ private void updatePrefs(ArrayList<AppEntry> apps) {
+ if (apps == null) return;
+ setEmptyText(R.string.premium_sms_none);
+ setLoading(false, true);
+ final PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(
+ getPrefContext());
+ screen.setOrderingAsAdded(true);
+
+ for (int i = 0; i < apps.size(); i++) {
+ final PremiumSmsPreference smsPreference =
+ new PremiumSmsPreference(apps.get(i), getPrefContext());
+ smsPreference.setOnPreferenceChangeListener(this);
+ screen.addPreference(smsPreference);
+ }
+ if (apps.size() != 0) {
+ DividerPreference summary = new DividerPreference(getPrefContext());
+ summary.setSelectable(false);
+ summary.setSummary(R.string.premium_sms_warning);
+ summary.setDividerAllowedAbove(true);
+ screen.addPreference(summary);
+ }
+
+ setPreferenceScreen(screen);
+ }
+
+ private void update() {
+ updatePrefs(mSession.rebuild(AppStateSmsPremBridge.FILTER_APP_PREMIUM_SMS,
+ ApplicationsState.ALPHA_COMPARATOR));
+ }
+
+ @Override
+ public void onExtraInfoUpdated() {
+ update();
+ }
+
+ @Override
+ public void onRebuildComplete(ArrayList<AppEntry> apps) {
+ updatePrefs(apps);
+ }
+
+ @Override
+ public void onRunningStateChanged(boolean running) {
+
+ }
+
+ @Override
+ public void onPackageListChanged() {
+
+ }
+
+ @Override
+ public void onPackageIconChanged() {
+
+ }
+
+ @Override
+ public void onPackageSizeChanged(String packageName) {
+
+ }
+
+ @Override
+ public void onAllSizesComputed() {
+
+ }
+
+ @Override
+ public void onLauncherInfoChanged() {
+
+ }
+
+ @Override
+ public void onLoadEntriesCompleted() {
+
+ }
+
+ private class PremiumSmsPreference extends DropDownPreference {
+ private final AppEntry mAppEntry;
+
+ public PremiumSmsPreference(AppEntry appEntry, Context context) {
+ super(context);
+ mAppEntry = appEntry;
+ mAppEntry.ensureLabel(context);
+ setTitle(mAppEntry.label);
+ if (mAppEntry.icon != null) {
+ setIcon(mAppEntry.icon);
+ }
+ setEntries(R.array.security_settings_premium_sms_values);
+ setEntryValues(new CharSequence[] {
+ String.valueOf(SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER),
+ String.valueOf(SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW),
+ String.valueOf(SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW),
+ });
+ setValue(String.valueOf(getCurrentValue()));
+ setSummary("%s");
+ }
+
+ private int getCurrentValue() {
+ return mAppEntry.extraInfo instanceof SmsState
+ ? ((SmsState) mAppEntry.extraInfo).smsState
+ : SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ if (getIcon() == null) {
+ holder.itemView.post(new Runnable() {
+ @Override
+ public void run() {
+ mApplicationsState.ensureIcon(mAppEntry);
+ setIcon(mAppEntry.icon);
+ }
+ });
+ }
+ super.onBindViewHolder(holder);
+ }
+ }
+}