diff options
author | Christopher Tate <ctate@google.com> | 2012-10-08 14:56:52 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2012-10-08 18:39:27 -0700 |
commit | af75948cddd40a0fde5af051b700306744eae64c (patch) | |
tree | 947f62cf61241b528b0dfa2d7e7ac9dda00fd3f2 /cmds | |
parent | bd03f5abb7bbd5552d49dfec4e78f3d9454238af (diff) | |
download | frameworks_base-af75948cddd40a0fde5af051b700306744eae64c.zip frameworks_base-af75948cddd40a0fde5af051b700306744eae64c.tar.gz frameworks_base-af75948cddd40a0fde5af051b700306744eae64c.tar.bz2 |
New command line tool: "settings"
Because the usual content provider interface doesn't allow specification of
the target user under which to perform settings reads/writes, this CL introduces
a new command line app specifically for that.
Usage:
settings [--user num] get namespace key
settings [--user num] put namespace key value
If a --user argument is not given, the owner user is targetted.
Bug 7299066
Change-Id: I73108bb76b04fad133cc4e0f218d64490de549f1
Diffstat (limited to 'cmds')
-rw-r--r-- | cmds/settings/Android.mk | 18 | ||||
-rwxr-xr-x | cmds/settings/settings | 5 | ||||
-rw-r--r-- | cmds/settings/src/com/android/commands/settings/SettingsCmd.java | 220 |
3 files changed, 243 insertions, 0 deletions
diff --git a/cmds/settings/Android.mk b/cmds/settings/Android.mk new file mode 100644 index 0000000..05deb99 --- /dev/null +++ b/cmds/settings/Android.mk @@ -0,0 +1,18 @@ +# Copyright 2011 The Android Open Source Project +# +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) +LOCAL_MODULE := settings +LOCAL_MODULE_TAGS := optional +include $(BUILD_JAVA_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := settings +LOCAL_SRC_FILES := settings +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) + + diff --git a/cmds/settings/settings b/cmds/settings/settings new file mode 100755 index 0000000..ef459ca --- /dev/null +++ b/cmds/settings/settings @@ -0,0 +1,5 @@ +# Script to start "settings" on the device +# +base=/system +export CLASSPATH=$base/framework/settings.jar +exec app_process $base/bin com.android.commands.settings.SettingsCmd "$@" diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java new file mode 100644 index 0000000..0c69f01 --- /dev/null +++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2012 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.commands.settings; + +import android.app.ActivityManagerNative; +import android.app.IActivityManager; +import android.app.IActivityManager.ContentProviderHolder; +import android.content.IContentProvider; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.UserHandle; +import android.provider.Settings; + +public final class SettingsCmd { + static final String TAG = "settings"; + + enum CommandVerb { + UNSPECIFIED, + GET, + PUT + } + + static String[] mArgs; + int mNextArg; + int mUser = -1; // unspecified + CommandVerb mVerb = CommandVerb.UNSPECIFIED; + String mTable = null; + String mKey = null; + String mValue = null; + + public static void main(String[] args) { + if (args == null || args.length < 3) { + printUsage(); + return; + } + + mArgs = args; + try { + new SettingsCmd().run(); + } catch (Exception e) { + System.err.println("Unable to run settings command"); + } + } + + public void run() { + boolean valid = false; + String arg; + try { + while ((arg = nextArg()) != null) { + if ("--user".equals(arg)) { + if (mUser != -1) { + // --user specified more than once; invalid + break; + } + mUser = Integer.parseInt(nextArg()); + } else if (mVerb == CommandVerb.UNSPECIFIED) { + if ("get".equalsIgnoreCase(arg)) { + mVerb = CommandVerb.GET; + } else if ("put".equalsIgnoreCase(arg)) { + mVerb = CommandVerb.PUT; + } else { + // invalid + System.err.println("Invalid command: " + arg); + break; + } + } else if (mTable == null) { + if (!"system".equalsIgnoreCase(arg) + && !"secure".equalsIgnoreCase(arg) + && !"global".equalsIgnoreCase(arg)) { + System.err.println("Invalid namespace '" + arg + "'"); + break; // invalid + } + mTable = arg.toLowerCase(); + } else if (mVerb == CommandVerb.GET) { + mKey = arg; + if (mNextArg >= mArgs.length) { + valid = true; + } else { + System.err.println("Too many arguments"); + } + break; + } else if (mKey == null) { + mKey = arg; + // keep going; there's another PUT arg + } else { // PUT, final arg + mValue = arg; + if (mNextArg >= mArgs.length) { + valid = true; + } else { + System.err.println("Too many arguments"); + } + break; + } + } + } catch (Exception e) { + valid = false; + } + + if (valid) { + if (mUser < 0) { + mUser = UserHandle.USER_OWNER; + } + + try { + IActivityManager activityManager = ActivityManagerNative.getDefault(); + IContentProvider provider = null; + IBinder token = new Binder(); + try { + ContentProviderHolder holder = activityManager.getContentProviderExternal( + "settings", UserHandle.USER_OWNER, token); + if (holder == null) { + throw new IllegalStateException("Could not find settings provider"); + } + provider = holder.provider; + + switch (mVerb) { + case GET: + System.out.println(getForUser(provider, mUser, mTable, mKey)); + break; + case PUT: + putForUser(provider, mUser, mTable, mKey, mValue); + break; + default: + System.err.println("Unspecified command"); + break; + } + + } finally { + if (provider != null) { + activityManager.removeContentProviderExternal("settings", token); + } + } + } catch (Exception e) { + System.err.println("Error while accessing settings provider"); + e.printStackTrace(); + } + + } else { + printUsage(); + } + } + + private String nextArg() { + if (mNextArg >= mArgs.length) { + return null; + } + String arg = mArgs[mNextArg]; + mNextArg++; + return arg; + } + + String getForUser(IContentProvider provider, int userHandle, + final String table, final String key) { + final String callGetCommand; + if ("system".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SYSTEM; + else if ("secure".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SECURE; + else if ("global".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_GLOBAL; + else { + System.err.println("Invalid table; no put performed"); + throw new IllegalArgumentException("Invalid table " + table); + } + + String result = null; + try { + Bundle arg = new Bundle(); + arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle); + Bundle b = provider.call(callGetCommand, key, arg); + if (b != null) { + result = b.getPairValue(); + } + } catch (RemoteException e) { + System.err.println("Can't read key " + key + " in " + table + " for user " + userHandle); + } + return result; + } + + void putForUser(IContentProvider provider, int userHandle, + final String table, final String key, final String value) { + final String callPutCommand; + if ("system".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM; + else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE; + else if ("global".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_GLOBAL; + else { + System.err.println("Invalid table; no put performed"); + return; + } + + try { + Bundle arg = new Bundle(); + arg.putString(Settings.NameValueTable.VALUE, value); + arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle); + provider.call(callPutCommand, key, arg); + } catch (RemoteException e) { + System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle); + } + } + + private static void printUsage() { + System.err.println("usage: settings [--user NUM] get namespace key"); + System.err.println(" settings [--user NUM] put namespace key value"); + System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive"); + System.err.println("If '--user NUM' is not given, the operations are performed on the owner user."); + } +} |