Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8bce66c authored by Jason Monk's avatar Jason Monk Committed by Android (Google) Code Review
Browse files

Merge "Restore the premiume SMS Preference." into nyc-dev

parents 37afa286 ea35f873
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -7372,4 +7372,13 @@
    <!-- Title of developer options to set the smallest width of the screen [CHAR LIMIT=60]-->
    <string name="developer_smallest_width">Smallest width</string>
    <!-- Message shown when there are no premium SMS apps [CHAR LIMIT=NONE] -->
    <string name="premium_sms_none">No installed apps have requested Premium SMS access</string>
    <!-- Warning message shown between options to enable Premium SMS for an app [CHAR LIMIT=NONE] -->
    <string name="premium_sms_warning">Premium SMS may cost you money and will add up to your carrier bills. If you enable permission for an app, you will be able to send premium SMS using that app.</string>
    <!-- Title of screen controlling which apps have access to send premium SMS messages [CHAR LIMIT=60] -->
    <string name="premium_sms_access">Premium SMS access</string>
</resources>
+5 −0
Original line number Diff line number Diff line
@@ -73,6 +73,11 @@
        android:title="@string/manage_notification_access_title"
        android:fragment="com.android.settings.notification.NotificationAccessSettings" />

    <PreferenceScreen
        android:key="premium_sms"
        android:title="@string/premium_sms_access"
        android:fragment="com.android.settings.applications.PremiumSmsAccess" />

    <PreferenceScreen
        android:key="data_saver"
        android:title="@string/unrestricted_data_saver"
+14 −0
Original line number Diff line number Diff line
@@ -36,6 +36,20 @@ public class DividerPreference extends Preference {
        }
    }

    public DividerPreference(Context context) {
        this(context, null);
    }

    public void setDividerAllowedAbove(boolean allowed) {
        mAllowAbove = allowed;
        notifyChanged();
    }

    public void setDividerAllowedBelow(boolean allowed) {
        mAllowBelow = allowed;
        notifyChanged();
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
+96 −0
Original line number Diff line number Diff line
/*
 * 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;
        }
    };
}
+207 −0
Original line number Diff line number Diff line
/*
 * 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);
        }
    }
}