More bad behavior: ANR and long-term wedge in system process.
Use ActivityController (the special monkey hook) to wedge ActivityManagerService, useful for triggering system ANRs and for setting off the watchdog. Also add more logging so it's clear what happens when.
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||||
<uses-permission android:name="android.permission.REBOOT" />
|
<uses-permission android:name="android.permission.REBOOT" />
|
||||||
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
|
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
|
||||||
|
<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER" />
|
||||||
<uses-permission android:name="android.permission.SET_ALWAYS_FINISH" />
|
<uses-permission android:name="android.permission.SET_ALWAYS_FINISH" />
|
||||||
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
|
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
|
||||||
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
|
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
|
||||||
|
|||||||
@@ -14,54 +14,70 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_crash_system"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/bad_behavior_crash_system_label" />
|
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_crash_main"
|
<Button android:id="@+id/bad_behavior_crash_main"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_crash_main_label" />
|
android:text="@string/bad_behavior_crash_main_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_crash_thread"
|
<Button android:id="@+id/bad_behavior_crash_thread"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_crash_thread_label" />
|
android:text="@string/bad_behavior_crash_thread_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_crash_native"
|
<Button android:id="@+id/bad_behavior_crash_native"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_crash_native_label" />
|
android:text="@string/bad_behavior_crash_native_label" />
|
||||||
|
|
||||||
|
<Button android:id="@+id/bad_behavior_crash_system"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/bad_behavior_crash_system_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_wtf"
|
<Button android:id="@+id/bad_behavior_wtf"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_wtf_label" />
|
android:text="@string/bad_behavior_wtf_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_anr"
|
<Button android:id="@+id/bad_behavior_anr"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_anr_label" />
|
android:text="@string/bad_behavior_anr_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_anr_activity"
|
<Button android:id="@+id/bad_behavior_anr_activity"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_anr_activity_label" />
|
android:text="@string/bad_behavior_anr_activity_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_anr_broadcast"
|
<Button android:id="@+id/bad_behavior_anr_broadcast"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_anr_broadcast_label" />
|
android:text="@string/bad_behavior_anr_broadcast_label" />
|
||||||
|
|
||||||
<Button android:id="@+id/bad_behavior_anr_service"
|
<Button android:id="@+id/bad_behavior_anr_service"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/bad_behavior_anr_service_label" />
|
android:text="@string/bad_behavior_anr_service_label" />
|
||||||
|
|
||||||
|
<Button android:id="@+id/bad_behavior_anr_system"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/bad_behavior_anr_system_label" />
|
||||||
|
|
||||||
|
<Button android:id="@+id/bad_behavior_wedge_system"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/bad_behavior_wedge_system_label" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|||||||
@@ -196,13 +196,15 @@
|
|||||||
<string name="select_account_to_sync">Select account to sync</string>
|
<string name="select_account_to_sync">Select account to sync</string>
|
||||||
|
|
||||||
<!-- BadBehaviorActivity -->
|
<!-- BadBehaviorActivity -->
|
||||||
<string name="bad_behavior_crash_system_label">Crash the system server</string>
|
|
||||||
<string name="bad_behavior_crash_main_label">Crash the main app thread</string>
|
<string name="bad_behavior_crash_main_label">Crash the main app thread</string>
|
||||||
<string name="bad_behavior_crash_thread_label">Crash an auxiliary app thread</string>
|
<string name="bad_behavior_crash_thread_label">Crash an auxiliary app thread</string>
|
||||||
<string name="bad_behavior_crash_native_label">Crash the native process</string>
|
<string name="bad_behavior_crash_native_label">Crash the native process</string>
|
||||||
|
<string name="bad_behavior_crash_system_label">Crash the system server</string>
|
||||||
<string name="bad_behavior_wtf_label">Report a WTF condition</string>
|
<string name="bad_behavior_wtf_label">Report a WTF condition</string>
|
||||||
<string name="bad_behavior_anr_label">ANR (Stop responding for 20 seconds)</string>
|
<string name="bad_behavior_anr_label">ANR (Stop responding for 20 seconds)</string>
|
||||||
<string name="bad_behavior_anr_activity_label">ANR launching a new Activity</string>
|
<string name="bad_behavior_anr_activity_label">ANR starting an Activity</string>
|
||||||
<string name="bad_behavior_anr_broadcast_label">ANR receiving a broadcast Intent</string>
|
<string name="bad_behavior_anr_broadcast_label">ANR receiving a broadcast Intent</string>
|
||||||
<string name="bad_behavior_anr_service_label">ANR starting a Service</string>
|
<string name="bad_behavior_anr_service_label">ANR starting a Service</string>
|
||||||
|
<string name="bad_behavior_anr_system_label">System ANR (in ActivityManager)</string>
|
||||||
|
<string name="bad_behavior_wedge_system_label">Wedge system (5 minute system ANR)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
package com.android.development;
|
package com.android.development;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityManagerNative;
|
||||||
|
import android.app.IActivityController;
|
||||||
|
import android.app.IActivityManager;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -45,8 +48,9 @@ public class BadBehaviorActivity extends Activity {
|
|||||||
public static class BadReceiver extends BroadcastReceiver {
|
public static class BadReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Log.i(TAG, "in BadReceiver.onReceive() -- about to hang");
|
Log.i(TAG, "in broadcast receiver -- about to hang");
|
||||||
try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
||||||
|
Log.i(TAG, "broadcast receiver hang finished -- returning");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,13 +62,49 @@ public class BadBehaviorActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int id) {
|
public int onStartCommand(Intent intent, int flags, int id) {
|
||||||
Log.i(TAG, "in BadService.onStartCommand() -- about to hang");
|
Log.i(TAG, "in service start -- about to hang");
|
||||||
try { Thread.sleep(30000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
try { Thread.sleep(30000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
||||||
|
Log.i(TAG, "service hang finished -- stopping and returning");
|
||||||
stopSelf();
|
stopSelf();
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class BadController extends IActivityController.Stub {
|
||||||
|
private int mDelay;
|
||||||
|
|
||||||
|
public BadController(int delay) { mDelay = delay; }
|
||||||
|
|
||||||
|
public boolean activityStarting(Intent intent, String pkg) {
|
||||||
|
try {
|
||||||
|
ActivityManagerNative.getDefault().setActivityController(null);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Can't call IActivityManager.setActivityController", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDelay > 0) {
|
||||||
|
Log.i(TAG, "in activity controller -- about to hang");
|
||||||
|
try { Thread.sleep(mDelay); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
||||||
|
Log.i(TAG, "activity controller hang finished -- disabling and returning");
|
||||||
|
mDelay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean activityResuming(String pkg) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean appCrashed(String proc, int pid, String m, String m2, long time, String st) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int appNotResponding(String proc, int pid, String st) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
@@ -72,6 +112,13 @@ public class BadBehaviorActivity extends Activity {
|
|||||||
if (getIntent().getBooleanExtra("anr", false)) {
|
if (getIntent().getBooleanExtra("anr", false)) {
|
||||||
Log.i(TAG, "in ANR activity -- about to hang");
|
Log.i(TAG, "in ANR activity -- about to hang");
|
||||||
try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
||||||
|
Log.i(TAG, "activity hang finished -- finishing");
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getIntent().getBooleanExtra("dummy", false)) {
|
||||||
|
Log.i(TAG, "in dummy activity -- finishing");
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -127,6 +174,7 @@ public class BadBehaviorActivity extends Activity {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Log.i(TAG, "ANR pressed -- about to hang");
|
Log.i(TAG, "ANR pressed -- about to hang");
|
||||||
try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
|
||||||
|
Log.i(TAG, "hang finished -- returning");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -154,5 +202,35 @@ public class BadBehaviorActivity extends Activity {
|
|||||||
startService(new Intent(BadBehaviorActivity.this, BadService.class));
|
startService(new Intent(BadBehaviorActivity.this, BadService.class));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Button anr_system = (Button) findViewById(R.id.bad_behavior_anr_system);
|
||||||
|
anr_system.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(BadBehaviorActivity.this, BadBehaviorActivity.class);
|
||||||
|
Log.i(TAG, "ANR system pressed -- about to engage");
|
||||||
|
try {
|
||||||
|
ActivityManagerNative.getDefault().setActivityController(
|
||||||
|
new BadController(20000));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Can't call IActivityManager.setActivityController", e);
|
||||||
|
}
|
||||||
|
startActivity(intent.putExtra("dummy", true));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button wedge_system = (Button) findViewById(R.id.bad_behavior_wedge_system);
|
||||||
|
wedge_system.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(BadBehaviorActivity.this, BadBehaviorActivity.class);
|
||||||
|
Log.i(TAG, "Wedge system pressed -- about to engage");
|
||||||
|
try {
|
||||||
|
ActivityManagerNative.getDefault().setActivityController(
|
||||||
|
new BadController(300000));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Can't call IActivityManager.setActivityController", e);
|
||||||
|
}
|
||||||
|
startActivity(intent.putExtra("dummy", true));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user