12687550272ba061448f5d5b914700dc335299ee7Jeff Brown/* 22687550272ba061448f5d5b914700dc335299ee7Jeff Brown * Copyright (C) 2014 The Android Open Source Project 32687550272ba061448f5d5b914700dc335299ee7Jeff Brown * 42687550272ba061448f5d5b914700dc335299ee7Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 52687550272ba061448f5d5b914700dc335299ee7Jeff Brown * you may not use this file except in compliance with the License. 62687550272ba061448f5d5b914700dc335299ee7Jeff Brown * You may obtain a copy of the License at 72687550272ba061448f5d5b914700dc335299ee7Jeff Brown * 82687550272ba061448f5d5b914700dc335299ee7Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 92687550272ba061448f5d5b914700dc335299ee7Jeff Brown * 102687550272ba061448f5d5b914700dc335299ee7Jeff Brown * Unless required by applicable law or agreed to in writing, software 112687550272ba061448f5d5b914700dc335299ee7Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 122687550272ba061448f5d5b914700dc335299ee7Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132687550272ba061448f5d5b914700dc335299ee7Jeff Brown * See the License for the specific language governing permissions and 142687550272ba061448f5d5b914700dc335299ee7Jeff Brown * limitations under the License. 152687550272ba061448f5d5b914700dc335299ee7Jeff Brown */ 162687550272ba061448f5d5b914700dc335299ee7Jeff Brown 172687550272ba061448f5d5b914700dc335299ee7Jeff Brownpackage com.android.dreams.dozetest; 182687550272ba061448f5d5b914700dc335299ee7Jeff Brown 192687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.app.AlarmManager; 202687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.app.PendingIntent; 212687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.content.BroadcastReceiver; 222687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.content.Context; 232687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.content.Intent; 242687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.content.IntentFilter; 25970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brownimport android.os.Handler; 262687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.os.PowerManager; 272687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.service.dreams.DreamService; 282687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.text.format.DateFormat; 292687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.util.Log; 30970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brownimport android.view.Display; 312687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.widget.TextView; 322687550272ba061448f5d5b914700dc335299ee7Jeff Brown 332687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport java.util.Date; 342687550272ba061448f5d5b914700dc335299ee7Jeff Brown 352687550272ba061448f5d5b914700dc335299ee7Jeff Brown/** 362687550272ba061448f5d5b914700dc335299ee7Jeff Brown * Simple test for doze mode. 372687550272ba061448f5d5b914700dc335299ee7Jeff Brown * <p> 382687550272ba061448f5d5b914700dc335299ee7Jeff Brown * adb shell setprop debug.doze.component com.android.dreams.dozetest/.DozeTestDream 392687550272ba061448f5d5b914700dc335299ee7Jeff Brown * </p> 402687550272ba061448f5d5b914700dc335299ee7Jeff Brown */ 412687550272ba061448f5d5b914700dc335299ee7Jeff Brownpublic class DozeTestDream extends DreamService { 422687550272ba061448f5d5b914700dc335299ee7Jeff Brown private static final String TAG = DozeTestDream.class.getSimpleName(); 432687550272ba061448f5d5b914700dc335299ee7Jeff Brown private static final boolean DEBUG = false; 442687550272ba061448f5d5b914700dc335299ee7Jeff Brown 452687550272ba061448f5d5b914700dc335299ee7Jeff Brown // Amount of time to allow to update the time shown on the screen before releasing 462687550272ba061448f5d5b914700dc335299ee7Jeff Brown // the wakelock. This timeout is design to compensate for the fact that we don't 472687550272ba061448f5d5b914700dc335299ee7Jeff Brown // currently have a way to know when time display contents have actually been 482687550272ba061448f5d5b914700dc335299ee7Jeff Brown // refreshed once the dream has finished rendering a new frame. 492687550272ba061448f5d5b914700dc335299ee7Jeff Brown private static final int UPDATE_TIME_TIMEOUT = 100; 502687550272ba061448f5d5b914700dc335299ee7Jeff Brown 51970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown // Not all hardware supports dozing. We should use Display.STATE_DOZE but 52970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown // for testing purposes it is convenient to use Display.STATE_ON so the 53970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown // test still works on hardware that does not support dozing. 54970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown private static final int DISPLAY_STATE_WHEN_DOZING = Display.STATE_ON; 55970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown 562687550272ba061448f5d5b914700dc335299ee7Jeff Brown private PowerManager mPowerManager; 572687550272ba061448f5d5b914700dc335299ee7Jeff Brown private PowerManager.WakeLock mWakeLock; 582687550272ba061448f5d5b914700dc335299ee7Jeff Brown private AlarmManager mAlarmManager; 592687550272ba061448f5d5b914700dc335299ee7Jeff Brown private PendingIntent mAlarmIntent; 60970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown private Handler mHandler = new Handler(); 612687550272ba061448f5d5b914700dc335299ee7Jeff Brown 622687550272ba061448f5d5b914700dc335299ee7Jeff Brown private TextView mAlarmClock; 632687550272ba061448f5d5b914700dc335299ee7Jeff Brown 642687550272ba061448f5d5b914700dc335299ee7Jeff Brown private final Date mTime = new Date(); 652687550272ba061448f5d5b914700dc335299ee7Jeff Brown private java.text.DateFormat mTimeFormat; 662687550272ba061448f5d5b914700dc335299ee7Jeff Brown 672687550272ba061448f5d5b914700dc335299ee7Jeff Brown private boolean mDreaming; 682687550272ba061448f5d5b914700dc335299ee7Jeff Brown 69970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown private long mLastTime = Long.MIN_VALUE; 70970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown 712687550272ba061448f5d5b914700dc335299ee7Jeff Brown @Override 722687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void onCreate() { 732687550272ba061448f5d5b914700dc335299ee7Jeff Brown super.onCreate(); 742687550272ba061448f5d5b914700dc335299ee7Jeff Brown 752687550272ba061448f5d5b914700dc335299ee7Jeff Brown mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); 762687550272ba061448f5d5b914700dc335299ee7Jeff Brown mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 772687550272ba061448f5d5b914700dc335299ee7Jeff Brown 782687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); 792687550272ba061448f5d5b914700dc335299ee7Jeff Brown 802687550272ba061448f5d5b914700dc335299ee7Jeff Brown Intent intent = new Intent("com.android.dreams.dozetest.ACTION_ALARM"); 812687550272ba061448f5d5b914700dc335299ee7Jeff Brown intent.setPackage(getPackageName()); 822687550272ba061448f5d5b914700dc335299ee7Jeff Brown IntentFilter filter = new IntentFilter(); 832687550272ba061448f5d5b914700dc335299ee7Jeff Brown filter.addAction(intent.getAction()); 842687550272ba061448f5d5b914700dc335299ee7Jeff Brown registerReceiver(mAlarmReceiver, filter); 852687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent, 862687550272ba061448f5d5b914700dc335299ee7Jeff Brown PendingIntent.FLAG_CANCEL_CURRENT); 87970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown 88970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); 892687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 902687550272ba061448f5d5b914700dc335299ee7Jeff Brown 912687550272ba061448f5d5b914700dc335299ee7Jeff Brown @Override 922687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void onDestroy() { 932687550272ba061448f5d5b914700dc335299ee7Jeff Brown super.onDestroy(); 942687550272ba061448f5d5b914700dc335299ee7Jeff Brown 952687550272ba061448f5d5b914700dc335299ee7Jeff Brown unregisterReceiver(mAlarmReceiver); 962687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmIntent.cancel(); 972687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 982687550272ba061448f5d5b914700dc335299ee7Jeff Brown 992687550272ba061448f5d5b914700dc335299ee7Jeff Brown @Override 1002687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void onAttachedToWindow() { 1012687550272ba061448f5d5b914700dc335299ee7Jeff Brown super.onAttachedToWindow(); 1022687550272ba061448f5d5b914700dc335299ee7Jeff Brown setInteractive(false); 1032687550272ba061448f5d5b914700dc335299ee7Jeff Brown setLowProfile(true); 1042687550272ba061448f5d5b914700dc335299ee7Jeff Brown setFullscreen(true); 1052687550272ba061448f5d5b914700dc335299ee7Jeff Brown setContentView(R.layout.dream); 106037c33eae74bee2774897d969d48947f9abe254fJeff Brown setScreenBright(false); 1072687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1082687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmClock = (TextView)findViewById(R.id.alarm_clock); 1092687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1102687550272ba061448f5d5b914700dc335299ee7Jeff Brown mTimeFormat = DateFormat.getTimeFormat(this); 1112687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1122687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1132687550272ba061448f5d5b914700dc335299ee7Jeff Brown @Override 1142687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void onDreamingStarted() { 1152687550272ba061448f5d5b914700dc335299ee7Jeff Brown super.onDreamingStarted(); 1162687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1172687550272ba061448f5d5b914700dc335299ee7Jeff Brown mDreaming = true; 1182687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1190f208eb707926f0afc1ce073be866bedd4955aa2Jeff Brown Log.d(TAG, "Dream started: canDoze=" + canDoze()); 1202687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1212687550272ba061448f5d5b914700dc335299ee7Jeff Brown performTimeUpdate(); 1222687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1232687550272ba061448f5d5b914700dc335299ee7Jeff Brown startDozing(); 1242687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1252687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1262687550272ba061448f5d5b914700dc335299ee7Jeff Brown @Override 1272687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void onDreamingStopped() { 1282687550272ba061448f5d5b914700dc335299ee7Jeff Brown super.onDreamingStopped(); 1292687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1302687550272ba061448f5d5b914700dc335299ee7Jeff Brown mDreaming = false; 1312687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1322687550272ba061448f5d5b914700dc335299ee7Jeff Brown Log.d(TAG, "Dream ended: isDozing=" + isDozing()); 1332687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1342687550272ba061448f5d5b914700dc335299ee7Jeff Brown stopDozing(); 1352687550272ba061448f5d5b914700dc335299ee7Jeff Brown cancelTimeUpdate(); 1362687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1372687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1382687550272ba061448f5d5b914700dc335299ee7Jeff Brown private void performTimeUpdate() { 1392687550272ba061448f5d5b914700dc335299ee7Jeff Brown if (mDreaming) { 1402687550272ba061448f5d5b914700dc335299ee7Jeff Brown long now = System.currentTimeMillis(); 1412687550272ba061448f5d5b914700dc335299ee7Jeff Brown now -= now % 60000; // back up to last minute boundary 142970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown if (mLastTime == now) { 143970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown return; 144970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown } 1452687550272ba061448f5d5b914700dc335299ee7Jeff Brown 146970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown mLastTime = now; 1472687550272ba061448f5d5b914700dc335299ee7Jeff Brown mTime.setTime(now); 1482687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmClock.setText(mTimeFormat.format(mTime)); 1492687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1502687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, now + 60000, mAlarmIntent); 1512687550272ba061448f5d5b914700dc335299ee7Jeff Brown 152970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown mWakeLock.acquire(UPDATE_TIME_TIMEOUT + 5000 /*for testing brightness*/); 153970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown 154970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown // flash the screen a bit to test these functions 155970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); 156970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown setDozeScreenBrightness(200); 157970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown mHandler.postDelayed(new Runnable() { 158970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown @Override 159970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown public void run() { 160970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown setDozeScreenBrightness(50); 161970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown } 162970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown }, 2000); 163970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown mHandler.postDelayed(new Runnable() { 164970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown @Override 165970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown public void run() { 166970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown setDozeScreenState(Display.STATE_OFF); 167970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown } 168970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown }, 5000); 1692687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1702687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1712687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1722687550272ba061448f5d5b914700dc335299ee7Jeff Brown private void cancelTimeUpdate() { 1732687550272ba061448f5d5b914700dc335299ee7Jeff Brown mAlarmManager.cancel(mAlarmIntent); 1742687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1752687550272ba061448f5d5b914700dc335299ee7Jeff Brown 1762687550272ba061448f5d5b914700dc335299ee7Jeff Brown private final BroadcastReceiver mAlarmReceiver = new BroadcastReceiver() { 1772687550272ba061448f5d5b914700dc335299ee7Jeff Brown @Override 1782687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void onReceive(Context context, Intent intent) { 1792687550272ba061448f5d5b914700dc335299ee7Jeff Brown performTimeUpdate(); 1802687550272ba061448f5d5b914700dc335299ee7Jeff Brown } 1812687550272ba061448f5d5b914700dc335299ee7Jeff Brown }; 1822687550272ba061448f5d5b914700dc335299ee7Jeff Brown} 183