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 mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent, 86 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED); 87 88 setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); 89 } 90 91 @Override onDestroy()92 public void onDestroy() { 93 super.onDestroy(); 94 95 unregisterReceiver(mAlarmReceiver); 96 mAlarmIntent.cancel(); 97 } 98 99 @Override onAttachedToWindow()100 public void onAttachedToWindow() { 101 super.onAttachedToWindow(); 102 setInteractive(false); 103 setFullscreen(true); 104 setContentView(R.layout.dream); 105 setScreenBright(false); 106 107 mAlarmClock = (TextView)findViewById(R.id.alarm_clock); 108 109 mTimeFormat = DateFormat.getTimeFormat(this); 110 } 111 112 @Override onDreamingStarted()113 public void onDreamingStarted() { 114 super.onDreamingStarted(); 115 116 mDreaming = true; 117 118 Log.d(TAG, "Dream started: canDoze=" + canDoze()); 119 120 performTimeUpdate(); 121 122 startDozing(); 123 } 124 125 @Override onDreamingStopped()126 public void onDreamingStopped() { 127 super.onDreamingStopped(); 128 129 mDreaming = false; 130 131 Log.d(TAG, "Dream ended: isDozing=" + isDozing()); 132 133 stopDozing(); 134 cancelTimeUpdate(); 135 } 136 performTimeUpdate()137 private void performTimeUpdate() { 138 if (mDreaming) { 139 long now = System.currentTimeMillis(); 140 now -= now % 60000; // back up to last minute boundary 141 if (mLastTime == now) { 142 return; 143 } 144 145 mLastTime = now; 146 mTime.setTime(now); 147 mAlarmClock.setText(mTimeFormat.format(mTime)); 148 149 mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, now + 60000, mAlarmIntent); 150 151 mWakeLock.acquire(UPDATE_TIME_TIMEOUT + 5000 /*for testing brightness*/); 152 153 // flash the screen a bit to test these functions 154 setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); 155 setDozeScreenBrightness(200); 156 mHandler.postDelayed(new Runnable() { 157 @Override 158 public void run() { 159 setDozeScreenBrightness(50); 160 } 161 }, 2000); 162 mHandler.postDelayed(new Runnable() { 163 @Override 164 public void run() { 165 setDozeScreenState(Display.STATE_OFF); 166 } 167 }, 5000); 168 } 169 } 170 cancelTimeUpdate()171 private void cancelTimeUpdate() { 172 mAlarmManager.cancel(mAlarmIntent); 173 } 174 175 private final BroadcastReceiver mAlarmReceiver = new BroadcastReceiver() { 176 @Override 177 public void onReceive(Context context, Intent intent) { 178 performTimeUpdate(); 179 } 180 }; 181 } 182