118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/* 218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Copyright (C) 2013 The Android Open Source Project 318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * you may not use this file except in compliance with the License. 618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You may obtain a copy of the License at 718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 1018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Unless required by applicable law or agreed to in writing, software 1118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 1218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See the License for the specific language governing permissions and 1418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * limitations under the License. 1518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 1618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupackage com.android.testing.sleephelper; 1818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.Activity; 2018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.Instrumentation; 2118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.content.ComponentName; 2218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.content.Context; 2318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.content.Intent; 2418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.content.ServiceConnection; 2518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Bundle; 2618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Debug; 2718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.IBinder; 2818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.RemoteException; 2918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.Log; 3018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 3118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport com.android.testing.alarmservice.Alarm; 3218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 3318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupublic class SetAlarm extends Instrumentation { 3418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 3518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String COMMAND = "command"; 3618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String PARAM = "param"; 3718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String CMD_PREPARE = "prepare"; 3818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String CMD_SET = "set_wait"; 3918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String CMD_DONE = "done"; 4018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String SERVICE_ACTION = "com.android.testing.ALARM_SERVICE"; 4118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String SERVICE_PKG = "com.android.testing.alarmservice"; 4218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String LOG_TAG = SetAlarm.class.getSimpleName(); 4318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 4418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private Alarm mAlarmService = null; 4518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private Bundle mArgs = null; 4618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private String mCommand = null; 4718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private Intent mServceIntent = new Intent(SERVICE_ACTION).setPackage(SERVICE_PKG); 4818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 4918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private ServiceConnection mConn = new ServiceConnection() { 5018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 5118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void onServiceDisconnected(ComponentName name) { 5218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Log.d(LOG_TAG, "Service disconnected."); 5318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mAlarmService = null; 5418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("service disconnected"); 5518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 5618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 5718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 5818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void onServiceConnected(ComponentName name, IBinder service) { 5918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Log.d(LOG_TAG, "Service connected."); 6018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mAlarmService = Alarm.Stub.asInterface(service); 6118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu handleCommands(); 6218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 6318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu }; 6418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void handleCommands() { 6718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (CMD_PREPARE.equals(mCommand)) { 6818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu callPrepare(); 6918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (CMD_SET.equals(mCommand)) { 7018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String paramString = mArgs.getString(PARAM); 7118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (paramString == null) { 7218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("argument expected for alarm time"); 7318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 7418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu long timeout = -1; 7518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 7618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu timeout = Long.parseLong(paramString); 7718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (NumberFormatException nfe) { 7818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("a number argument is expected"); 7918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 8018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu callSetAndWait(timeout); 8118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (CMD_DONE.equals(mCommand)) { 8218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu callDone(); 8318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else { 8418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("Unrecognized command: " + mCommand); 8518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 8618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu finish(Activity.RESULT_OK, new Bundle()); 8718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 8818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 8918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 9018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void onCreate(Bundle arguments) { 9118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu super.onCreate(arguments); 9218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mCommand = arguments.getString(COMMAND); 9318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if ("true".equals(arguments.getString("debug"))) { 9418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Debug.waitForDebugger(); 9518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mCommand == null) { 9718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("No command specified"); 9818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mArgs = arguments; 10018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu connectToAlarmService(); 10118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 10218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 10318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void errorFinish(String msg) { 10418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Bundle ret = new Bundle(); 10518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ret.putString("error", msg); 10618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu finish(Activity.RESULT_CANCELED, ret); 10718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 10818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 10918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void connectToAlarmService() { 11018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // start the service with an intent, this ensures the service keeps running after unbind 11118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ComponentName cn = getContext().startService(mServceIntent); 11218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (cn == null) { 11318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("failed to start service"); 11418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (!getContext().bindService(mServceIntent, mConn, Context.BIND_AUTO_CREATE)) { 11618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("failed to bind service"); 11718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 12018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void callPrepare() { 12118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 12218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mAlarmService.prepare(); 12318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (RemoteException e) { 12418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("RemoteExeption in prepare()"); 12518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } finally { 12618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getContext().unbindService(mConn); 12718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 12818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 12918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 13018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void callDone() { 13118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 13218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mAlarmService.done(); 13318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (RemoteException e) { 13418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("RemoteExeption in prepare()"); 13518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } finally { 13618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getContext().unbindService(mConn); 13718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 13818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // explicitly stop the service (started in prepare()) so that the service is now free 13918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // to be reclaimed 14018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getContext().stopService(mServceIntent); 14118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 14218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 14318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void callSetAndWait(long timeoutMills) { 14418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 14518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mAlarmService.setAlarmAndWait(timeoutMills); 14618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (RemoteException e) { 14718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu errorFinish("RemoteExeption in setAlarmAndWait()"); 14818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } finally { 14918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getContext().unbindService(mConn); 15018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 15118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 15218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu} 153