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

Commit 1dd1b577 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add deviceId parameter to settings shell commands" into main

parents 031ed9b5 858f55b8
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -3215,7 +3215,9 @@ public class SettingsProvider extends ContentProvider {
    }

    private static boolean canUidAccessDeviceAwareSettings(int uid) {
        return uid == SYSTEM_UID || uid == SHELL_UID;
        // Allow root, system and shell (for testing) to access device-aware settings (i.e.,
        // settings for virtual devices).
        return uid == ROOT_UID || uid == SYSTEM_UID || uid == SHELL_UID;
    }

    final class SettingsRegistry {
+37 −18
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.providers.settings;

import android.app.ActivityManager;
import android.content.AttributionSource;
import android.content.Context;
import android.content.IContentProvider;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -110,6 +111,7 @@ final public class SettingsService extends Binder {
        }

        int mUser = UserHandle.USER_NULL;
        int mDeviceId = Context.DEVICE_ID_DEFAULT;
        CommandVerb mVerb = CommandVerb.UNSPECIFIED;
        String mTable = null;
        String mKey = null;
@@ -147,6 +149,16 @@ final public class SettingsService extends Binder {
                        perr.println("Invalid user: all");
                        return -1;
                    }
                } else if ("--deviceId".equals(arg)) {
                    if (mDeviceId != Context.DEVICE_ID_DEFAULT) {
                        perr.println("Invalid device: --deviceId specified more than once");
                        break;
                    }
                    try {
                        mDeviceId = Integer.parseInt(getNextArgRequired());
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Bad deviceId number: " + arg);
                    }
                } else if (mVerb == CommandVerb.UNSPECIFIED) {
                    if ("get".equalsIgnoreCase(arg)) {
                        mVerb = CommandVerb.GET;
@@ -249,15 +261,15 @@ final public class SettingsService extends Binder {
            final PrintWriter pout = getOutPrintWriter();
            switch (mVerb) {
                case GET:
                    pout.println(getForUser(iprovider, mUser, mTable, mKey));
                    pout.println(getForUser(iprovider, mUser, mDeviceId, mTable, mKey));
                    break;
                case PUT:
                    putForUser(iprovider, mUser, mTable, mKey, mValue, mTag, mMakeDefault,
                            mOverrideableByRestore);
                    putForUser(iprovider, mUser, mDeviceId, mTable, mKey, mValue, mTag,
                            mMakeDefault, mOverrideableByRestore);
                    break;
                case DELETE:
                    pout.println("Deleted "
                            + deleteForUser(iprovider, mUser, mTable, mKey) + " rows");
                            + deleteForUser(iprovider, mUser, mDeviceId, mTable, mKey) + " rows");
                    break;
                case LIST:
                    for (String line : listForUser(iprovider, mUser, mTable)) {
@@ -265,7 +277,7 @@ final public class SettingsService extends Binder {
                    }
                    break;
                case RESET:
                    resetForUser(iprovider, mUser, mTable, mTag);
                    resetForUser(iprovider, mUser, mDeviceId, mTable, mTag);
                    break;
                default:
                    perr.println("Unspecified command");
@@ -335,7 +347,7 @@ final public class SettingsService extends Binder {
            return lines;
        }

        String getForUser(IContentProvider provider, int userHandle,
        String getForUser(IContentProvider provider, int userHandle, int deviceId,
                final String table, final String key) {
            final String callGetCommand;
            if ("system".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SYSTEM;
@@ -351,7 +363,8 @@ final public class SettingsService extends Binder {
                Bundle arg = new Bundle();
                arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
                final AttributionSource attributionSource = new AttributionSource(
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null,
                        deviceId);
                Bundle b = provider.call(attributionSource, Settings.AUTHORITY,
                        callGetCommand, key, arg);
                if (b != null) {
@@ -363,7 +376,7 @@ final public class SettingsService extends Binder {
            return result;
        }

        void putForUser(IContentProvider provider, int userHandle, final String table,
        void putForUser(IContentProvider provider, int userHandle, int deviceId, final String table,
                final String key, final String value, String tag, boolean makeDefault,
                boolean overrideableByRestore) {
            Slog.v(LOG_TAG, "putForUser(userId=" + userHandle + ", table=" + table + ", key=" + key
@@ -398,7 +411,8 @@ final public class SettingsService extends Binder {
                    arg.putBoolean(Settings.CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY, true);
                }
                final AttributionSource attributionSource = new AttributionSource(
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null,
                        deviceId);
                provider.call(attributionSource, Settings.AUTHORITY,
                        callPutCommand, key, arg);
            } catch (RemoteException e) {
@@ -406,7 +420,7 @@ final public class SettingsService extends Binder {
            }
        }

        int deleteForUser(IContentProvider provider, int userHandle,
        int deleteForUser(IContentProvider provider, int userHandle, int deviceId,
                final String table, final String key) {
            final String callDeleteCommand;
            if ("system".equals(table)) {
@@ -424,7 +438,8 @@ final public class SettingsService extends Binder {
                Bundle arg = new Bundle();
                arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
                final AttributionSource attributionSource = new AttributionSource(
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null,
                        deviceId);
                Bundle result = provider.call(attributionSource, Settings.AUTHORITY,
                        callDeleteCommand, key, arg);
                return result.getInt(SettingsProvider.RESULT_ROWS_DELETED);
@@ -433,7 +448,7 @@ final public class SettingsService extends Binder {
            }
        }

        void resetForUser(IContentProvider provider, int userHandle,
        void resetForUser(IContentProvider provider, int userHandle, int deviceId,
                String table, String tag) {
            final String callResetCommand;
            if ("secure".equals(table)) callResetCommand = Settings.CALL_METHOD_RESET_SECURE;
@@ -450,10 +465,10 @@ final public class SettingsService extends Binder {
                if (tag != null) {
                    arg.putString(Settings.CALL_METHOD_TAG_KEY, tag);
                }
                String packageName = mPackageName != null ? mPackageName : resolveCallingPackage();
                arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
                final AttributionSource attributionSource = new AttributionSource(
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null);
                        Binder.getCallingUid(), resolveCallingPackage(), /*attributionTag*/ null,
                        deviceId);
                provider.call(attributionSource, Settings.AUTHORITY, callResetCommand, null, arg);
            } catch (RemoteException e) {
                throw new RuntimeException("Failed in IPC", e);
@@ -492,16 +507,20 @@ final public class SettingsService extends Binder {
                pw.println("Settings provider (settings) commands:");
                pw.println("  help");
                pw.println("      Print this help text.");
                pw.println("  get [--user <USER_ID> | current] NAMESPACE KEY");
                pw.println("  get [--user <USER_ID> | current] [--deviceId <DEVICE_ID> | 0]"
                        + " NAMESPACE KEY");
                pw.println("      Retrieve the current value of KEY.");
                pw.println("  put [--user <USER_ID> | current] NAMESPACE KEY VALUE [TAG] [default] [overrideableByRestore]");
                pw.println("  put [--user <USER_ID> | current] [--deviceId <DEVICE_ID> | 0]"
                        + " NAMESPACE KEY VALUE [TAG] [default] [overrideableByRestore]");
                pw.println("      Change the contents of KEY to VALUE.");
                pw.println("      TAG to associate with the setting (cannot be default or overrideableByRestore).");
                pw.println("      {default} to set as the default, case-insensitive only for global/secure namespace");
                pw.println("      {overrideableByRestore} to let the value be overridden by BackupManager on restore operations");
                pw.println("  delete [--user <USER_ID> | current] NAMESPACE KEY");
                pw.println("  delete [--user <USER_ID> | current] [--deviceId <DEVICE_ID> | 0]"
                        + " NAMESPACE KEY");
                pw.println("      Delete the entry for KEY.");
                pw.println("  reset [--user <USER_ID> | current] NAMESPACE {PACKAGE_NAME | RESET_MODE}");
                pw.println("  reset [--user <USER_ID> | current] [--deviceId <DEVICE_ID> | 0]"
                        + " NAMESPACE {PACKAGE_NAME | RESET_MODE}");
                pw.println("      Reset the global/secure table for a package with mode.");
                pw.println("      RESET_MODE is one of {untrusted_defaults, untrusted_clear, trusted_defaults}, case-insensitive");
                pw.println("  list [--user <USER_ID> | current] NAMESPACE");
+53 −30
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import org.junit.runner.RunWith;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
@@ -77,13 +78,7 @@ abstract class BaseSettingsProviderTest {
    }

    protected void setStringViaFrontEndApiSetting(int type, String name, String value, int userId) {
        setStringViaFrontEndApiSetting(type, name, value, userId, Context.DEVICE_ID_DEFAULT);
    }

    protected void setStringViaFrontEndApiSetting(int type, String name, String value, int userId,
            int deviceId) {
        ContentResolver contentResolver =
                getContext().createDeviceContext(deviceId).getContentResolver();
        ContentResolver contentResolver = getContext().getContentResolver();

        switch (type) {
            case SETTING_TYPE_GLOBAL: {
@@ -105,13 +100,7 @@ abstract class BaseSettingsProviderTest {
    }

    protected String getStringViaFrontEndApiSetting(int type, String name, int userId) {
        return getStringViaFrontEndApiSetting(type, name, userId, Context.DEVICE_ID_DEFAULT);
    }

    protected String getStringViaFrontEndApiSetting(int type, String name, int userId,
            int deviceId) {
        ContentResolver contentResolver = getContext().createDeviceContext(deviceId)
                .getContentResolver();
        ContentResolver contentResolver = getContext().getContentResolver();

        switch (type) {
            case SETTING_TYPE_GLOBAL: {
@@ -134,12 +123,6 @@ abstract class BaseSettingsProviderTest {

    protected Uri insertStringViaProviderApi(int type, String name, String value,
            boolean withTableRowUri) {
        return insertStringViaProviderApi(type, name, value, withTableRowUri,
                Context.DEVICE_ID_DEFAULT);
    }

    protected Uri insertStringViaProviderApi(int type, String name, String value,
            boolean withTableRowUri, int deviceId) {
        Uri uri = getBaseUriForType(type);
        if (withTableRowUri) {
            uri = Uri.withAppendedPath(uri, name);
@@ -148,7 +131,7 @@ abstract class BaseSettingsProviderTest {
        values.put(Settings.NameValueTable.NAME, name);
        values.put(Settings.NameValueTable.VALUE, value);

        return getContext().createDeviceContext(deviceId).getContentResolver().insert(uri, values);
        return getContext().getContentResolver().insert(uri, values);
    }

    protected int deleteStringViaProviderApi(int type, String name) {
@@ -307,30 +290,70 @@ abstract class BaseSettingsProviderTest {
        }
    }

    protected static String getSettingViaShell(int type, String name, int userId, int deviceId)
            throws Exception {
        byte[] result;
        switch (type) {
            case SETTING_TYPE_GLOBAL: {
                result = executeShellCommand("settings get --user " + userId + " --deviceId "
                        + deviceId + " global " + name);

            } break;

            case SETTING_TYPE_SECURE: {
                result = executeShellCommand("settings get --user " + userId + " --deviceId "
                        + deviceId + " secure " + name);
            } break;

            case SETTING_TYPE_SYSTEM: {
                result = executeShellCommand("settings get --user " + userId + " --deviceId "
                        + deviceId + " system " + name);
            } break;

            default: {
                throw new IllegalArgumentException("Invalid type: " + type);
            }
        }
        // Remove trailing line breaks from the output.
        return new String(result, StandardCharsets.UTF_8).replaceAll("\n", "");
    }

    protected static void setSettingViaShell(int type, String name, String value,
            boolean makeDefault) throws IOException {
        setSettingViaShell(type, name, value, null, makeDefault);
        setSettingViaShell(type, name, value, null /* token */, makeDefault);
    }

    protected static void setSettingViaShell(int type, String name, String value,
            String token, boolean makeDefault) throws IOException {
        setSettingViaShell(type, name, value, token, makeDefault, UserHandle.USER_SYSTEM,
                Context.DEVICE_ID_DEFAULT);
    }

    protected static void setSettingViaShell(int type, String name, String value,
            int userId, int deviceId) throws Exception {
        setSettingViaShell(type, name, value, null /* token */, true /* makeDefault */, userId,
                deviceId);
    }

    protected static void setSettingViaShell(int type, String name, String value,
            String token, boolean makeDefault, int userId, int deviceId) throws IOException {
        switch (type) {
            case SETTING_TYPE_GLOBAL: {
                executeShellCommand("settings put global " + name + " "
                        + value + (token != null ? " " + token : "")
                executeShellCommand("settings put --user " + userId + " --deviceId " + deviceId
                        + " global " + name + " " + value + (token != null ? " " + token : "")
                        + (makeDefault ? " default" : ""));

            } break;

            case SETTING_TYPE_SECURE: {
                executeShellCommand("settings put secure " + name + " "
                        + value + (token != null ? " " + token : "")
                executeShellCommand("settings put --user " + userId + " --deviceId " + deviceId
                        + " secure " + name + " " + value + (token != null ? " " + token : "")
                        + (makeDefault ? " default" : ""));
            } break;

            case SETTING_TYPE_SYSTEM: {
                executeShellCommand("settings put system " + name + " "
                        + value + (token != null ? " " + token : "")
                executeShellCommand("settings put --user " + userId + " --deviceId " + deviceId
                        + " system " + name + " " + value + (token != null ? " " + token : "")
                        + (makeDefault ? " default" : ""));
            } break;

@@ -384,9 +407,9 @@ abstract class BaseSettingsProviderTest {
        }
    }

    protected static void executeShellCommand(String command) throws IOException {
    private static byte[] executeShellCommand(String command) throws IOException {
        InputStream is = new FileInputStream(InstrumentationRegistry.getInstrumentation()
                .getUiAutomation().executeShellCommand(command).getFileDescriptor());
        Streams.readFully(is);
        return Streams.readFully(is);
    }
}
+95 −112

File changed.

Preview size limit exceeded, changes collapsed.