Merge "Help for the debugging help for issue #8734824." into jb-mr2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d43a71dad8
@ -31,6 +31,7 @@ import android.content.Intent;
|
|||||||
import android.content.pm.IPackageManager;
|
import android.content.pm.IPackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@ -94,6 +95,7 @@ public class Am extends BaseCommand {
|
|||||||
" am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
|
" am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
|
||||||
" am clear-debug-app\n" +
|
" am clear-debug-app\n" +
|
||||||
" am monitor [--gdb <port>]\n" +
|
" am monitor [--gdb <port>]\n" +
|
||||||
|
" am hang [--allow-restart]\n" +
|
||||||
" am screen-compat [on|off] <PACKAGE>\n" +
|
" am screen-compat [on|off] <PACKAGE>\n" +
|
||||||
" am to-uri [INTENT]\n" +
|
" am to-uri [INTENT]\n" +
|
||||||
" am to-intent-uri [INTENT]\n" +
|
" am to-intent-uri [INTENT]\n" +
|
||||||
@ -169,6 +171,9 @@ public class Am extends BaseCommand {
|
|||||||
"am monitor: start monitoring for crashes or ANRs.\n" +
|
"am monitor: start monitoring for crashes or ANRs.\n" +
|
||||||
" --gdb: start gdbserv on the given port at crash/ANR\n" +
|
" --gdb: start gdbserv on the given port at crash/ANR\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
"am hang: hang the system.\n" +
|
||||||
|
" --allow-restart: allow watchdog to perform normal system restart\n" +
|
||||||
|
"\n" +
|
||||||
"am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
|
"am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"am to-uri: print the given Intent specification as a URI.\n" +
|
"am to-uri: print the given Intent specification as a URI.\n" +
|
||||||
@ -249,6 +254,8 @@ public class Am extends BaseCommand {
|
|||||||
runBugReport();
|
runBugReport();
|
||||||
} else if (op.equals("monitor")) {
|
} else if (op.equals("monitor")) {
|
||||||
runMonitor();
|
runMonitor();
|
||||||
|
} else if (op.equals("hang")) {
|
||||||
|
runHang();
|
||||||
} else if (op.equals("screen-compat")) {
|
} else if (op.equals("screen-compat")) {
|
||||||
runScreenCompat();
|
runScreenCompat();
|
||||||
} else if (op.equals("to-uri")) {
|
} else if (op.equals("to-uri")) {
|
||||||
@ -1304,6 +1311,22 @@ public class Am extends BaseCommand {
|
|||||||
controller.run();
|
controller.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runHang() throws Exception {
|
||||||
|
String opt;
|
||||||
|
boolean allowRestart = false;
|
||||||
|
while ((opt=nextOption()) != null) {
|
||||||
|
if (opt.equals("--allow-restart")) {
|
||||||
|
allowRestart = true;
|
||||||
|
} else {
|
||||||
|
System.err.println("Error: Unknown option: " + opt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Hanging the system...");
|
||||||
|
mAm.hang(new Binder(), allowRestart);
|
||||||
|
}
|
||||||
|
|
||||||
private void runScreenCompat() throws Exception {
|
private void runScreenCompat() throws Exception {
|
||||||
String mode = nextArgRequired();
|
String mode = nextArgRequired();
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
|
@ -1870,6 +1870,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case HANG_TRANSACTION: {
|
||||||
|
data.enforceInterface(IActivityManager.descriptor);
|
||||||
|
IBinder who = data.readStrongBinder();
|
||||||
|
boolean allowRestart = data.readInt() != 0;
|
||||||
|
hang(who, allowRestart);
|
||||||
|
reply.writeNoException();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onTransact(code, data, reply, flags);
|
return super.onTransact(code, data, reply, flags);
|
||||||
@ -4270,5 +4279,17 @@ class ActivityManagerProxy implements IActivityManager
|
|||||||
reply.recycle();
|
reply.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hang(IBinder who, boolean allowRestart) throws RemoteException {
|
||||||
|
Parcel data = Parcel.obtain();
|
||||||
|
Parcel reply = Parcel.obtain();
|
||||||
|
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||||
|
data.writeStrongBinder(who);
|
||||||
|
data.writeInt(allowRestart ? 1 : 0);
|
||||||
|
mRemote.transact(HANG_TRANSACTION, data, reply, 0);
|
||||||
|
reply.readException();
|
||||||
|
data.recycle();
|
||||||
|
reply.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
private IBinder mRemote;
|
private IBinder mRemote;
|
||||||
}
|
}
|
||||||
|
@ -377,6 +377,8 @@ public interface IActivityManager extends IInterface {
|
|||||||
|
|
||||||
public void killUid(int uid, String reason) throws RemoteException;
|
public void killUid(int uid, String reason) throws RemoteException;
|
||||||
|
|
||||||
|
public void hang(IBinder who, boolean allowRestart) throws RemoteException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private non-Binder interfaces
|
* Private non-Binder interfaces
|
||||||
*/
|
*/
|
||||||
@ -638,4 +640,5 @@ public interface IActivityManager extends IInterface {
|
|||||||
int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
|
int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
|
||||||
int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
|
int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
|
||||||
int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
|
int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
|
||||||
|
int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ public class Watchdog extends Thread {
|
|||||||
|
|
||||||
int mPhonePid;
|
int mPhonePid;
|
||||||
IActivityController mController;
|
IActivityController mController;
|
||||||
|
boolean mAllowRestart = true;
|
||||||
|
|
||||||
final Calendar mCalendar = Calendar.getInstance();
|
final Calendar mCalendar = Calendar.getInstance();
|
||||||
int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
|
int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
|
||||||
@ -233,6 +234,12 @@ public class Watchdog extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAllowRestart(boolean allowRestart) {
|
||||||
|
synchronized (this) {
|
||||||
|
mAllowRestart = allowRestart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addMonitor(Monitor monitor) {
|
public void addMonitor(Monitor monitor) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (isAlive()) {
|
if (isAlive()) {
|
||||||
@ -401,6 +408,7 @@ public class Watchdog extends Thread {
|
|||||||
|
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
|
final boolean allowRestart;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
long timeout = TIME_TO_WAIT;
|
long timeout = TIME_TO_WAIT;
|
||||||
|
|
||||||
@ -437,6 +445,7 @@ public class Watchdog extends Thread {
|
|||||||
|
|
||||||
name = (mCurrentMonitor != null) ?
|
name = (mCurrentMonitor != null) ?
|
||||||
mCurrentMonitor.getClass().getName() : "null";
|
mCurrentMonitor.getClass().getName() : "null";
|
||||||
|
allowRestart = mAllowRestart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got here, that means that the system is most likely hung.
|
// If we got here, that means that the system is most likely hung.
|
||||||
@ -506,12 +515,14 @@ public class Watchdog extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only kill the process if the debugger is not attached.
|
// Only kill the process if the debugger is not attached.
|
||||||
if (!Debug.isDebuggerConnected()) {
|
if (Debug.isDebuggerConnected()) {
|
||||||
|
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
|
||||||
|
} else if (!allowRestart) {
|
||||||
|
Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
|
||||||
|
} else {
|
||||||
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
|
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
|
||||||
Process.killProcess(Process.myPid());
|
Process.killProcess(Process.myPid());
|
||||||
System.exit(10);
|
System.exit(10);
|
||||||
} else {
|
|
||||||
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
waitedHalf = false;
|
waitedHalf = false;
|
||||||
|
@ -7813,6 +7813,45 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
return killed;
|
return killed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hang(final IBinder who, boolean allowRestart) {
|
||||||
|
if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
throw new SecurityException("Requires permission "
|
||||||
|
+ android.Manifest.permission.SET_ACTIVITY_WATCHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
final IBinder.DeathRecipient death = new DeathRecipient() {
|
||||||
|
@Override
|
||||||
|
public void binderDied() {
|
||||||
|
synchronized (this) {
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
who.linkToDeath(death, 0);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "hang: given caller IBinder is already dead.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
Watchdog.getInstance().setAllowRestart(allowRestart);
|
||||||
|
Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
|
||||||
|
synchronized (death) {
|
||||||
|
while (who.isBinderAlive()) {
|
||||||
|
try {
|
||||||
|
death.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Watchdog.getInstance().setAllowRestart(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final void startRunning(String pkg, String cls, String action,
|
public final void startRunning(String pkg, String cls, String action,
|
||||||
String data) {
|
String data) {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
|
Reference in New Issue
Block a user