summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java284
-rw-r--r--cmds/content/src/com/android/commands/content/Content.java26
-rw-r--r--cmds/dpm/src/com/android/commands/dpm/Dpm.java18
-rwxr-xr-xcmds/input/input2
-rw-r--r--cmds/media/src/com/android/commands/media/Media.java1
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java111
-rw-r--r--cmds/screencap/screencap.cpp15
-rw-r--r--cmds/settings/src/com/android/commands/settings/SettingsCmd.java74
-rw-r--r--cmds/svc/src/com/android/commands/svc/DataCommand.java2
-rw-r--r--cmds/svc/src/com/android/commands/svc/WifiCommand.java2
-rw-r--r--cmds/uiautomator/library/Android.mk1
-rw-r--r--cmds/wm/src/com/android/commands/wm/Wm.java46
12 files changed, 506 insertions, 76 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 2ea1d4d..219d35b 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -44,7 +44,6 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SELinux;
@@ -113,16 +112,19 @@ public class Am extends BaseCommand {
" am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
" [--user <USER_ID> | current]\n" +
" [--no-window-animation] [--abi <ABI>] <COMPONENT>\n" +
- " am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
+ " am profile start [--user <USER_ID> current] [--sampling INTERVAL] <PROCESS> <FILE>\n" +
" am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
" am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
" am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
" am clear-debug-app\n" +
+ " am set-watch-heap <PROCESS> <MEM-LIMIT>\n" +
+ " am clear-watch-heap\n" +
" am monitor [--gdb <port>]\n" +
" am hang [--allow-restart]\n" +
" am restart\n" +
" am idle-maintenance\n" +
" am screen-compat [on|off] <PACKAGE>\n" +
+ " am package-importance <PACKAGE>\n" +
" am to-uri [INTENT]\n" +
" am to-intent-uri [INTENT]\n" +
" am to-app-uri [INTENT]\n" +
@@ -132,11 +134,16 @@ public class Am extends BaseCommand {
" am stack start <DISPLAY_ID> <INTENT>\n" +
" am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
" am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
+ " am stack split <STACK_ID> <v|h> [INTENT]\n" +
" am stack list\n" +
" am stack info <STACK_ID>\n" +
- " am lock-task <TASK_ID>\n" +
- " am lock-task stop\n" +
+ " am task lock <TASK_ID>\n" +
+ " am task lock stop\n" +
+ " am task resizeable <TASK_ID> [true|false]\n" +
+ " am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
" am get-config\n" +
+ " am set-idle [--user <USER_ID>] <PACKAGE> true|false\n" +
+ " am get-idle [--user <USER_ID>] <PACKAGE>\n" +
"\n" +
"am start: start an Activity. Options are:\n" +
" -D: enable debugging\n" +
@@ -209,6 +216,11 @@ public class Am extends BaseCommand {
"\n" +
"am clear-debug-app: clear the previously set-debug-app.\n" +
"\n" +
+ "am set-watch-heap: start monitoring pss size of <PROCESS>, if it is at or\n" +
+ " above <HEAP-LIMIT> then a heap dump is collected for the user to report\n" +
+ "\n" +
+ "am clear-watch-heap: clear the previously set-watch-heap.\n" +
+ "\n" +
"am bug-report: request bug report generation; will launch UI\n" +
" when done to select where it should be delivered.\n" +
"\n" +
@@ -224,6 +236,8 @@ public class Am extends BaseCommand {
"\n" +
"am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
"\n" +
+ "am package-importance: print current importance of <PACKAGE>.\n" +
+ "\n" +
"am to-uri: print the given Intent specification as a URI.\n" +
"\n" +
"am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
@@ -244,17 +258,37 @@ public class Am extends BaseCommand {
"am stack movetask: move <TASK_ID> from its current stack to the top (true) or" +
" bottom (false) of <STACK_ID>.\n" +
"\n" +
- "am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.\n" +
+ "am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>" +
+ ".\n" +
+ "\n" +
+ "am stack split: split <STACK_ID> into 2 stacks <v>ertically or <h>orizontally\n" +
+ " starting the new stack with [INTENT] if specified. If [INTENT] isn't\n" +
+ " specified and the current stack has more than one task, then the top task\n" +
+ " of the current task will be moved to the new stack. Command will also force\n" +
+ " all current tasks in both stacks to be resizeable.\n" +
"\n" +
"am stack list: list all of the activity stacks and their sizes.\n" +
"\n" +
"am stack info: display the information about activity stack <STACK_ID>.\n" +
"\n" +
- "am lock-task: bring <TASK_ID> to the front and don't allow other tasks to run\n" +
+ "am task lock: bring <TASK_ID> to the front and don't allow other tasks to run\n" +
+ "\n" +
+ "am task lock stop: end the current task lock\n" +
+ "\n" +
+ "am task resizeable: change if <TASK_ID> is resizeable (true) or not (false).\n" +
+ "\n" +
+ "am task resize: makes sure <TASK_ID> is in a stack with the specified bounds.\n" +
+ " Forces the task to be resizeable and creates a stack if no existing stack\n" +
+ " has the specified bounds.\n" +
"\n" +
"am get-config: retrieve the configuration and any recent configurations\n" +
" of the device\n" +
"\n" +
+ "am set-idle: sets the idle state of an app\n" +
+ "\n" +
+ "am get-idle: returns the idle state of an app\n" +
+ "\n" +
+ "\n" +
"<INTENT> specifications include these flags and arguments:\n" +
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
" [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -325,6 +359,10 @@ public class Am extends BaseCommand {
runSetDebugApp();
} else if (op.equals("clear-debug-app")) {
runClearDebugApp();
+ } else if (op.equals("set-watch-heap")) {
+ runSetWatchHeap();
+ } else if (op.equals("clear-watch-heap")) {
+ runClearWatchHeap();
} else if (op.equals("bug-report")) {
runBugReport();
} else if (op.equals("monitor")) {
@@ -337,6 +375,8 @@ public class Am extends BaseCommand {
runIdleMaintenance();
} else if (op.equals("screen-compat")) {
runScreenCompat();
+ } else if (op.equals("package-importance")) {
+ runPackageImportance();
} else if (op.equals("to-uri")) {
runToUri(0);
} else if (op.equals("to-intent-uri")) {
@@ -351,10 +391,14 @@ public class Am extends BaseCommand {
runStopUser();
} else if (op.equals("stack")) {
runStack();
- } else if (op.equals("lock-task")) {
- runLockTask();
+ } else if (op.equals("task")) {
+ runTask();
} else if (op.equals("get-config")) {
runGetConfig();
+ } else if (op.equals("set-idle")) {
+ runSetIdle();
+ } else if (op.equals("get-idle")) {
+ runGetIdle();
} else {
showError("Error: unknown command '" + op + "'");
}
@@ -824,6 +868,11 @@ public class Am extends BaseCommand {
"Error: Activity not started, voice control not allowed for: "
+ intent);
break;
+ case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
+ out.println(
+ "Error: Not allowed to start background user activity"
+ + " that shouldn't be displayed for all users.");
+ break;
default:
out.println(
"Error: Activity not started, unknown error code " + res);
@@ -1003,6 +1052,7 @@ public class Am extends BaseCommand {
boolean wall = false;
int userId = UserHandle.USER_CURRENT;
int profileType = 0;
+ mSamplingInterval = 0;
String process = null;
@@ -1016,6 +1066,8 @@ public class Am extends BaseCommand {
userId = parseUserArg(nextArgRequired());
} else if (opt.equals("--wall")) {
wall = true;
+ } else if (opt.equals("--sampling")) {
+ mSamplingInterval = Integer.parseInt(nextArgRequired());
} else {
System.err.println("Error: Unknown option: " + opt);
return;
@@ -1065,7 +1117,7 @@ public class Am extends BaseCommand {
System.err.println("Consider using a file under /data/local/tmp/");
return;
}
- profilerInfo = new ProfilerInfo(profileFile, fd, 0, false);
+ profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false);
}
try {
@@ -1155,6 +1207,17 @@ public class Am extends BaseCommand {
mAm.setDebugApp(null, false, true);
}
+ private void runSetWatchHeap() throws Exception {
+ String proc = nextArgRequired();
+ String limit = nextArgRequired();
+ mAm.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
+ }
+
+ private void runClearWatchHeap() throws Exception {
+ String proc = nextArgRequired();
+ mAm.setDumpHeapDebugLimit(proc, 0, -1, null);
+ }
+
private void runBugReport() throws Exception {
mAm.requestBugReport();
System.out.println("Your lovely bug report is being created; please be patient.");
@@ -1562,6 +1625,16 @@ public class Am extends BaseCommand {
} while (packageName != null);
}
+ private void runPackageImportance() throws Exception {
+ String packageName = nextArgRequired();
+ try {
+ int procState = mAm.getPackageProcessState(packageName);
+ System.out.println(
+ ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
+ } catch (RemoteException e) {
+ }
+ }
+
private void runToUri(int flags) throws Exception {
Intent intent = makeIntent(UserHandle.USER_CURRENT);
System.out.println(intent.toUri(flags));
@@ -1682,6 +1755,8 @@ public class Am extends BaseCommand {
runStackList();
} else if (op.equals("info")) {
runStackInfo();
+ } else if (op.equals("split")) {
+ runStackSplit();
} else {
showError("Error: unknown command '" + op + "'");
return;
@@ -1694,10 +1769,10 @@ public class Am extends BaseCommand {
Intent intent = makeIntent(UserHandle.USER_CURRENT);
try {
- IBinder homeActivityToken = mAm.getHomeActivityToken();
- IActivityContainer container = mAm.createActivityContainer(homeActivityToken, null);
- container.attachToDisplay(displayId);
- container.startActivity(intent);
+ IActivityContainer container = mAm.createStackOnDisplay(displayId);
+ if (container != null) {
+ container.startActivity(intent);
+ }
} catch (RemoteException e) {
}
}
@@ -1727,17 +1802,14 @@ public class Am extends BaseCommand {
private void runStackResize() throws Exception {
String stackIdStr = nextArgRequired();
int stackId = Integer.valueOf(stackIdStr);
- String leftStr = nextArgRequired();
- int left = Integer.valueOf(leftStr);
- String topStr = nextArgRequired();
- int top = Integer.valueOf(topStr);
- String rightStr = nextArgRequired();
- int right = Integer.valueOf(rightStr);
- String bottomStr = nextArgRequired();
- int bottom = Integer.valueOf(bottomStr);
+ final Rect bounds = getBounds();
+ if (bounds == null) {
+ System.err.println("Error: invalid input bounds");
+ return;
+ }
try {
- mAm.resizeStack(stackId, new Rect(left, top, right, bottom));
+ mAm.resizeStack(stackId, bounds);
} catch (RemoteException e) {
}
}
@@ -1762,7 +1834,79 @@ public class Am extends BaseCommand {
}
}
- private void runLockTask() throws Exception {
+ private void runStackSplit() throws Exception {
+ final int stackId = Integer.valueOf(nextArgRequired());
+ final String splitDirection = nextArgRequired();
+ Intent intent = null;
+ try {
+ intent = makeIntent(UserHandle.USER_CURRENT);
+ } catch (IllegalArgumentException e) {
+ // no intent supplied.
+ }
+
+ try {
+ final StackInfo currentStackInfo = mAm.getStackInfo(stackId);
+ // Calculate bounds for new and current stack.
+ final Rect currentStackBounds = new Rect(currentStackInfo.bounds);
+ final Rect newStackBounds = new Rect(currentStackInfo.bounds);
+ if ("v".equals(splitDirection)) {
+ currentStackBounds.right = newStackBounds.left = currentStackInfo.bounds.centerX();
+ } else if ("h".equals(splitDirection)) {
+ currentStackBounds.bottom = newStackBounds.top = currentStackInfo.bounds.centerY();
+ } else {
+ showError("Error: unknown split direction '" + splitDirection + "'");
+ return;
+ }
+
+ // Create new stack
+ IActivityContainer container = mAm.createStackOnDisplay(currentStackInfo.displayId);
+ if (container == null) {
+ showError("Error: Unable to create new stack...");
+ }
+
+ final int newStackId = container.getStackId();
+
+ if (intent != null) {
+ container.startActivity(intent);
+ } else if (currentStackInfo.taskIds != null && currentStackInfo.taskIds.length > 1) {
+ // Move top task over to new stack
+ mAm.moveTaskToStack(currentStackInfo.taskIds[currentStackInfo.taskIds.length - 1],
+ newStackId, true);
+ }
+
+ final StackInfo newStackInfo = mAm.getStackInfo(newStackId);
+
+ // Make all tasks in the stacks resizeable.
+ for (int taskId : currentStackInfo.taskIds) {
+ mAm.setTaskResizeable(taskId, true);
+ }
+
+ for (int taskId : newStackInfo.taskIds) {
+ mAm.setTaskResizeable(taskId, true);
+ }
+
+ // Resize stacks
+ mAm.resizeStack(currentStackInfo.stackId, currentStackBounds);
+ mAm.resizeStack(newStackInfo.stackId, newStackBounds);
+ } catch (RemoteException e) {
+ }
+ }
+
+ private void runTask() throws Exception {
+ String op = nextArgRequired();
+ if (op.equals("lock")) {
+ runTaskLock();
+ } else if (op.equals("resizeable")) {
+ runTaskResizeable();
+ } else if (op.equals("resize")) {
+ runTaskResize();
+ } else {
+ showError("Error: unknown command '" + op + "'");
+ return;
+ }
+ }
+
+ private void runTaskLock() throws Exception {
String taskIdStr = nextArgRequired();
try {
if (taskIdStr.equals("stop")) {
@@ -1777,6 +1921,32 @@ public class Am extends BaseCommand {
}
}
+ private void runTaskResizeable() throws Exception {
+ final String taskIdStr = nextArgRequired();
+ final int taskId = Integer.valueOf(taskIdStr);
+ final String resizeableStr = nextArgRequired();
+ final boolean resizeable = Boolean.valueOf(resizeableStr);
+
+ try {
+ mAm.setTaskResizeable(taskId, resizeable);
+ } catch (RemoteException e) {
+ }
+ }
+
+ private void runTaskResize() throws Exception {
+ final String taskIdStr = nextArgRequired();
+ final int taskId = Integer.valueOf(taskIdStr);
+ final Rect bounds = getBounds();
+ if (bounds == null) {
+ System.err.println("Error: invalid input bounds");
+ return;
+ }
+ try {
+ mAm.resizeTask(taskId, bounds);
+ } catch (RemoteException e) {
+ }
+ }
+
private List<Configuration> getRecentConfigurations(int days) {
IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
Context.USAGE_STATS_SERVICE));
@@ -1860,6 +2030,46 @@ public class Am extends BaseCommand {
}
}
+ private void runSetIdle() throws Exception {
+ int userId = UserHandle.USER_OWNER;
+
+ String opt;
+ while ((opt=nextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = parseUserArg(nextArgRequired());
+ } else {
+ System.err.println("Error: Unknown option: " + opt);
+ return;
+ }
+ }
+ String packageName = nextArgRequired();
+ String value = nextArgRequired();
+
+ IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+ Context.USAGE_STATS_SERVICE));
+ usm.setAppIdle(packageName, Boolean.parseBoolean(value), userId);
+ }
+
+ private void runGetIdle() throws Exception {
+ int userId = UserHandle.USER_OWNER;
+
+ String opt;
+ while ((opt=nextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = parseUserArg(nextArgRequired());
+ } else {
+ System.err.println("Error: Unknown option: " + opt);
+ return;
+ }
+ }
+ String packageName = nextArgRequired();
+
+ IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+ Context.USAGE_STATS_SERVICE));
+ boolean isIdle = usm.isAppIdle(packageName, userId);
+ System.out.println("Idle=" + isIdle);
+ }
+
/**
* Open the given file for sending into the system process. This verifies
* with SELinux that the system will have access to the file.
@@ -1873,4 +2083,32 @@ public class Am extends BaseCommand {
}
return fd;
}
+
+ private Rect getBounds() {
+ String leftStr = nextArgRequired();
+ int left = Integer.valueOf(leftStr);
+ String topStr = nextArgRequired();
+ int top = Integer.valueOf(topStr);
+ String rightStr = nextArgRequired();
+ int right = Integer.valueOf(rightStr);
+ String bottomStr = nextArgRequired();
+ int bottom = Integer.valueOf(bottomStr);
+ if (left < 0) {
+ System.err.println("Error: bad left arg: " + leftStr);
+ return null;
+ }
+ if (top < 0) {
+ System.err.println("Error: bad top arg: " + topStr);
+ return null;
+ }
+ if (right <= 0) {
+ System.err.println("Error: bad right arg: " + rightStr);
+ return null;
+ }
+ if (bottom <= 0) {
+ System.err.println("Error: bad bottom arg: " + bottomStr);
+ return null;
+ }
+ return new Rect(left, top, right, bottom);
+ }
}
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index bd34a9c..c0ed893 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -27,6 +27,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -426,6 +427,22 @@ public class Content {
}
}
+ public static String resolveCallingPackage() {
+ switch (Process.myUid()) {
+ case Process.ROOT_UID: {
+ return "root";
+ }
+
+ case Process.SHELL_UID: {
+ return "com.android.shell";
+ }
+
+ default: {
+ return null;
+ }
+ }
+ }
+
protected abstract void onExecute(IContentProvider provider) throws Exception;
}
@@ -439,7 +456,7 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.insert(null, mUri, mContentValues);
+ provider.insert(resolveCallingPackage(), mUri, mContentValues);
}
}
@@ -453,7 +470,7 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.delete(null, mUri, mWhere, null);
+ provider.delete(resolveCallingPackage(), mUri, mWhere, null);
}
}
@@ -532,7 +549,8 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- Cursor cursor = provider.query(null, mUri, mProjection, mWhere, null, mSortOrder, null);
+ Cursor cursor = provider.query(resolveCallingPackage(), mUri, mProjection, mWhere,
+ null, mSortOrder, null);
if (cursor == null) {
System.out.println("No result found.");
return;
@@ -594,7 +612,7 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.update(null, mUri, mContentValues, mWhere, null);
+ provider.update(resolveCallingPackage(), mUri, mContentValues, mWhere, null);
}
}
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 781fb96..3d86ac1 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -52,7 +52,7 @@ public final class Dpm extends BaseCommand {
"usage: dpm [subcommand] [options]\n" +
"usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" +
"usage: dpm set-device-owner <COMPONENT>\n" +
- "usage: dpm set-profile-owner <COMPONENT> <USER_ID>\n" +
+ "usage: dpm set-profile-owner [ --user <USER_ID> ] <COMPONENT>\n" +
"\n" +
"dpm set-active-admin: Sets the given component as active admin" +
" for an existing user.\n" +
@@ -125,23 +125,21 @@ public final class Dpm extends BaseCommand {
}
private void runSetProfileOwner() throws RemoteException {
- // To be refactored later to use parseArgs(boolean). Currently in use by existing tests.
- ComponentName component = parseComponentName(nextArgRequired());
- int userId = parseInt(nextArgRequired());
- mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, userId);
+ parseArgs(true);
+ mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
try {
- if (!mDevicePolicyManager.setProfileOwner(component, "" /*ownerName*/, userId)) {
- throw new RuntimeException("Can't set component " + component.toShortString() +
- " as profile owner for user " + userId);
+ if (!mDevicePolicyManager.setProfileOwner(mComponent, "" /*ownerName*/, mUserId)) {
+ throw new RuntimeException("Can't set component " + mComponent.toShortString() +
+ " as profile owner for user " + mUserId);
}
} catch (Exception e) {
// Need to remove the admin that we just added.
- mDevicePolicyManager.removeActiveAdmin(component, userId);
+ mDevicePolicyManager.removeActiveAdmin(mComponent, mUserId);
throw e;
}
System.out.println("Success: Active admin and profile owner set to "
- + component.toShortString() + " for user " + userId);
+ + mComponent.toShortString() + " for user " + mUserId);
}
private ComponentName parseComponentName(String component) {
diff --git a/cmds/input/input b/cmds/input/input
index fa9dced..7f1a18e 100755
--- a/cmds/input/input
+++ b/cmds/input/input
@@ -3,5 +3,5 @@
#
base=/system
export CLASSPATH=$base/framework/input.jar
-exec app_process $base/bin com.android.commands.input.Input $*
+exec app_process $base/bin com.android.commands.input.Input "$@"
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
index 6a8fb05..d7f23cb 100644
--- a/cmds/media/src/com/android/commands/media/Media.java
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -24,7 +24,6 @@ import android.media.MediaMetadata;
import android.media.session.ISessionController;
import android.media.session.ISessionControllerCallback;
import android.media.session.ISessionManager;
-import android.media.session.MediaController;
import android.media.session.ParcelableVolumeInfo;
import android.media.session.PlaybackState;
import android.os.Bundle;
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 7a01701..39de1dc7 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -48,20 +48,21 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IUserManager;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
+import android.text.format.DateUtils;
import android.util.Log;
+import libcore.io.IoUtils;
+
import com.android.internal.content.PackageHelper;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.SizedInputStream;
-import libcore.io.IoUtils;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -235,6 +236,14 @@ public final class Pm {
return runForceDexOpt();
}
+ if ("move-package".equals(op)) {
+ return runMovePackage();
+ }
+
+ if ("move-primary-storage".equals(op)) {
+ return runMovePrimaryStorage();
+ }
+
try {
if (args.length == 1) {
if (args[0].equalsIgnoreCase("-l")) {
@@ -893,6 +902,8 @@ public final class Pm {
installFlags |= PackageManager.INSTALL_INTERNAL;
} else if (opt.equals("-d")) {
installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+ } else if (opt.equals("-g")) {
+ installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
} else if (opt.equals("--originating-uri")) {
originatingUriString = nextOptionData();
if (originatingUriString == null) {
@@ -1277,6 +1288,61 @@ public final class Pm {
}
}
+ public int runMovePackage() {
+ final String packageName = nextArg();
+ String volumeUuid = nextArg();
+ if ("internal".equals(volumeUuid)) {
+ volumeUuid = null;
+ }
+
+ try {
+ final int moveId = mPm.movePackage(packageName, volumeUuid);
+
+ int status = mPm.getMoveStatus(moveId);
+ while (!PackageManager.isMoveStatusFinished(status)) {
+ SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
+ status = mPm.getMoveStatus(moveId);
+ }
+
+ if (status == PackageManager.MOVE_SUCCEEDED) {
+ System.out.println("Success");
+ return 0;
+ } else {
+ System.err.println("Failure [" + status + "]");
+ return 1;
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ public int runMovePrimaryStorage() {
+ String volumeUuid = nextArg();
+ if ("internal".equals(volumeUuid)) {
+ volumeUuid = null;
+ }
+
+ try {
+ final int moveId = mPm.movePrimaryStorage(volumeUuid);
+
+ int status = mPm.getMoveStatus(moveId);
+ while (!PackageManager.isMoveStatusFinished(status)) {
+ SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
+ status = mPm.getMoveStatus(moveId);
+ }
+
+ if (status == PackageManager.MOVE_SUCCEEDED) {
+ System.out.println("Success");
+ return 0;
+ } else {
+ System.err.println("Failure [" + status + "]");
+ return 1;
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
private int runUninstall() throws RemoteException {
int flags = 0;
int userId = UserHandle.USER_ALL;
@@ -1334,7 +1400,8 @@ public final class Pm {
}
final LocalIntentReceiver receiver = new LocalIntentReceiver();
- mInstaller.uninstall(pkg, flags, receiver.getIntentSender(), userId);
+ mInstaller.uninstall(pkg, null /* callerPackageName */, flags,
+ receiver.getIntentSender(), userId);
final Intent result = receiver.getResult();
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
@@ -1518,6 +1585,15 @@ public final class Pm {
}
private int runGrantRevokePermission(boolean grant) {
+ int userId = UserHandle.USER_CURRENT;
+
+ String opt = null;
+ while ((opt = nextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = Integer.parseInt(nextArg());
+ }
+ }
+
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
@@ -1530,11 +1606,12 @@ public final class Pm {
showUsage();
return 1;
}
+
try {
if (grant) {
- mPm.grantPermission(pkg, perm);
+ mPm.grantPermission(pkg, perm, userId);
} else {
- mPm.revokePermission(pkg, perm);
+ mPm.revokePermission(pkg, perm, userId);
}
return 0;
} catch (RemoteException e) {
@@ -1629,9 +1706,13 @@ public final class Pm {
showUsage();
return 1;
}
+ String volumeUuid = nextArg();
+ if ("internal".equals(volumeUuid)) {
+ volumeUuid = null;
+ }
ClearDataObserver obs = new ClearDataObserver();
try {
- mPm.freeStorageAndNotify(sizeVal, obs);
+ mPm.freeStorageAndNotify(volumeUuid, sizeVal, obs);
synchronized (obs) {
while (!obs.finished) {
try {
@@ -1802,13 +1883,15 @@ public final class Pm {
System.err.println(" pm list users");
System.err.println(" pm path PACKAGE");
System.err.println(" pm dump PACKAGE");
- System.err.println(" pm install [-lrtsfd] [-i PACKAGE] [PATH]");
+ System.err.println(" pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]");
System.err.println(" pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]");
System.err.println(" pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]");
System.err.println(" pm install-commit SESSION_ID");
System.err.println(" pm install-abandon SESSION_ID");
System.err.println(" pm uninstall [-k] [--user USER_ID] PACKAGE");
System.err.println(" pm set-installer PACKAGE INSTALLER");
+ System.err.println(" pm move-package PACKAGE [internal|UUID]");
+ System.err.println(" pm move-primary-storage [internal|UUID]");
System.err.println(" pm clear [--user USER_ID] PACKAGE");
System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
@@ -1816,12 +1899,12 @@ public final class Pm {
System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm hide [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm grant PACKAGE PERMISSION");
- System.err.println(" pm revoke PACKAGE PERMISSION");
+ System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION");
+ System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
- System.err.println(" pm trim-caches DESIRED_FREE_SPACE");
+ System.err.println(" pm trim-caches DESIRED_FREE_SPACE [internal|UUID]");
System.err.println(" pm create-user [--profileOf USER_ID] [--managed] USER_NAME");
System.err.println(" pm remove-user USER_ID");
System.err.println(" pm get-max-users");
@@ -1869,6 +1952,7 @@ public final class Pm {
System.err.println(" -f: install application on internal flash");
System.err.println(" -d: allow version code downgrade");
System.err.println(" -p: partial application install");
+ System.err.println(" -g: grant all runtime permissions");
System.err.println(" -S: size in bytes of entire session");
System.err.println("");
System.err.println("pm install-write: write a package into existing session; path may");
@@ -1890,8 +1974,9 @@ public final class Pm {
System.err.println(" as \"package/class\").");
System.err.println("");
System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
- System.err.println(" to applications. Only optional permissions the application has");
- System.err.println(" declared can be granted or revoked.");
+ System.err.println(" to apps. The permissions must be declared as used in the app's");
+ System.err.println(" manifest, be runtime permissions (protection level dangerous),");
+ System.err.println(" and the app targeting SDK greater than Lollipop MR1.");
System.err.println("");
System.err.println("pm get-install-location: returns the current install location.");
System.err.println(" 0 [auto]: Let system decide the best location");
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index b0aee7b..dbc35af 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -36,9 +36,7 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkImageEncoder.h>
-#include <SkBitmap.h>
#include <SkData.h>
-#include <SkStream.h>
#pragma GCC diagnostic pop
using namespace android;
@@ -198,14 +196,11 @@ int main(int argc, char** argv)
if (png) {
const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f),
kPremul_SkAlphaType);
- SkBitmap b;
- b.installPixels(info, const_cast<void*>(base), s*bytesPerPixel(f));
- SkDynamicMemoryWStream stream;
- SkImageEncoder::EncodeStream(&stream, b,
- SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
- SkData* streamData = stream.copyToData();
- write(fd, streamData->data(), streamData->size());
- streamData->unref();
+ SkAutoTUnref<SkData> data(SkImageEncoder::EncodeData(info, base, s*bytesPerPixel(f),
+ SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality));
+ if (data.get()) {
+ write(fd, data->data(), data->size());
+ }
if (fn != NULL) {
notifyMediaScanner(fn);
}
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
index e6847a9..c27d0c0 100644
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
@@ -20,22 +20,28 @@ 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 {
- static final String TAG = "settings";
enum CommandVerb {
UNSPECIFIED,
GET,
PUT,
- DELETE
+ DELETE,
+ LIST,
}
static String[] mArgs;
@@ -47,7 +53,7 @@ public final class SettingsCmd {
String mValue = null;
public static void main(String[] args) {
- if (args == null || args.length < 3) {
+ if (args == null || args.length < 2) {
printUsage();
return;
}
@@ -78,6 +84,8 @@ public final class SettingsCmd {
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);
@@ -91,6 +99,10 @@ public final class SettingsCmd {
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) {
@@ -144,6 +156,11 @@ public final class SettingsCmd {
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;
@@ -164,6 +181,34 @@ public final class SettingsCmd {
}
}
+ 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;
@@ -188,7 +233,7 @@ public final class SettingsCmd {
try {
Bundle arg = new Bundle();
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- Bundle b = provider.call(null, callGetCommand, key, arg);
+ Bundle b = provider.call(resolveCallingPackage(), callGetCommand, key, arg);
if (b != null) {
result = b.getPairValue();
}
@@ -213,7 +258,7 @@ public final class SettingsCmd {
Bundle arg = new Bundle();
arg.putString(Settings.NameValueTable.VALUE, value);
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- provider.call(null, callPutCommand, key, arg);
+ provider.call(resolveCallingPackage(), callPutCommand, key, arg);
} catch (RemoteException e) {
System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle);
}
@@ -232,7 +277,7 @@ public final class SettingsCmd {
int num = 0;
try {
- num = provider.delete(null, targetUri, null, null);
+ num = provider.delete(resolveCallingPackage(), targetUri, null, null);
} catch (RemoteException e) {
System.err.println("Can't clear key " + key + " in " + table + " for user "
+ userHandle);
@@ -244,7 +289,24 @@ public final class SettingsCmd {
System.err.println("usage: settings [--user NUM] get namespace key");
System.err.println(" settings [--user NUM] put namespace key value");
System.err.println(" settings [--user NUM] delete namespace key");
+ System.err.println(" settings [--user NUM] list namespace");
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.");
}
+
+ 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;
+ }
+ }
+ }
}
diff --git a/cmds/svc/src/com/android/commands/svc/DataCommand.java b/cmds/svc/src/com/android/commands/svc/DataCommand.java
index 406e33b..35510cf 100644
--- a/cmds/svc/src/com/android/commands/svc/DataCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/DataCommand.java
@@ -18,8 +18,6 @@ package com.android.commands.svc;
import android.os.ServiceManager;
import android.os.RemoteException;
-import android.net.IConnectivityManager;
-import android.net.ConnectivityManager;
import android.content.Context;
import com.android.internal.telephony.ITelephony;
diff --git a/cmds/svc/src/com/android/commands/svc/WifiCommand.java b/cmds/svc/src/com/android/commands/svc/WifiCommand.java
index 39f0e35..94214ff 100644
--- a/cmds/svc/src/com/android/commands/svc/WifiCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/WifiCommand.java
@@ -19,8 +19,6 @@ package com.android.commands.svc;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.net.wifi.IWifiManager;
-import android.net.IConnectivityManager;
-import android.net.ConnectivityManager;
import android.content.Context;
public class WifiCommand extends Svc.Command {
diff --git a/cmds/uiautomator/library/Android.mk b/cmds/uiautomator/library/Android.mk
index 7cc0884..2123f25 100644
--- a/cmds/uiautomator/library/Android.mk
+++ b/cmds/uiautomator/library/Android.mk
@@ -65,6 +65,7 @@ LOCAL_SOURCE_FILES_ALL_GENERATED := true
include $(BUILD_STATIC_JAVA_LIBRARY)
# Make sure to run droiddoc first to generate the stub source files.
$(full_classes_compiled_jar) : $(uiautomator_stubs_stamp)
+$(built_dex_intermediate) : $(uiautomator_stubs_stamp)
uiautomator_stubs_jar := $(full_classes_compiled_jar)
###############################################
diff --git a/cmds/wm/src/com/android/commands/wm/Wm.java b/cmds/wm/src/com/android/commands/wm/Wm.java
index 815a0ac..64f023f 100644
--- a/cmds/wm/src/com/android/commands/wm/Wm.java
+++ b/cmds/wm/src/com/android/commands/wm/Wm.java
@@ -24,6 +24,7 @@ import android.graphics.Rect;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.AndroidException;
+import android.util.DisplayMetrics;
import android.view.Display;
import android.view.IWindowManager;
import com.android.internal.os.BaseCommand;
@@ -45,21 +46,27 @@ public class Wm extends BaseCommand {
(new Wm()).run(args);
}
+ @Override
public void onShowUsage(PrintStream out) {
out.println(
"usage: wm [subcommand] [options]\n" +
- " wm size [reset|WxH]\n" +
+ " wm size [reset|WxH|WdpxHdp]\n" +
" wm density [reset|DENSITY]\n" +
" wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
+ " wm scaling [off|auto]\n" +
"\n" +
"wm size: return or override display size.\n" +
+ " width and height in pixels unless suffixed with 'dp'.\n" +
"\n" +
"wm density: override display density.\n" +
"\n" +
- "wm overscan: set overscan area for display.\n"
+ "wm overscan: set overscan area for display.\n" +
+ "\n" +
+ "wm scaling: set display scaling mode.\n"
);
}
+ @Override
public void onRun() throws Exception {
mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
Context.WINDOW_SERVICE));
@@ -76,6 +83,8 @@ public class Wm extends BaseCommand {
runDisplayDensity();
} else if (op.equals("overscan")) {
runDisplayOverscan();
+ } else if (op.equals("scaling")) {
+ runDisplayScaling();
} else {
showError("Error: unknown command '" + op + "'");
return;
@@ -85,6 +94,7 @@ public class Wm extends BaseCommand {
private void runDisplaySize() throws Exception {
String size = nextArg();
int w, h;
+ boolean scale = true;
if (size == null) {
Point initialSize = new Point();
Point baseSize = new Point();
@@ -109,8 +119,8 @@ public class Wm extends BaseCommand {
String wstr = size.substring(0, div);
String hstr = size.substring(div+1);
try {
- w = Integer.parseInt(wstr);
- h = Integer.parseInt(hstr);
+ w = parseDimension(wstr);
+ h = parseDimension(hstr);
} catch (NumberFormatException e) {
System.err.println("Error: bad number " + e);
return;
@@ -193,4 +203,32 @@ public class Wm extends BaseCommand {
} catch (RemoteException e) {
}
}
+
+ private void runDisplayScaling() throws Exception {
+ String scalingStr = nextArgRequired();
+ if ("auto".equals(scalingStr)) {
+ mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 0);
+ } else if ("off".equals(scalingStr)) {
+ mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
+ } else {
+ System.err.println("Error: scaling must be 'auto' or 'off'");
+ }
+ }
+
+ private int parseDimension(String s) throws NumberFormatException {
+ if (s.endsWith("px")) {
+ return Integer.parseInt(s.substring(0, s.length() - 2));
+ }
+ if (s.endsWith("dp")) {
+ int density;
+ try {
+ density = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
+ } catch (RemoteException e) {
+ density = DisplayMetrics.DENSITY_DEFAULT;
+ }
+ return Integer.parseInt(s.substring(0, s.length() - 2)) * density /
+ DisplayMetrics.DENSITY_DEFAULT;
+ }
+ return Integer.parseInt(s);
+ }
}