summaryrefslogtreecommitdiffstats
path: root/cmds/content/src
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2014-04-15 11:36:20 -0400
committerJohn Spurlock <jspurlock@google.com>2014-04-15 19:28:08 -0400
commitcee823e4d4d3a7217cbaf8fcdd10da7999881290 (patch)
treeff7b6a024bc52516e65dc92c96c3335824a8c9c0 /cmds/content/src
parent1c3f409284b47312c1c7e5d36283df9a05d29dfb (diff)
downloadframeworks_base-cee823e4d4d3a7217cbaf8fcdd10da7999881290.zip
frameworks_base-cee823e4d4d3a7217cbaf8fcdd10da7999881290.tar.gz
frameworks_base-cee823e4d4d3a7217cbaf8fcdd10da7999881290.tar.bz2
Add 'read' subcommand to the 'content' tool.
Access raw content exposed by content provider openFile uris. Bug:14079104 Change-Id: I9ef0e19f9354fa12408df1583b211a8d8a2e9fdb
Diffstat (limited to 'cmds/content/src')
-rw-r--r--cmds/content/src/com/android/commands/content/Content.java61
1 files changed, 61 insertions, 0 deletions
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 466dcd4..948c9a2 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -26,9 +26,17 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.text.TextUtils;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import libcore.io.IoUtils;
+
/**
* This class is a command line utility for manipulating content. A client
* can insert, update, and remove records in a content provider. For example,
@@ -109,6 +117,12 @@ public class Content {
+ " <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"
+ + "usage: adb shell content read --uri <URI> [--user <USER_ID>]\n"
+ + " Example:\n"
+ + " # cat default ringtone to a file, then pull to host\n"
+ + " adb shell 'content read --uri content://settings/system/ringtone >"
+ + " /mnt/sdcard/tmp.ogg' && adb pull /mnt/sdcard/tmp.ogg\n"
+ "\n";
private static class Parser {
@@ -117,6 +131,7 @@ public class Content {
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_READ = "read";
private static final String ARGUMENT_WHERE = "--where";
private static final String ARGUMENT_BIND = "--bind";
private static final String ARGUMENT_URI = "--uri";
@@ -154,6 +169,8 @@ public class Content {
return parseQueryCommand();
} else if (ARGUMENT_CALL.equals(operation)) {
return parseCallCommand();
+ } else if (ARGUMENT_READ.equals(operation)) {
+ return parseReadCommand();
} else {
throw new IllegalArgumentException("Unsupported operation: " + operation);
}
@@ -273,6 +290,25 @@ public class Content {
return new CallCommand(uri, userId, method, arg, values);
}
+ private ReadCommand parseReadCommand() {
+ Uri uri = null;
+ int userId = UserHandle.USER_OWNER;
+ 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 {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ return new ReadCommand(uri, userId);
+ }
+
public QueryCommand parseQueryCommand() {
Uri uri = null;
int userId = UserHandle.USER_OWNER;
@@ -458,6 +494,31 @@ public class Content {
}
}
+ private static class ReadCommand extends Command {
+ public ReadCommand(Uri uri, int userId) {
+ super(uri, userId);
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null);
+ copy(new FileInputStream(fd.getFileDescriptor()), System.out);
+ }
+
+ private static void copy(InputStream is, OutputStream os) throws IOException {
+ final byte[] buffer = new byte[8 * 1024];
+ int read;
+ try {
+ while ((read = is.read(buffer)) > -1) {
+ os.write(buffer, 0, read);
+ }
+ } finally {
+ IoUtils.closeQuietly(is);
+ IoUtils.closeQuietly(os);
+ }
+ }
+ }
+
private static class QueryCommand extends DeleteCommand {
final String[] mProjection;
final String mSortOrder;