1 /* 2 * Copyright (C) 2014 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 com.android.dreams.dozetest; 18 19 import android.app.AlarmManager; 20 import android.app.PendingIntent; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.os.Handler; 26 import android.os.PowerManager; 27 import android.service.dreams.DreamService; 28 import android.text.format.DateFormat; 29 import android.util.Log; 30 import android.view.Display; 31 import android.widget.TextView; 32 33 import java.util.Date; 34 35 /** 36 * Simple test for doze mode. 37 * <p> 38 * adb shell setprop debug.doze.component com.android.dreams.dozetest/.DozeTestDream 39 * </p> 40 */ 41 public class DozeTestDream extends DreamService { 42 private static final String TAG = DozeTestDream.class.getSimpleName(); 43 private static final boolean DEBUG = false; 44 45 // Amount of time to allow to update the time shown on the screen before releasing 46 // the wakelock. This timeout is design to compensate for the fact that we don't 47 // currently have a way to know when time display contents have actually been 48 // refreshed once the dream has finished rendering a new frame. 49 private static final int UPDATE_TIME_TIMEOUT = 100; 50 51 // Not all hardware supports dozing. We should use Display.STATE_DOZE but 52 // for testing purposes it is convenient to use Display.STATE_ON so the 53 // test still works on hardware that does not support dozing. 54 private static final int DISPLAY_STATE_WHEN_DOZING = Display.STATE_ON; 55 56 private PowerManager mPowerManager; 57 private PowerManager.WakeLock mWakeLock; 58 private AlarmManager mAlarmManager; 59 private PendingIntent mAlarmIntent; 60 private Handler mHandler = new Handler(); 61 62 private TextView mAlarmClock; 63 64 private final Date mTime = new Date(); 65 private java.text.DateFormat mTimeFormat; 66 67 private boolean mDreaming; 68 69 private long mLastTime = Long.MIN_VALUE; 70 71 @Override onCreate()72 public void onCreate() { 73 super.onCreate(); 74 75 mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); 76 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 77 78 mAlarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); 79 80 Intent intent = new Intent("com.android.dreams.dozetest.ACTION_ALARM"); 81 intent.setPackage(getPackageName()); 82 IntentFilter filter = new IntentFilter(); 83 filter.addAction(intent.getAction()); 84 registerReceiver(mAlarmReceiver, filter, 85 Context.RECEIVER_EXPORTED_UNAUDITED); 86 mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent, 87 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED); 88 89 setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); 90 } 91 92 @Override onDestroy()93 public void onDestroy() { 94 super.onDestroy(); 95 96 unregisterReceiver(mAlarmReceiver); 97 mAlarmIntent.cancel(); 98 } 99 100 @Override onAttachedToWindow()101 public void onAttachedToWindow() { 102 super.onAttachedToWindow(); 103 setInteractive(false); 104 setFullscreen(true); 105 setContentView(R.layout.dream); 106 setScreenBright(false); 107 108 mAlarmClock = (TextView)findViewById(R.id.alarm_clock); 109 110 mTimeFormat = DateFormat.getTimeFormat(this); 111 } 112 113 @Override onDreamingStarted()114 public void onDreamingStarted() { 115 super.onDreamingStarted(); 116 117 mDreaming = true; 118 119 Log.d(TAG, "Dream started: canDoze=" + canDoze()); 120 121 performTimeUpdate(); 122 123 startDozing(); 124 } 125 126 @Override onDreamingStopped()127 public void onDreamingStopped() { 128 super.onDreamingStopped(); 129 130 mDreaming = false; 131 132 Log.d(TAG, "Dream ended: isDozing=" + isDozing()); 133 134 stopDozing(); 135 cancelTimeUpdate(); 136 } 137 performTimeUpdate()138 private void performTimeUpdate() { 139 if (mDreaming) { 140 long now = System.currentTimeMillis(); 141 now -= now % 60000; // back up to last minute boundary 142 if (mLastTime == now) { 143 return; 144 } 145 146 mLastTime = now; 147 mTime.setTime(now); 148 mAlarmClock.setText(mTimeFormat.format(mTime)); 149 150 mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, now + 60000, mAlarmIntent); 151 152 mWakeLock.acquire(UPDATE_TIME_TIMEOUT + 5000 /*for testing brightness*/); 153 154 // flash the screen a bit to test these functions 155 setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); 156 setDozeScreenBrightness(200); 157 mHandler.postDelayed(new Runnable() { 158 @Override 159 public void run() { 160 setDozeScreenBrightness(50); 161 } 162 }, 2000); 163 mHandler.postDelayed(new Runnable() { 164 @Override 165 public void run() { 166 setDozeScreenState(Display.STATE_OFF); 167 } 168 }, 5000); 169 } 170 } 171 cancelTimeUpdate()172 private void cancelTimeUpdate() { 173 mAlarmManager.cancel(mAlarmIntent); 174 } 175 176 private final BroadcastReceiver mAlarmReceiver = new BroadcastReceiver() { 177 @Override 178 public void onReceive(Context context, Intent intent) { 179 performTimeUpdate(); 180 } 181 }; 182 } 183