1 /* 2 * Copyright (C) 2012 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 17 package android.cts.tagging; 18 19 import android.app.Activity; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.ServiceConnection; 24 import android.cts.tagging.TestingService; 25 import android.os.Handler; 26 import android.os.IBinder; 27 import android.os.Message; 28 import android.os.Messenger; 29 import android.os.RemoteException; 30 import android.util.Log; 31 32 public class ServiceRunnerActivity extends Activity { 33 private static String TAG = ServiceRunnerActivity.class.getName(); 34 35 private Messenger mService; 36 private boolean mIsBound; 37 38 private int mResult; 39 private final Object mFinishEvent = new Object(); 40 getResult()41 public synchronized int getResult() { return mResult; } 42 43 // Handler of incoming messages from service. 44 class IncomingHandler extends Handler { 45 private ServiceRunnerActivity mActivity; 46 IncomingHandler(ServiceRunnerActivity activity)47 IncomingHandler(ServiceRunnerActivity activity) { mActivity = activity; } 48 49 @Override handleMessage(Message msg)50 public void handleMessage(Message msg) { 51 switch (msg.what) { 52 case TestingService.MSG_NOTIFY_TEST_RESULT: 53 synchronized (mActivity.mFinishEvent) { 54 mActivity.mResult = msg.arg1; 55 mFinishEvent.notify(); 56 } 57 doUnbindService(); 58 break; 59 default: 60 super.handleMessage(msg); 61 return; 62 } 63 } 64 } 65 66 // Target we publish for clients to send messages to IncomingHandler. 67 final Messenger mMessenger = new Messenger(new IncomingHandler(this)); 68 69 private ServiceConnection mConnection = new ServiceConnection() { 70 @Override 71 public void onServiceConnected(ComponentName className, IBinder service) { 72 mService = new Messenger(service); 73 74 // Send a message to the service to register. 75 try { 76 Message msg = Message.obtain(null, TestingService.MSG_START_TEST); 77 msg.replyTo = mMessenger; 78 mService.send(msg); 79 } catch (RemoteException e) { 80 // In this case the service has crashed before we could even do anything. 81 Log.e(TAG, "Failed to send start message to service."); 82 } 83 } 84 85 @Override 86 public void onServiceDisconnected(ComponentName className) { 87 // This is called when the connection with the service has been unexpectedly 88 // disconnected -- that is, its process crashed. 89 Log.i(TAG, "Service disconnected."); 90 mService = null; 91 synchronized (mFinishEvent) { 92 mResult = TestingService.RESULT_TEST_CRASHED; 93 mFinishEvent.notify(); 94 } 95 } 96 }; 97 doUnbindService()98 void doUnbindService() { 99 // Detach our existing connection. 100 unbindService(mConnection); 101 mIsBound = false; 102 } 103 runExternalService(ComponentName component)104 public void runExternalService(ComponentName component) throws Exception { 105 Intent intent = new Intent(); 106 intent.setComponent(component); 107 runServiceCommon(intent, true); 108 } 109 runService(Class<?> cls)110 public void runService(Class<?> cls) throws Exception { 111 Intent intent = new Intent(this, cls); 112 runServiceCommon(intent, false); 113 } 114 runServiceCommon(Intent intent, boolean external)115 void runServiceCommon(Intent intent, boolean external) throws Exception { 116 mResult = TestingService.RESULT_TEST_UNKNOWN; 117 int flags = Context.BIND_AUTO_CREATE; 118 if (external) 119 flags |= Context.BIND_EXTERNAL_SERVICE; 120 boolean result = bindService(intent, mConnection, flags); 121 if (result == false) { 122 mResult = TestingService.RESULT_TEST_BIND_FAILED; 123 return; 124 } 125 126 mIsBound = true; 127 Thread thread = new Thread() { 128 @Override 129 public void run() { 130 synchronized (mFinishEvent) { 131 while (mResult == TestingService.RESULT_TEST_UNKNOWN) { 132 try { 133 mFinishEvent.wait(); 134 } catch (InterruptedException e) { 135 } 136 } 137 } 138 } 139 }; 140 thread.start(); 141 thread.join(50000 /* millis */); 142 } 143 } 144