in com/android/server/DeviceIdleController.java [2839:3244]
int onShellCommand(Shell shell, String cmd) {
PrintWriter pw = shell.getOutPrintWriter();
if ("step".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
String arg = shell.getNextArg();
try {
if (arg == null || "deep".equals(arg)) {
stepIdleStateLocked("s:shell");
pw.print("Stepped to deep: ");
pw.println(stateToString(mState));
} else if ("light".equals(arg)) {
stepLightIdleStateLocked("s:shell");
pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
} else {
pw.println("Unknown idle mode: " + arg);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else if ("force-idle".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
String arg = shell.getNextArg();
try {
if (arg == null || "deep".equals(arg)) {
if (!mDeepEnabled) {
pw.println("Unable to go deep idle; not enabled");
return -1;
}
mForceIdle = true;
becomeInactiveIfAppropriateLocked();
int curState = mState;
while (curState != STATE_IDLE) {
stepIdleStateLocked("s:shell");
if (curState == mState) {
pw.print("Unable to go deep idle; stopped at ");
pw.println(stateToString(mState));
exitForceIdleLocked();
return -1;
}
curState = mState;
}
pw.println("Now forced in to deep idle mode");
} else if ("light".equals(arg)) {
mForceIdle = true;
becomeInactiveIfAppropriateLocked();
int curLightState = mLightState;
while (curLightState != LIGHT_STATE_IDLE) {
stepLightIdleStateLocked("s:shell");
if (curLightState == mLightState) {
pw.print("Unable to go light idle; stopped at ");
pw.println(lightStateToString(mLightState));
exitForceIdleLocked();
return -1;
}
curLightState = mLightState;
}
pw.println("Now forced in to light idle mode");
} else {
pw.println("Unknown idle mode: " + arg);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else if ("force-inactive".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
try {
mForceIdle = true;
becomeInactiveIfAppropriateLocked();
pw.print("Light state: ");
pw.print(lightStateToString(mLightState));
pw.print(", deep state: ");
pw.println(stateToString(mState));
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else if ("unforce".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
try {
exitForceIdleLocked();
pw.print("Light state: ");
pw.print(lightStateToString(mLightState));
pw.print(", deep state: ");
pw.println(stateToString(mState));
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else if ("get".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
String arg = shell.getNextArg();
if (arg != null) {
long token = Binder.clearCallingIdentity();
try {
switch (arg) {
case "light": pw.println(lightStateToString(mLightState)); break;
case "deep": pw.println(stateToString(mState)); break;
case "force": pw.println(mForceIdle); break;
case "screen": pw.println(mScreenOn); break;
case "charging": pw.println(mCharging); break;
case "network": pw.println(mNetworkConnected); break;
default: pw.println("Unknown get option: " + arg); break;
}
} finally {
Binder.restoreCallingIdentity(token);
}
} else {
pw.println("Argument required");
}
}
} else if ("disable".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
String arg = shell.getNextArg();
try {
boolean becomeActive = false;
boolean valid = false;
if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
valid = true;
if (mDeepEnabled) {
mDeepEnabled = false;
becomeActive = true;
pw.println("Deep idle mode disabled");
}
}
if (arg == null || "light".equals(arg) || "all".equals(arg)) {
valid = true;
if (mLightEnabled) {
mLightEnabled = false;
becomeActive = true;
pw.println("Light idle mode disabled");
}
}
if (becomeActive) {
becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
Process.myUid());
}
if (!valid) {
pw.println("Unknown idle mode: " + arg);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else if ("enable".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
String arg = shell.getNextArg();
try {
boolean becomeInactive = false;
boolean valid = false;
if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
valid = true;
if (!mDeepEnabled) {
mDeepEnabled = true;
becomeInactive = true;
pw.println("Deep idle mode enabled");
}
}
if (arg == null || "light".equals(arg) || "all".equals(arg)) {
valid = true;
if (!mLightEnabled) {
mLightEnabled = true;
becomeInactive = true;
pw.println("Light idle mode enable");
}
}
if (becomeInactive) {
becomeInactiveIfAppropriateLocked();
}
if (!valid) {
pw.println("Unknown idle mode: " + arg);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else if ("enabled".equals(cmd)) {
synchronized (this) {
String arg = shell.getNextArg();
if (arg == null || "all".equals(arg)) {
pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
} else if ("deep".equals(arg)) {
pw.println(mDeepEnabled ? "1" : 0);
} else if ("light".equals(arg)) {
pw.println(mLightEnabled ? "1" : 0);
} else {
pw.println("Unknown idle mode: " + arg);
}
}
} else if ("whitelist".equals(cmd)) {
String arg = shell.getNextArg();
if (arg != null) {
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
long token = Binder.clearCallingIdentity();
try {
do {
if (arg.length() < 1 || (arg.charAt(0) != '-'
&& arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
pw.println("Package must be prefixed with +, -, or =: " + arg);
return -1;
}
char op = arg.charAt(0);
String pkg = arg.substring(1);
if (op == '+') {
if (addPowerSaveWhitelistAppInternal(pkg)) {
pw.println("Added: " + pkg);
} else {
pw.println("Unknown package: " + pkg);
}
} else if (op == '-') {
if (removePowerSaveWhitelistAppInternal(pkg)) {
pw.println("Removed: " + pkg);
}
} else {
pw.println(getPowerSaveWhitelistAppInternal(pkg));
}
} while ((arg=shell.getNextArg()) != null);
} finally {
Binder.restoreCallingIdentity(token);
}
} else {
synchronized (this) {
for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
pw.print("system-excidle,");
pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
pw.print(",");
pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
}
for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
pw.print("system,");
pw.print(mPowerSaveWhitelistApps.keyAt(j));
pw.print(",");
pw.println(mPowerSaveWhitelistApps.valueAt(j));
}
for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
pw.print("user,");
pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
pw.print(",");
pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
}
}
}
} else if ("tempwhitelist".equals(cmd)) {
long duration = 10000;
boolean removePkg = false;
String opt;
while ((opt=shell.getNextOption()) != null) {
if ("-u".equals(opt)) {
opt = shell.getNextArg();
if (opt == null) {
pw.println("-u requires a user number");
return -1;
}
shell.userId = Integer.parseInt(opt);
} else if ("-d".equals(opt)) {
opt = shell.getNextArg();
if (opt == null) {
pw.println("-d requires a duration");
return -1;
}
duration = Long.parseLong(opt);
} else if ("-r".equals(opt)) {
removePkg = true;
}
}
String arg = shell.getNextArg();
if (arg != null) {
try {
if (removePkg) {
removePowerSaveTempWhitelistAppChecked(arg, shell.userId);
} else {
addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell");
}
} catch (Exception e) {
pw.println("Failed: " + e);
return -1;
}
} else if (removePkg) {
pw.println("[-r] requires a package name");
return -1;
} else {
dumpTempWhitelistSchedule(pw, false);
}
} else if ("except-idle-whitelist".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final long token = Binder.clearCallingIdentity();
try {
String arg = shell.getNextArg();
if (arg == null) {
pw.println("No arguments given");
return -1;
} else if ("reset".equals(arg)) {
resetPowerSaveWhitelistExceptIdleInternal();
} else {
do {
if (arg.length() < 1 || (arg.charAt(0) != '-'
&& arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
pw.println("Package must be prefixed with +, -, or =: " + arg);
return -1;
}
char op = arg.charAt(0);
String pkg = arg.substring(1);
if (op == '+') {
if (addPowerSaveWhitelistExceptIdleInternal(pkg)) {
pw.println("Added: " + pkg);
} else {
pw.println("Unknown package: " + pkg);
}
} else if (op == '=') {
pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg));
} else {
pw.println("Unknown argument: " + arg);
return -1;
}
} while ((arg = shell.getNextArg()) != null);
}
} finally {
Binder.restoreCallingIdentity(token);
}
} else if ("sys-whitelist".equals(cmd)) {
String arg = shell.getNextArg();
if (arg != null) {
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final long token = Binder.clearCallingIdentity();
try {
if ("reset".equals(arg)) {
resetSystemPowerWhitelistInternal();
} else {
do {
if (arg.length() < 1
|| (arg.charAt(0) != '-' && arg.charAt(0) != '+')) {
pw.println("Package must be prefixed with + or - " + arg);
return -1;
}
final char op = arg.charAt(0);
final String pkg = arg.substring(1);
switch (op) {
case '+':
if (restoreSystemPowerWhitelistAppInternal(pkg)) {
pw.println("Restored " + pkg);
}
break;
case '-':
if (removeSystemPowerWhitelistAppInternal(pkg)) {
pw.println("Removed " + pkg);
}
break;
}
} while ((arg = shell.getNextArg()) != null);
}
} finally {
Binder.restoreCallingIdentity(token);
}
} else {
synchronized (this) {
for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) {
pw.print(mPowerSaveWhitelistApps.keyAt(j));
pw.print(",");
pw.println(mPowerSaveWhitelistApps.valueAt(j));
}
}
}
} else if ("motion".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
synchronized (this) {
long token = Binder.clearCallingIdentity();
try {
motionLocked();
pw.print("Light state: ");
pw.print(lightStateToString(mLightState));
pw.print(", deep state: ");
pw.println(stateToString(mState));
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else {
return shell.handleDefaultCommands(cmd);
}
return 0;
}