Merge "Expand "extras" support in content tool." into rvc-dev am: cfeb0d8323 am: 8afffa8dcc

Change-Id: Ia33e90c5718c7d5dad006e6feca8bc47ec580cc6
This commit is contained in:
TreeHugger Robot
2020-03-26 06:57:27 +00:00
committed by Automerger Merge Worker

View File

@@ -32,8 +32,11 @@ import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Pair;
import java.io.FileDescriptor;
import java.util.ArrayList;
import java.util.List;
/**
* This class is a command line utility for manipulating content. A client
@@ -72,7 +75,7 @@ public class Content {
"usage: adb shell content [subcommand] [options]\n"
+ "\n"
+ "usage: adb shell content insert --uri <URI> [--user <USER_ID>]"
+ " --bind <BINDING> [--bind <BINDING>...]\n"
+ " --bind <BINDING> [--bind <BINDING>...] [--extra <BINDING>...]\n"
+ " <URI> a content provider URI.\n"
+ " <BINDING> binds a typed value to a column and is formatted:\n"
+ " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
@@ -84,7 +87,8 @@ public class Content {
+ " adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
+ " --bind value:s:new_value\n"
+ "\n"
+ "usage: adb shell content update --uri <URI> [--user <USER_ID>] [--where <WHERE>]\n"
+ "usage: adb shell content update --uri <URI> [--user <USER_ID>]"
+ " [--where <WHERE>] [--extra <BINDING>...]\n"
+ " <WHERE> is a SQL style where clause in quotes (You have to escape single quotes"
+ " - see example below).\n"
+ " Example:\n"
@@ -93,14 +97,15 @@ public class Content {
+ " value:s:newer_value --where \"name=\'new_setting\'\"\n"
+ "\n"
+ "usage: adb shell content delete --uri <URI> [--user <USER_ID>] --bind <BINDING>"
+ " [--bind <BINDING>...] [--where <WHERE>]\n"
+ " [--bind <BINDING>...] [--where <WHERE>] [--extra <BINDING>...]\n"
+ " Example:\n"
+ " # Remove \"new_setting\" secure setting.\n"
+ " adb shell content delete --uri content://settings/secure "
+ "--where \"name=\'new_setting\'\"\n"
+ "\n"
+ "usage: adb shell content query --uri <URI> [--user <USER_ID>]"
+ " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]\n"
+ " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]"
+ " [--extra <BINDING>...]\n"
+ " <PROJECTION> is a list of colon separated column names and is formatted:\n"
+ " <COLUMN_NAME>[:<COLUMN_NAME>...]\n"
+ " <SORT_ORDER> is the order in which rows in the result should be sorted.\n"
@@ -196,6 +201,7 @@ public class Content {
Uri uri = null;
int userId = UserHandle.USER_SYSTEM;
ContentValues values = new ContentValues();
Bundle extras = new Bundle();
for (String argument; (argument = mTokenizer.nextArg()) != null;) {
if (ARGUMENT_URI.equals(argument)) {
uri = Uri.parse(argumentValueRequired(argument));
@@ -203,6 +209,8 @@ public class Content {
userId = Integer.parseInt(argumentValueRequired(argument));
} else if (ARGUMENT_BIND.equals(argument)) {
parseBindValue(values);
} else if (ARGUMENT_EXTRA.equals(argument)) {
parseBindValue(extras);
} else {
throw new IllegalArgumentException("Unsupported argument: " + argument);
}
@@ -215,20 +223,23 @@ public class Content {
throw new IllegalArgumentException("Bindings not specified."
+ " Did you specify --bind argument(s)?");
}
return new InsertCommand(uri, userId, values);
return new InsertCommand(uri, userId, values, extras);
}
private DeleteCommand parseDeleteCommand() {
Uri uri = null;
int userId = UserHandle.USER_SYSTEM;
String where = null;
Bundle extras = new Bundle();
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_WHERE.equals(argument)) {
where = argumentValueRequired(argument);
extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
argumentValueRequired(argument));
} else if (ARGUMENT_EXTRA.equals(argument)) {
parseBindValue(extras);
} else {
throw new IllegalArgumentException("Unsupported argument: " + argument);
}
@@ -237,23 +248,26 @@ public class Content {
throw new IllegalArgumentException("Content provider URI not specified."
+ " Did you specify --uri argument?");
}
return new DeleteCommand(uri, userId, where);
return new DeleteCommand(uri, userId, extras);
}
private UpdateCommand parseUpdateCommand() {
Uri uri = null;
int userId = UserHandle.USER_SYSTEM;
String where = null;
ContentValues values = new ContentValues();
Bundle extras = new Bundle();
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_WHERE.equals(argument)) {
where = argumentValueRequired(argument);
extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
argumentValueRequired(argument));
} else if (ARGUMENT_BIND.equals(argument)) {
parseBindValue(values);
} else if (ARGUMENT_EXTRA.equals(argument)) {
parseBindValue(extras);
} else {
throw new IllegalArgumentException("Unsupported argument: " + argument);
}
@@ -266,7 +280,7 @@ public class Content {
throw new IllegalArgumentException("Bindings not specified."
+ " Did you specify --bind argument(s)?");
}
return new UpdateCommand(uri, userId, values, where);
return new UpdateCommand(uri, userId, values, extras);
}
public CallCommand parseCallCommand() {
@@ -274,7 +288,7 @@ public class Content {
int userId = UserHandle.USER_SYSTEM;
String arg = null;
Uri uri = null;
ContentValues values = new ContentValues();
Bundle extras = new Bundle();
for (String argument; (argument = mTokenizer.nextArg())!= null;) {
if (ARGUMENT_URI.equals(argument)) {
uri = Uri.parse(argumentValueRequired(argument));
@@ -285,11 +299,10 @@ public class Content {
} else if (ARGUMENT_ARG.equals(argument)) {
arg = argumentValueRequired(argument);
} else if (ARGUMENT_EXTRA.equals(argument)) {
parseBindValue(values);
parseBindValue(extras);
} else {
throw new IllegalArgumentException("Unsupported argument: " + argument);
}
}
if (uri == null) {
throw new IllegalArgumentException("Content provider URI not specified."
@@ -298,7 +311,7 @@ public class Content {
if (method == null) {
throw new IllegalArgumentException("Content provider method not specified.");
}
return new CallCommand(uri, userId, method, arg, values);
return new CallCommand(uri, userId, method, arg, extras);
}
private GetTypeCommand parseGetTypeCommand() {
@@ -363,19 +376,22 @@ public class Content {
Uri uri = null;
int userId = UserHandle.USER_SYSTEM;
String[] projection = null;
String sort = null;
String where = null;
Bundle extras = new Bundle();
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_WHERE.equals(argument)) {
where = argumentValueRequired(argument);
extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
argumentValueRequired(argument));
} else if (ARGUMENT_SORT.equals(argument)) {
sort = argumentValueRequired(argument);
extras.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER,
argumentValueRequired(argument));
} else if (ARGUMENT_PROJECTION.equals(argument)) {
projection = argumentValueRequired(argument).split("[\\s]*:[\\s]*");
} else if (ARGUMENT_EXTRA.equals(argument)) {
parseBindValue(extras);
} else {
throw new IllegalArgumentException("Unsupported argument: " + argument);
}
@@ -384,40 +400,76 @@ public class Content {
throw new IllegalArgumentException("Content provider URI not specified."
+ " Did you specify --uri argument?");
}
return new QueryCommand(uri, userId, projection, where, sort);
return new QueryCommand(uri, userId, projection, extras);
}
private void parseBindValue(ContentValues values) {
private List<String> splitWithEscaping(String argument, char splitChar) {
final List<String> res = new ArrayList<>();
final StringBuilder cur = new StringBuilder();
for (int i = 0; i < argument.length(); i++) {
char c = argument.charAt(i);
if (c == '\\') {
if (++i == argument.length()) {
throw new IllegalArgumentException("Invalid escaping");
} else {
// Skip escaping char and insert next
c = argument.charAt(i);
cur.append(c);
}
} else if (c == splitChar) {
// Splitting char means next string
res.add(cur.toString());
cur.setLength(0);
} else {
// Copy non-escaping and non-splitting char
cur.append(c);
}
}
res.add(cur.toString());
return res;
}
private Pair<String, Object> parseBindValue() {
String argument = mTokenizer.nextArg();
if (TextUtils.isEmpty(argument)) {
throw new IllegalArgumentException("Binding not well formed: " + argument);
}
final int firstColonIndex = argument.indexOf(COLON);
if (firstColonIndex < 0) {
final List<String> split = splitWithEscaping(argument, COLON.charAt(0));
if (split.size() != 3) {
throw new IllegalArgumentException("Binding not well formed: " + argument);
}
final int secondColonIndex = argument.indexOf(COLON, firstColonIndex + 1);
if (secondColonIndex < 0) {
throw new IllegalArgumentException("Binding not well formed: " + argument);
}
String column = argument.substring(0, firstColonIndex);
String type = argument.substring(firstColonIndex + 1, secondColonIndex);
String value = argument.substring(secondColonIndex + 1);
String column = split.get(0);
String type = split.get(1);
String value = split.get(2);
if (TYPE_STRING.equals(type)) {
values.put(column, value);
return Pair.create(column, value);
} else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
values.put(column, Boolean.parseBoolean(value));
} else if (TYPE_INTEGER.equalsIgnoreCase(type) || TYPE_LONG.equalsIgnoreCase(type)) {
values.put(column, Long.parseLong(value));
} else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) {
values.put(column, Double.parseDouble(value));
return Pair.create(column, Boolean.parseBoolean(value));
} else if (TYPE_INTEGER.equalsIgnoreCase(type)) {
return Pair.create(column, Integer.parseInt(value));
} else if (TYPE_LONG.equalsIgnoreCase(type)) {
return Pair.create(column, Long.parseLong(value));
} else if (TYPE_FLOAT.equalsIgnoreCase(type)) {
return Pair.create(column, Float.parseFloat(value));
} else if (TYPE_DOUBLE.equalsIgnoreCase(type)) {
return Pair.create(column, Double.parseDouble(value));
} else if (TYPE_NULL.equalsIgnoreCase(type)) {
values.putNull(column);
return Pair.create(column, null);
} else {
throw new IllegalArgumentException("Unsupported type: " + type);
}
}
private void parseBindValue(ContentValues values) {
final Pair<String, Object> columnValue = parseBindValue();
values.putObject(columnValue.first, columnValue.second);
}
private void parseBindValue(Bundle extras) {
final Pair<String, Object> columnValue = parseBindValue();
extras.putObject(columnValue.first, columnValue.second);
}
private String argumentValueRequired(String argument) {
String value = mTokenizer.nextArg();
if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) {
@@ -500,60 +552,43 @@ public class Content {
private static class InsertCommand extends Command {
final ContentValues mContentValues;
final Bundle mExtras;
public InsertCommand(Uri uri, int userId, ContentValues contentValues) {
public InsertCommand(Uri uri, int userId, ContentValues contentValues, Bundle extras) {
super(uri, userId);
mContentValues = contentValues;
mExtras = extras;
}
@Override
public void onExecute(IContentProvider provider) throws Exception {
provider.insert(resolveCallingPackage(), null, mUri, mContentValues, null);
provider.insert(resolveCallingPackage(), null, mUri, mContentValues, mExtras);
}
}
private static class DeleteCommand extends Command {
final String mWhere;
final Bundle mExtras;
public DeleteCommand(Uri uri, int userId, String where) {
public DeleteCommand(Uri uri, int userId, Bundle extras) {
super(uri, userId);
mWhere = where;
mExtras = extras;
}
@Override
public void onExecute(IContentProvider provider) throws Exception {
provider.delete(resolveCallingPackage(), null, mUri,
ContentResolver.createSqlQueryBundle(mWhere, null));
provider.delete(resolveCallingPackage(), null, mUri, mExtras);
}
}
private static class CallCommand extends Command {
final String mMethod, mArg;
Bundle mExtras = null;
final Bundle mExtras;
public CallCommand(Uri uri, int userId, String method, String arg, ContentValues values) {
public CallCommand(Uri uri, int userId, String method, String arg, Bundle extras) {
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);
}
}
}
mExtras = extras;
}
@Override
@@ -604,21 +639,20 @@ public class Content {
}
}
private static class QueryCommand extends DeleteCommand {
private static class QueryCommand extends Command {
final String[] mProjection;
final String mSortOrder;
final Bundle mExtras;
public QueryCommand(
Uri uri, int userId, String[] projection, String where, String sortOrder) {
super(uri, userId, where);
public QueryCommand(Uri uri, int userId, String[] projection, Bundle extras) {
super(uri, userId);
mProjection = projection;
mSortOrder = sortOrder;
mExtras = extras;
}
@Override
public void onExecute(IContentProvider provider) throws Exception {
Cursor cursor = provider.query(resolveCallingPackage(), null, mUri, mProjection,
ContentResolver.createSqlQueryBundle(mWhere, null, mSortOrder), null);
mExtras, null);
if (cursor == null) {
System.out.println("No result found.");
return;
@@ -670,18 +704,19 @@ public class Content {
}
}
private static class UpdateCommand extends InsertCommand {
final String mWhere;
private static class UpdateCommand extends Command {
final ContentValues mValues;
final Bundle mExtras;
public UpdateCommand(Uri uri, int userId, ContentValues contentValues, String where) {
super(uri, userId, contentValues);
mWhere = where;
public UpdateCommand(Uri uri, int userId, ContentValues values, Bundle extras) {
super(uri, userId);
mValues = values;
mExtras = extras;
}
@Override
public void onExecute(IContentProvider provider) throws Exception {
provider.update(resolveCallingPackage(), null, mUri, mContentValues,
ContentResolver.createSqlQueryBundle(mWhere, null));
provider.update(resolveCallingPackage(), null, mUri, mValues, mExtras);
}
}