185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu/* 285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * Copyright (C) 2014 The Android Open Source Project 385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * 485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * you may not use this file except in compliance with the License. 685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * You may obtain a copy of the License at 785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * 885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * http://www.apache.org/licenses/LICENSE-2.0 985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * 1085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * Unless required by applicable law or agreed to in writing, software 1185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 1285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * See the License for the specific language governing permissions and 1485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * limitations under the License. 1585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu */ 1685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 1785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhupackage android.test.wakeuploop; 1885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 1985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.app.AlarmManager; 2085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.app.PendingIntent; 2185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.content.BroadcastReceiver; 2285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.content.Context; 2385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.content.Intent; 2485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.Environment; 2585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.Message; 2685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.Messenger; 2785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.PowerManager; 2885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.PowerManager.WakeLock; 2985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.RemoteException; 3085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.os.SystemClock; 3185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport android.util.Log; 3285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 3385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhuimport java.io.File; 3485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 3585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu/** 3685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * The receiver for the alarm we set 3785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu * 3885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu */ 3985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhupublic class WakeUpCall extends BroadcastReceiver { 4085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu private static final String LOG_TAG = WakeUpCall.class.getSimpleName(); 4185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu static final String WAKEUP_CALL = "android.test.wakeuploop.WAKEUP"; 4285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu static final String CANCEL = "CANCEL"; 4385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 4485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu @Override 4585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu public void onReceive(Context context, Intent intent) { 4685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 4785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu boolean cancel = intent.hasExtra(CANCEL); 4885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu if (!cancel) { 4985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu long maxLoop = intent.getLongExtra(WakeLoopService.MAX_LOOP, 0); 5085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu long wakeupInterval = intent.getLongExtra(WakeLoopService.WAKEUP_INTERNAL, 0); 5185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu long thisLoop = intent.getLongExtra(WakeLoopService.THIS_LOOP, -1); 5285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.d(LOG_TAG, String.format("incoming: interval = %d, max loop = %d, this loop = %d", 5385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu wakeupInterval, maxLoop, thisLoop)); 5485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu if (thisLoop == -1) { 5585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.e(LOG_TAG, "no valid loop count received, trying to stop service"); 5685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu stopService(intent); 5785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu return; 5885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 5985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu if (wakeupInterval == 0) { 6085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.e(LOG_TAG, "no valid wakeup interval received, trying to stop service"); 6185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu stopService(intent); 6285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu return; 6385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 6485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu thisLoop++; 6585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.d(LOG_TAG, String.format("WakeLoop - iteration %d of %d", thisLoop, maxLoop)); 6685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu if (thisLoop == maxLoop) { 6785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu // when maxLoop is 0, we loop forever, so not checking that case 6885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu // here 6985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.d(LOG_TAG, "reached max loop count, stopping service"); 7085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu stopService(intent); 7185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu return; 7285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 7385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu screenOn(context); 7485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu FileUtil.get().writeDateToFile( 7585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu new File(Environment.getExternalStorageDirectory(), "wakeup-loop.txt")); 7685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu // calculate when device should be waken up 7785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu long atTime = SystemClock.elapsedRealtime() + wakeupInterval; 7885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu intent.putExtra(WakeLoopService.THIS_LOOP, thisLoop); 7985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 8085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu PendingIntent.FLAG_UPDATE_CURRENT); 8185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu // set alarm, which will be delivered in form of the wakeupIntent 8285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, atTime, pi); 8385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } else { 8485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu // cancel alarms 8585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.d(LOG_TAG, "cancelling future alarms on request"); 8685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu am.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); 8785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 8885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 8985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 9085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu private void stopService(Intent i) { 9185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Messenger msgr = i.getParcelableExtra(WakeLoopService.STOP_CALLBACK); 9285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu if (msgr == null) { 9385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.e(LOG_TAG, "no stop service callback found, cannot stop"); 9485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } else { 9585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Message msg = new Message(); 9685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu msg.what = WakeLoopService.MSG_STOP_SERVICE; 9785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu try { 9885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu msgr.send(msg); 9985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } catch (RemoteException e) { 10085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu Log.e(LOG_TAG, "ignored remoted exception while attempting to stop service", e); 10185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 10285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 10385c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 10485c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu 10585c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu private void screenOn(Context context) { 10685c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 10785c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu @SuppressWarnings("deprecation") 10885c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | 10985c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu PowerManager.ACQUIRE_CAUSES_WAKEUP, LOG_TAG); 11085c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu wl.acquire(500); 11185c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu } 11285c70eeb6cd10cc556373e64db50c6592b5278afGuang Zhu} 113