Implement support for method calls in the content tool.
$ content call
--uri content://com.example
--method methodname
[--arg optional_string_arg]
[--extra name:s:foo --extra value:i:0]
The URI is just used to resolve the provider. --extra has
the same syntax as --bind.
Change-Id: I98cb89f0174a00e7c29ca0d8c8d809d453de3623
This commit is contained in:
@@ -24,6 +24,7 @@ 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.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
@@ -102,6 +103,12 @@ public class Content {
|
||||
+ "equal to \"new_setting\" and sort the result by name in ascending order.\n"
|
||||
+ " adb shell content query --uri content://settings/secure --projection name:value"
|
||||
+ " --where \"name=\'new_setting\'\" --sort \"name ASC\"\n"
|
||||
+ "\n"
|
||||
+ "usage: adb shell content call --uri <URI> --method <METHOD> [--arg <ARG>]\n"
|
||||
+ " [--extra <BINDING> ...]\n"
|
||||
+ " <METHOD> is the name of a provider-defined method\n"
|
||||
+ " <ARG> is an optional string argument\n"
|
||||
+ " <BINDING> is like --bind above, typed data of the form <KEY>:{b,s,i,l,f,d}:<VAL>\n"
|
||||
+ "\n";
|
||||
|
||||
private static class Parser {
|
||||
@@ -109,12 +116,16 @@ public class Content {
|
||||
private static final String ARGUMENT_DELETE = "delete";
|
||||
private static final String ARGUMENT_UPDATE = "update";
|
||||
private static final String ARGUMENT_QUERY = "query";
|
||||
private static final String ARGUMENT_CALL = "call";
|
||||
private static final String ARGUMENT_WHERE = "--where";
|
||||
private static final String ARGUMENT_BIND = "--bind";
|
||||
private static final String ARGUMENT_URI = "--uri";
|
||||
private static final String ARGUMENT_USER = "--user";
|
||||
private static final String ARGUMENT_PROJECTION = "--projection";
|
||||
private static final String ARGUMENT_SORT = "--sort";
|
||||
private static final String ARGUMENT_METHOD = "--method";
|
||||
private static final String ARGUMENT_ARG = "--arg";
|
||||
private static final String ARGUMENT_EXTRA = "--extra";
|
||||
private static final String TYPE_BOOLEAN = "b";
|
||||
private static final String TYPE_STRING = "s";
|
||||
private static final String TYPE_INTEGER = "i";
|
||||
@@ -141,6 +152,8 @@ public class Content {
|
||||
return parseUpdateCommand();
|
||||
} else if (ARGUMENT_QUERY.equals(operation)) {
|
||||
return parseQueryCommand();
|
||||
} else if (ARGUMENT_CALL.equals(operation)) {
|
||||
return parseCallCommand();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported operation: " + operation);
|
||||
}
|
||||
@@ -228,6 +241,38 @@ public class Content {
|
||||
return new UpdateCommand(uri, userId, values, where);
|
||||
}
|
||||
|
||||
public CallCommand parseCallCommand() {
|
||||
String method = null;
|
||||
int userId = UserHandle.USER_OWNER;
|
||||
String arg = null;
|
||||
Uri uri = null;
|
||||
ContentValues values = new ContentValues();
|
||||
for (String argument; (argument = mTokenizer.nextArg())!= null;) {
|
||||
if (ARGUMENT_URI.equals(argument)) {
|
||||
uri = Uri.parse(argumentValueRequired(argument));
|
||||
} else if (ARGUMENT_USER.equals(argument)) {
|
||||
userId = Integer.parseInt(argumentValueRequired(argument));
|
||||
} else if (ARGUMENT_METHOD.equals(argument)) {
|
||||
method = argumentValueRequired(argument);
|
||||
} else if (ARGUMENT_ARG.equals(argument)) {
|
||||
arg = argumentValueRequired(argument);
|
||||
} else if (ARGUMENT_EXTRA.equals(argument)) {
|
||||
parseBindValue(values);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported argument: " + argument);
|
||||
}
|
||||
|
||||
}
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("Content provider URI not specified."
|
||||
+ " Did you specify --uri argument?");
|
||||
}
|
||||
if (method == null) {
|
||||
throw new IllegalArgumentException("Content provider method not specified.");
|
||||
}
|
||||
return new CallCommand(uri, userId, method, arg, values);
|
||||
}
|
||||
|
||||
public QueryCommand parseQueryCommand() {
|
||||
Uri uri = null;
|
||||
int userId = UserHandle.USER_OWNER;
|
||||
@@ -376,6 +421,43 @@ public class Content {
|
||||
}
|
||||
}
|
||||
|
||||
private static class CallCommand extends Command {
|
||||
final String mMethod, mArg;
|
||||
Bundle mExtras = null;
|
||||
|
||||
public CallCommand(Uri uri, int userId, String method, String arg, ContentValues values) {
|
||||
super(uri, userId);
|
||||
mMethod = method;
|
||||
mArg = arg;
|
||||
if (values != null) {
|
||||
mExtras = new Bundle();
|
||||
for (String key : values.keySet()) {
|
||||
final Object val = values.get(key);
|
||||
if (val instanceof String) {
|
||||
mExtras.putString(key, (String) val);
|
||||
} else if (val instanceof Float) {
|
||||
mExtras.putFloat(key, (Float) val);
|
||||
} else if (val instanceof Double) {
|
||||
mExtras.putDouble(key, (Double) val);
|
||||
} else if (val instanceof Boolean) {
|
||||
mExtras.putBoolean(key, (Boolean) val);
|
||||
} else if (val instanceof Integer) {
|
||||
mExtras.putInt(key, (Integer) val);
|
||||
} else if (val instanceof Long) {
|
||||
mExtras.putLong(key, (Long) val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExecute(IContentProvider provider) throws Exception {
|
||||
Bundle result = provider.call(null, mMethod, mArg, mExtras);
|
||||
final int size = result.size(); // unpack
|
||||
System.out.println("Result: " + result);
|
||||
}
|
||||
}
|
||||
|
||||
private static class QueryCommand extends DeleteCommand {
|
||||
final String[] mProjection;
|
||||
final String mSortOrder;
|
||||
|
||||
Reference in New Issue
Block a user