1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.development;
18
19import android.app.Activity;
20import android.app.ActivityManagerNative;
21import android.app.IActivityController;
22import android.app.IActivityManager;
23import android.app.Service;
24import android.content.BroadcastReceiver;
25import android.content.Context;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.os.Bundle;
29import android.os.IBinder;
30import android.os.IPowerManager;
31import android.os.Process;
32import android.os.RemoteException;
33import android.os.ServiceManager;
34import android.util.Log;
35import android.view.View;
36import android.widget.Button;
37
38public class BadBehaviorActivity extends Activity {
39    private static final String TAG = "BadBehaviorActivity";
40
41    private static class BadBehaviorException extends RuntimeException {
42        BadBehaviorException() {
43            super("Whatcha gonna do, whatcha gonna do",
44                    new IllegalStateException("When they come for you"));
45        }
46    }
47
48    public static class BadReceiver extends BroadcastReceiver {
49        @Override
50        public void onReceive(Context context, Intent intent) {
51            Log.i(TAG, "in broadcast receiver -- about to hang");
52            try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
53            Log.i(TAG, "broadcast receiver hang finished -- returning");
54        }
55    };
56
57    public static class BadService extends Service {
58        @Override
59        public IBinder onBind(Intent intent) {
60            return null;
61        }
62
63        @Override
64        public int onStartCommand(Intent intent, int flags, int id) {
65            Log.i(TAG, "in service start -- about to hang");
66            try { Thread.sleep(30000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
67            Log.i(TAG, "service hang finished -- stopping and returning");
68            stopSelf();
69            return START_NOT_STICKY;
70        }
71    }
72
73    public static class BadController extends IActivityController.Stub {
74        private int mDelay;
75
76        public BadController(int delay) { mDelay = delay; }
77
78        public boolean activityStarting(Intent intent, String pkg) {
79            try {
80                ActivityManagerNative.getDefault().setActivityController(null);
81            } catch (RemoteException e) {
82                Log.e(TAG, "Can't call IActivityManager.setActivityController", e);
83            }
84
85            if (mDelay > 0) {
86                Log.i(TAG, "in activity controller -- about to hang");
87                try { Thread.sleep(mDelay); } catch (InterruptedException e) { Log.wtf(TAG, e); }
88                Log.i(TAG, "activity controller hang finished -- disabling and returning");
89                mDelay = 0;
90            }
91
92            return true;
93        }
94
95        public boolean activityResuming(String pkg) {
96            return true;
97        }
98
99        public boolean appCrashed(String proc, int pid, String m, String m2, long time, String st) {
100            return true;
101        }
102
103        public int appEarlyNotResponding(String processName, int pid, String annotation) {
104            return 0;
105        }
106
107        public int appNotResponding(String proc, int pid, String st) {
108            return 0;
109        }
110    }
111
112    @Override
113    public void onCreate(Bundle icicle) {
114        super.onCreate(icicle);
115
116        if (getIntent().getBooleanExtra("anr", false)) {
117            Log.i(TAG, "in ANR activity -- about to hang");
118            try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
119            Log.i(TAG, "activity hang finished -- finishing");
120            finish();
121            return;
122        }
123
124        if (getIntent().getBooleanExtra("dummy", false)) {
125            Log.i(TAG, "in dummy activity -- finishing");
126            finish();
127            return;
128        }
129
130        setContentView(R.layout.bad_behavior);
131
132        Button crash_system = (Button) findViewById(R.id.bad_behavior_crash_system);
133        crash_system.setOnClickListener(new View.OnClickListener() {
134            public void onClick(View v) {
135                try {
136                    IBinder b = ServiceManager.getService(POWER_SERVICE);
137                    IPowerManager pm = IPowerManager.Stub.asInterface(b);
138                    pm.crash("Crashed by BadBehaviorActivity");
139                } catch (RemoteException e) {
140                    Log.e(TAG, "Can't call IPowerManager.crash()", e);
141                }
142            }
143        });
144
145        Button crash_main = (Button) findViewById(R.id.bad_behavior_crash_main);
146        crash_main.setOnClickListener(new View.OnClickListener() {
147            public void onClick(View v) { throw new BadBehaviorException(); }
148        });
149
150        Button crash_thread = (Button) findViewById(R.id.bad_behavior_crash_thread);
151        crash_thread.setOnClickListener(new View.OnClickListener() {
152            public void onClick(View v) {
153                new Thread() {
154                    @Override
155                    public void run() { throw new BadBehaviorException(); }
156                }.start();
157            }
158        });
159
160        Button crash_native = (Button) findViewById(R.id.bad_behavior_crash_native);
161        crash_native.setOnClickListener(new View.OnClickListener() {
162            public void onClick(View v) {
163                // For some reason, the JVM needs two of these to get the hint
164                Log.i(TAG, "Native crash pressed -- about to kill -11 self");
165                Process.sendSignal(Process.myPid(), 11);
166                Process.sendSignal(Process.myPid(), 11);
167                Log.i(TAG, "Finished kill -11, should be dead or dying");
168            }
169        });
170
171        Button wtf = (Button) findViewById(R.id.bad_behavior_wtf);
172        wtf.setOnClickListener(new View.OnClickListener() {
173            public void onClick(View v) { Log.wtf(TAG, "Apps Behaving Badly"); }
174        });
175
176        Button anr = (Button) findViewById(R.id.bad_behavior_anr);
177        anr.setOnClickListener(new View.OnClickListener() {
178            public void onClick(View v) {
179                Log.i(TAG, "ANR pressed -- about to hang");
180                try { Thread.sleep(20000); } catch (InterruptedException e) { Log.wtf(TAG, e); }
181                Log.i(TAG, "hang finished -- returning");
182            }
183        });
184
185        Button anr_activity = (Button) findViewById(R.id.bad_behavior_anr_activity);
186        anr_activity.setOnClickListener(new View.OnClickListener() {
187            public void onClick(View v) {
188                Intent intent = new Intent(BadBehaviorActivity.this, BadBehaviorActivity.class);
189                Log.i(TAG, "ANR activity pressed -- about to launch");
190                startActivity(intent.putExtra("anr", true));
191            }
192        });
193
194        Button anr_broadcast = (Button) findViewById(R.id.bad_behavior_anr_broadcast);
195        anr_broadcast.setOnClickListener(new View.OnClickListener() {
196            public void onClick(View v) {
197                Log.i(TAG, "ANR broadcast pressed -- about to send");
198                sendOrderedBroadcast(new Intent("com.android.development.BAD_BEHAVIOR"), null);
199            }
200        });
201
202        Button anr_service = (Button) findViewById(R.id.bad_behavior_anr_service);
203        anr_service.setOnClickListener(new View.OnClickListener() {
204            public void onClick(View v) {
205                Log.i(TAG, "ANR service pressed -- about to start");
206                startService(new Intent(BadBehaviorActivity.this, BadService.class));
207            }
208        });
209
210        Button anr_system = (Button) findViewById(R.id.bad_behavior_anr_system);
211        anr_system.setOnClickListener(new View.OnClickListener() {
212            public void onClick(View v) {
213                Intent intent = new Intent(BadBehaviorActivity.this, BadBehaviorActivity.class);
214                Log.i(TAG, "ANR system pressed -- about to engage");
215                try {
216                    ActivityManagerNative.getDefault().setActivityController(
217                        new BadController(20000));
218                } catch (RemoteException e) {
219                    Log.e(TAG, "Can't call IActivityManager.setActivityController", e);
220                }
221                startActivity(intent.putExtra("dummy", true));
222            }
223        });
224
225        Button wedge_system = (Button) findViewById(R.id.bad_behavior_wedge_system);
226        wedge_system.setOnClickListener(new View.OnClickListener() {
227            public void onClick(View v) {
228                Intent intent = new Intent(BadBehaviorActivity.this, BadBehaviorActivity.class);
229                Log.i(TAG, "Wedge system pressed -- about to engage");
230                try {
231                    ActivityManagerNative.getDefault().setActivityController(
232                        new BadController(300000));
233                } catch (RemoteException e) {
234                    Log.e(TAG, "Can't call IActivityManager.setActivityController", e);
235                }
236                startActivity(intent.putExtra("dummy", true));
237            }
238        });
239    }
240}
241