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

Commit cda0663e authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Enforce READ_EXTERNAL in Developer Options." into jb-dev

parents 53fa78fc caf15613
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -18,8 +18,4 @@
    <item
        android:id="@+id/storage_usb"
        android:title="@string/storage_menu_usb" />
    <item
        android:id="@+id/storage_enforce_read_external"
        android:title="@string/storage_menu_enforce_read_external"
        android:checkable="true" />
</menu>
+18 −2
Original line number Diff line number Diff line
@@ -1897,8 +1897,6 @@

    <!-- Storage setting.  Menu option for USB transfer settings [CHAR LIMIT=30]-->
    <string name="storage_menu_usb">USB computer connection</string>
    <!-- Storage setting.  Menu option to enforce read external storage permission. [CHAR LIMIT=30]-->
    <string name="storage_menu_enforce_read_external">Enforce read external</string>

    <!-- Storage setting.  Title for USB transfer settings [CHAR LIMIT=30]-->
    <string name="storage_title_usb">USB computer connection</string>
@@ -2799,6 +2797,24 @@
    <!-- Warning text to user about the implications of enabling USB debugging -->
    <string name="dev_settings_warning_message">These settings are intended for development use only.  They can cause your device and the applications on it to break or misbehave.</string>

    <!-- Title of checkbox setting that protects external storage. [CHAR LIMIT=32] -->
    <string name="enforce_read_external_title" product="nosdcard">Protect USB storage</string>
    <!-- Summary of checkbox setting that protects external storage. [CHAR LIMIT=64] -->
    <string name="enforce_read_external_summary" product="nosdcard">Apps must request permission to read USB storage</string>
    <!-- Title of dialog confirming that user wants to protect external storage. [CHAR LIMIT=32] -->
    <string name="enforce_read_external_confirm_title" product="nosdcard">Protect USB storage?</string>
    <!-- Message of dialog confirming that user wants to protect external storage. [CHAR LIMIT=NONE] -->
    <string name="enforce_read_external_confirm_message" product="nosdcard">When USB storage is protected, apps must request permission to read data from external storage.\n\nSome apps may not work until updated by their developers.</string>

    <!-- Title of checkbox setting that protects external storage. [CHAR LIMIT=32] -->
    <string name="enforce_read_external_title" product="default">Protect SD card</string>
    <!-- Summary of checkbox setting that protects external storage. [CHAR LIMIT=64] -->
    <string name="enforce_read_external_summary" product="default">Apps must request permission to read SD card</string>
    <!-- Title of dialog confirming that user wants to protect external storage. [CHAR LIMIT=32] -->
    <string name="enforce_read_external_confirm_title" product="default">Protect SD card?</string>
    <!-- Message of dialog confirming that user wants to protect external storage. [CHAR LIMIT=NONE] -->
    <string name="enforce_read_external_confirm_message" product="default">When SD card is protected, apps must request permission to read data from external storage.\n\nSome apps may not work until updated by their developers.</string>

    <!-- Title for the screen that lets the user choose a gadget to add to the home screen
         (or other screens that can host gadgets).  Note to translators: we're still determining
         the final name for Gadgets/Widgets, so please translate both for now. -->
+5 −0
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@
        android:entries="@array/hdcp_checking_titles"
        android:entryValues="@array/hdcp_checking_values" />

    <CheckBoxPreference
        android:key="enforce_read_external"
        android:title="@string/enforce_read_external_title"
        android:summary="@string/enforce_read_external_summary" />

    <PreferenceCategory android:key="debug_debugging_category"
            android:title="@string/debug_debugging_category">

+76 −4
Original line number Diff line number Diff line
@@ -16,17 +16,20 @@

package com.android.settings;

import java.util.ArrayList;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;

import android.app.ActionBar;
import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.backup.IBackupManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -45,12 +48,11 @@ import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.MultiCheckPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.HardwareRenderer;
import android.view.IWindowManager;
@@ -58,6 +60,8 @@ import android.view.View;
import android.widget.CompoundButton;
import android.widget.Switch;

import java.util.ArrayList;

/*
 * Displays preferences for application developers.
 */
@@ -70,6 +74,7 @@ public class DevelopmentSettings extends PreferenceFragment
    private static final String ALLOW_MOCK_LOCATION = "allow_mock_location";
    private static final String HDCP_CHECKING_KEY = "hdcp_checking";
    private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
    private static final String ENFORCE_READ_EXTERNAL = "enforce_read_external";
    private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
    private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";

@@ -97,6 +102,8 @@ public class DevelopmentSettings extends PreferenceFragment

    private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";

    private static final String TAG_CONFIRM_ENFORCE = "confirm_enforce";

    private static final int RESULT_DEBUG_APP = 1000;

    private IWindowManager mWindowManager;
@@ -109,6 +116,7 @@ public class DevelopmentSettings extends PreferenceFragment

    private CheckBoxPreference mEnableAdb;
    private CheckBoxPreference mKeepScreenOn;
    private CheckBoxPreference mEnforceReadExternal;
    private CheckBoxPreference mAllowMockLocation;
    private PreferenceScreen mPassword;

@@ -157,6 +165,7 @@ public class DevelopmentSettings extends PreferenceFragment

        mEnableAdb = findAndInitCheckboxPref(ENABLE_ADB);
        mKeepScreenOn = findAndInitCheckboxPref(KEEP_SCREEN_ON);
        mEnforceReadExternal = findAndInitCheckboxPref(ENFORCE_READ_EXTERNAL);
        mAllowMockLocation = findAndInitCheckboxPref(ALLOW_MOCK_LOCATION);
        mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
        mAllPrefs.add(mPassword);
@@ -302,12 +311,14 @@ public class DevelopmentSettings extends PreferenceFragment
    }

    private void updateAllOptions() {
        final ContentResolver cr = getActivity().getContentResolver();
        final Context context = getActivity();
        final ContentResolver cr = context.getContentResolver();
        mHaveDebugSettings = false;
        updateCheckBox(mEnableAdb, Settings.Secure.getInt(cr,
                Settings.Secure.ADB_ENABLED, 0) != 0);
        updateCheckBox(mKeepScreenOn, Settings.System.getInt(cr,
                Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
        updateCheckBox(mEnforceReadExternal, isPermissionEnforced(context, READ_EXTERNAL_STORAGE));
        updateCheckBox(mAllowMockLocation, Settings.Secure.getInt(cr,
                Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0);
        updateHdcpValues();
@@ -786,6 +797,12 @@ public class DevelopmentSettings extends PreferenceFragment
                    Settings.System.STAY_ON_WHILE_PLUGGED_IN, 
                    mKeepScreenOn.isChecked() ? 
                    (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
        } else if (preference == mEnforceReadExternal) {
            if (mEnforceReadExternal.isChecked()) {
                ConfirmEnforceFragment.show(this);
            } else {
                setPermissionEnforced(getActivity(), READ_EXTERNAL_STORAGE, false);
            }
        } else if (preference == mAllowMockLocation) {
            Settings.Secure.putInt(getActivity().getContentResolver(),
                    Settings.Secure.ALLOW_MOCK_LOCATION,
@@ -934,4 +951,59 @@ public class DevelopmentSettings extends PreferenceFragment
            return null;
        }
    }

    /**
     * Dialog to confirm enforcement of {@link #READ_EXTERNAL_STORAGE}.
     */
    public static class ConfirmEnforceFragment extends DialogFragment {
        public static void show(DevelopmentSettings parent) {
            final ConfirmEnforceFragment dialog = new ConfirmEnforceFragment();
            dialog.setTargetFragment(parent, 0);
            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_ENFORCE);
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final Context context = getActivity();

            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle(R.string.enforce_read_external_confirm_title);
            builder.setMessage(R.string.enforce_read_external_confirm_message);

            builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    setPermissionEnforced(context, READ_EXTERNAL_STORAGE, true);
                    ((DevelopmentSettings) getTargetFragment()).updateAllOptions();
                }
            });
            builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ((DevelopmentSettings) getTargetFragment()).updateAllOptions();
                }
            });

            return builder.create();
        }
    }

    private static boolean isPermissionEnforced(Context context, String permission) {
        try {
            return ActivityThread.getPackageManager().isPermissionEnforced(READ_EXTERNAL_STORAGE);
        } catch (RemoteException e) {
            throw new RuntimeException("Problem talking with PackageManager", e);
        }
    }

    private static void setPermissionEnforced(
            Context context, String permission, boolean enforced) {
        try {
            // TODO: offload to background thread
            ActivityThread.getPackageManager()
                    .setPermissionEnforced(READ_EXTERNAL_STORAGE, enforced);
        } catch (RemoteException e) {
            throw new RuntimeException("Problem talking with PackageManager", e);
        }
    }
}
+0 −29
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.settings.deviceinfo;

import static android.Manifest.permission.READ_EXTERNAL_STORAGE;

import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
@@ -26,7 +23,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Environment;
@@ -68,7 +64,6 @@ public class Memory extends SettingsPreferenceFragment {
    private IMountService mMountService = null;

    private StorageManager mStorageManager = null;
    private IPackageManager mPackageService;

    private StorageVolumePreferenceCategory mInternalStorageVolumePreferenceCategory;
    private StorageVolumePreferenceCategory[] mStorageVolumePreferenceCategories;
@@ -82,8 +77,6 @@ public class Memory extends SettingsPreferenceFragment {
            mStorageManager.registerListener(mStorageListener);
        }

        mPackageService = ActivityThread.getPackageManager();

        addPreferencesFromResource(R.xml.device_info_memory);

        mResources = getResources();
@@ -178,16 +171,6 @@ public class Memory extends SettingsPreferenceFragment {
    public void onPrepareOptionsMenu(Menu menu) {
        final MenuItem usb = menu.findItem(R.id.storage_usb);
        usb.setVisible(!isMassStorageEnabled());

        final boolean enforced;
        try {
            enforced = mPackageService.isPermissionEnforced(READ_EXTERNAL_STORAGE);
        } catch (RemoteException e) {
            throw new RuntimeException("Problem talking with PackageManager", e);
        }

        final MenuItem enforceReadExternal = menu.findItem(R.id.storage_enforce_read_external);
        enforceReadExternal.setChecked(enforced);
    }

    @Override
@@ -204,18 +187,6 @@ public class Memory extends SettingsPreferenceFragment {
                    startFragment(this, UsbSettings.class.getCanonicalName(), -1, null);
                }
                return true;
            case R.id.storage_enforce_read_external: {
                final boolean checked = !item.isChecked();
                item.setChecked(checked);

                try {
                    // TODO: offload to background thread
                    mPackageService.setPermissionEnforced(READ_EXTERNAL_STORAGE, checked);
                } catch (RemoteException e) {
                    throw new RuntimeException("Problem talking with PackageManager", e);
                }
                return true;
            }
        }
        return super.onOptionsItemSelected(item);
    }