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