Skip to content
Snippets Groups Projects
Commit a59ddd79 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Switch settings command to use "cmd" call on service."

parents 10398dfb 1d44c243
No related branches found
No related tags found
No related merge requests found
......@@ -3,11 +3,6 @@
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
......
# 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 "$@"
#!/system/bin/sh
cmd settings "$@"
/*
* 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.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public final class SettingsCmd {
enum CommandVerb {
UNSPECIFIED,
GET,
PUT,
DELETE,
LIST,
}
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 < 2) {
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;
}
arg = nextArg();
if ("current".equals(arg) || "cur".equals(arg)) {
mUser = UserHandle.USER_CURRENT;
} else {
mUser = Integer.parseInt(arg);
}
} else if (mVerb == CommandVerb.UNSPECIFIED) {
if ("get".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.GET;
} else if ("put".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.PUT;
} else if ("delete".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.DELETE;
} else if ("list".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.LIST;
} 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();
if (mVerb == CommandVerb.LIST) {
valid = true;
break;
}
} else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
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) {
try {
IActivityManager activityManager = ActivityManagerNative.getDefault();
if (mUser == UserHandle.USER_CURRENT) {
mUser = activityManager.getCurrentUser().id;
}
if (mUser < 0) {
mUser = UserHandle.USER_SYSTEM;
}
IContentProvider provider = null;
IBinder token = new Binder();
try {
ContentProviderHolder holder = activityManager.getContentProviderExternal(
"settings", UserHandle.USER_SYSTEM, 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;
case DELETE:
System.out.println("Deleted "
+ deleteForUser(provider, mUser, mTable, mKey) + " rows");
break;
case LIST:
for (String line : listForUser(provider, mUser, mTable)) {
System.out.println(line);
}
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 List<String> listForUser(IContentProvider provider, int userHandle, String table) {
final Uri uri = "system".equals(table) ? Settings.System.CONTENT_URI
: "secure".equals(table) ? Settings.Secure.CONTENT_URI
: "global".equals(table) ? Settings.Global.CONTENT_URI
: null;
final ArrayList<String> lines = new ArrayList<String>();
if (uri == null) {
return lines;
}
try {
final Cursor cursor = provider.query(resolveCallingPackage(), uri, null, null, null,
null, null);
try {
while (cursor != null && cursor.moveToNext()) {
lines.add(cursor.getString(1) + "=" + cursor.getString(2));
}
} finally {
if (cursor != null) {
cursor.close();
}
}
Collections.sort(lines);
} catch (RemoteException e) {
System.err.println("List failed in " + table + " for user " + userHandle);
}
return lines;
}
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(resolveCallingPackage(), 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(resolveCallingPackage(), callPutCommand, key, arg);
} catch (RemoteException e) {
System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle);
}
}
int deleteForUser(IContentProvider provider, int userHandle,
final String table, final String key) {
Uri targetUri;
if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
else {
System.err.println("Invalid table; no delete performed");
throw new IllegalArgumentException("Invalid table " + table);
}
int num = 0;
try {
num = provider.delete(resolveCallingPackage(), targetUri, null, null);
} catch (RemoteException e) {
System.err.println("Can't clear key " + key + " in " + table + " for user "
+ userHandle);
}
return num;
}
private static void printUsage() {
System.err.println("usage: settings [--user <USER_ID> | current] get namespace key");
System.err.println(" settings [--user <USER_ID> | current] put namespace key value");
System.err.println(" settings [--user <USER_ID> | current] delete namespace key");
System.err.println(" settings [--user <USER_ID> | current] list namespace");
System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
System.err.println("If '--user <USER_ID> | current' is not given, the operations are "
+ "performed on the system user.");
}
public static String resolveCallingPackage() {
switch (android.os.Process.myUid()) {
case Process.ROOT_UID: {
return "root";
}
case Process.SHELL_UID: {
return "com.android.shell";
}
default: {
return null;
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment