2020import android .content .ComponentName ;
2121import android .content .Intent ;
2222import android .content .ServiceConnection ;
23+ import android .os .Binder ;
2324import android .os .Bundle ;
2425import android .os .Handler ;
2526import android .os .IBinder ;
4546public class FrameworkPerfActivity extends Activity
4647 implements AdapterView .OnItemSelectedListener {
4748 static final String TAG = "Perf" ;
49+ static final boolean DEBUG = false ;
4850
4951 Spinner mFgSpinner ;
5052 Spinner mBgSpinner ;
@@ -67,22 +69,47 @@ public class FrameworkPerfActivity extends Activity
6769 TestService .Op mBgTest ;
6870 int mCurOpIndex = 0 ;
6971 TestConnection mCurConnection ;
72+ boolean mConnectionBound ;
7073
7174 final ArrayList <RunResult > mResults = new ArrayList <RunResult >();
7275
73- class TestConnection implements ServiceConnection {
76+ class TestConnection implements ServiceConnection , IBinder . DeathRecipient {
7477 Messenger mService ;
78+ boolean mLinked ;
7579
7680 @ Override public void onServiceConnected (ComponentName name , IBinder service ) {
77- mService = new Messenger (service );
78- dispatchCurOp (this );
81+ try {
82+ if (!(service instanceof Binder )) {
83+ // If remote, we'll be killing ye.
84+ service .linkToDeath (this , 0 );
85+ mLinked = true ;
86+ }
87+ mService = new Messenger (service );
88+ dispatchCurOp (this );
89+ } catch (RemoteException e ) {
90+ // Whoops, service has disappeared... try starting again.
91+ Log .w (TAG , "Test service died, starting again" );
92+ startCurOp ();
93+ }
7994 }
8095
8196 @ Override public void onServiceDisconnected (ComponentName name ) {
8297 }
98+
99+ @ Override public void binderDied () {
100+ cleanup ();
101+ connectionDied (this );
102+ }
103+
104+ void cleanup () {
105+ if (mLinked ) {
106+ mLinked = false ;
107+ mService .getBinder ().unlinkToDeath (this , 0 );
108+ }
109+ }
83110 }
84111
85- static final int MSG_CONTINUE = 1000 ;
112+ static final int MSG_DO_NEXT_TEST = 1000 ;
86113
87114 final Handler mHandler = new Handler () {
88115 @ Override public void handleMessage (Message msg ) {
@@ -93,11 +120,7 @@ class TestConnection implements ServiceConnection {
93120 RunResult res = (RunResult )bundle .getParcelable ("res" );
94121 completeCurOp (res );
95122 } break ;
96- case TestService .RES_TERMINATED : {
97- // Give a little time for things to settle down.
98- sendMessageDelayed (obtainMessage (MSG_CONTINUE ), 500 );
99- } break ;
100- case MSG_CONTINUE : {
123+ case MSG_DO_NEXT_TEST : {
101124 startCurOp ();
102125 } break ;
103126 }
@@ -235,7 +258,7 @@ void dispatchCurOp(TestConnection conn) {
235258 try {
236259 conn .mService .send (msg );
237260 } catch (RemoteException e ) {
238- Log .i (TAG , "Failure communicating with service" , e );
261+ Log .w (TAG , "Failure communicating with service" , e );
239262 }
240263 }
241264
@@ -273,37 +296,69 @@ void completeCurOp(RunResult result) {
273296 }
274297
275298 void disconnect () {
276- if (mCurConnection != null ) {
277- unbindService (mCurConnection );
278- if (mCurConnection .mService != null ) {
299+ final TestConnection conn = mCurConnection ;
300+ if (conn != null ) {
301+ if (DEBUG ) {
302+ RuntimeException here = new RuntimeException ("here" );
303+ here .fillInStackTrace ();
304+ Log .i (TAG , "Unbinding " + conn , here );
305+ }
306+ if (mConnectionBound ) {
307+ unbindService (conn );
308+ mConnectionBound = false ;
309+ }
310+ if (conn .mLinked ) {
279311 Message msg = Message .obtain (null , TestService .CMD_TERMINATE );
280- msg .replyTo = mMessenger ;
281312 try {
282- mCurConnection .mService .send (msg );
313+ conn .mService .send (msg );
314+ return ;
283315 } catch (RemoteException e ) {
284- Log .i (TAG , "Failure communicating with service" , e );
316+ Log .w (TAG , "Test service aleady died when terminating" );
285317 }
286318 }
319+ conn .cleanup ();
320+ }
321+ connectionDied (conn );
322+ }
323+
324+ void connectionDied (TestConnection conn ) {
325+ if (mCurConnection == conn ) {
326+ // Now that we know the test process has died, we can commence
327+ // the next test. Just give a little delay to allow the activity
328+ // manager to know it has died as well (not a disaster if it hasn't
329+ // yet, though).
330+ if (mConnectionBound ) {
331+ unbindService (conn );
332+ }
287333 mCurConnection = null ;
334+ mHandler .sendMessageDelayed (Message .obtain (null , MSG_DO_NEXT_TEST ), 100 );
288335 }
289336 }
290337
291338 void startCurOp () {
339+ if (DEBUG ) Log .i (TAG , "startCurOp: mCurConnection=" + mCurConnection );
292340 if (mCurConnection != null ) {
293341 disconnect ();
342+ return ;
294343 }
295344 if (mStarted ) {
296345 mHandler .removeMessages (TestService .RES_TEST_FINISHED );
297346 mHandler .removeMessages (TestService .RES_TERMINATED );
298- mHandler .removeMessages (MSG_CONTINUE );
347+ mHandler .removeMessages (MSG_DO_NEXT_TEST );
299348 mCurConnection = new TestConnection ();
300349 Intent intent ;
301350 if (mLocalCheckBox .isChecked ()) {
302351 intent = new Intent (this , LocalTestService .class );
303352 } else {
304353 intent = new Intent (this , TestService .class );
305354 }
355+ if (DEBUG ) {
356+ RuntimeException here = new RuntimeException ("here" );
357+ here .fillInStackTrace ();
358+ Log .i (TAG , "Binding " + mCurConnection , here );
359+ }
306360 bindService (intent , mCurConnection , BIND_AUTO_CREATE |BIND_IMPORTANT );
361+ mConnectionBound = true ;
307362 }
308363 }
309364
0 commit comments