DeskClock.java revision 7dd2d1f5fb1de58c8aef5bc102d21627924295cf
1f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler/* 2f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * Copyright (C) 2009 The Android Open Source Project 3f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * 4f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License"); 5f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * you may not use this file except in compliance with the License. 6f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * You may obtain a copy of the License at 7f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * 8f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * http://www.apache.org/licenses/LICENSE-2.0 9f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * 10f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * Unless required by applicable law or agreed to in writing, software 11f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS, 12f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * See the License for the specific language governing permissions and 14f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler * limitations under the License. 15f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler */ 16f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 17f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerpackage com.android.deskclock; 18f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 197fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikovimport static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN; 207fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov 21f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.app.Activity; 22ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandlerimport android.app.AlarmManager; 23ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandlerimport android.app.PendingIntent; 242f2ce735ef658f4e2b72fe9b0352fad9279e636dDianne Hackbornimport android.app.UiModeManager; 25ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandlerimport android.content.BroadcastReceiver; 26f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.content.Context; 27f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.content.Intent; 28ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandlerimport android.content.IntentFilter; 292763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.content.pm.PackageManager; 30f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.content.res.Configuration; 312763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.content.res.Resources; 32f6e3c42ec2bfd7e3440393bd5a0d498a513574c5Daniel Sandlerimport android.database.ContentObserver; 33f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.database.Cursor; 34f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandlerimport android.graphics.Rect; 352763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.graphics.drawable.Drawable; 36f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.net.Uri; 373b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandlerimport android.os.BatteryManager; 38f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.os.Bundle; 39f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.os.Handler; 402763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.os.Message; 41aa0d261b50d103dd718077b261dd0671d388266fDaniel Sandlerimport android.provider.MediaStore; 427fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikovimport android.provider.Settings; 43f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.text.TextUtils; 442ff01ef636c8896455e6780fbe14cd0dca207969Daniel Sandlerimport android.text.format.DateFormat; 4591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandlerimport android.util.DisplayMetrics; 4672a353a7d443f17a0e16412ae85ad359d97e9394Daniel Sandlerimport android.util.Log; 47ec04d6516961bac094fbb2dade7925adecac6c80Erikimport android.view.GestureDetector; 48f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.view.Menu; 494e8ad3a40141d05ced3279c6a0296b71ffc5117dDaniel Sandlerimport android.view.MenuInflater; 50f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.view.MenuItem; 51f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandlerimport android.view.MotionEvent; 522763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.view.View; 53f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.view.ViewGroup; 54f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandlerimport android.view.ViewTreeObserver; 55f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.view.Window; 56f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerimport android.view.WindowManager; 572763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.view.animation.AnimationUtils; 5891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandlerimport android.widget.AbsoluteLayout; 59f8952fa79d0cc70e5a802fb2624701fbed0736b8Daniel Sandlerimport android.widget.ImageButton; 602763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.widget.ImageView; 612763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandlerimport android.widget.TextView; 62f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 63ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandlerimport java.util.Calendar; 64ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandlerimport java.util.Date; 6591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandlerimport java.util.Random; 66f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 67f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler/** 687dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler * DeskClock clock view for desk docks. 69f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler */ 70f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandlerpublic class DeskClock extends Activity { 71e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler private static final boolean DEBUG = false; 72f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 7372a353a7d443f17a0e16412ae85ad359d97e9394Daniel Sandler private static final String LOG_TAG = "DeskClock"; 7472a353a7d443f17a0e16412ae85ad359d97e9394Daniel Sandler 759463551d754302e158b80357d9c5c88517fe6e58Daniel Sandler // Alarm action for midnight (so we can update the date display). 76ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler private static final String ACTION_MIDNIGHT = "com.android.deskclock.MIDNIGHT"; 777e77977037b89c775faa0a480c8ce70eb820dc20RoboErik private static final String KEY_DIMMED = "dimmed"; 787e77977037b89c775faa0a480c8ce70eb820dc20RoboErik private static final String KEY_SCREEN_SAVER = "screen_saver"; 79ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler 80d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik // This controls whether or not we will show a battery display when plugged 81d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik // in. 82d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik private static final boolean USE_BATTERY_DISPLAY = false; 83d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik 847dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler // Intent to broadcast for dock settings. 857dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler private static final String DOCK_SETTINGS_ACTION = "com.android.settings.DOCK_SETTINGS"; 867dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 870a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler // Delay before engaging the burn-in protection mode (green-on-black). 88f6e3c42ec2bfd7e3440393bd5a0d498a513574c5Daniel Sandler private final long SCREEN_SAVER_TIMEOUT = 5 * 60 * 1000; // 5 min 890a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 900a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler // Repositioning delay in screen saver. 91c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler public static final long SCREEN_SAVER_MOVE_DELAY = 60 * 1000; // 1 min 920a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 930a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler // Color to use for text & graphics in screen saver mode. 94322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik private int SCREEN_SAVER_COLOR = 0xFF006688; 95322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik private int SCREEN_SAVER_COLOR_DIM = 0xFF001634; 960a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 97b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler // Opacity of black layer between clock display and wallpaper. 98b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler private final float DIM_BEHIND_AMOUNT_NORMAL = 0.4f; 99f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler private final float DIM_BEHIND_AMOUNT_DIMMED = 0.8f; // higher contrast when display dimmed 100b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler 10191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private final int SCREEN_SAVER_TIMEOUT_MSG = 0x2000; 10291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private final int SCREEN_SAVER_MOVE_MSG = 0x2001; 10391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 1040a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler // State variables follow. 1052763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler private DigitalClock mTime; 106f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler private TextView mDate; 1072763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler 1082763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler private TextView mNextAlarm = null; 1093955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler private TextView mBatteryDisplay; 1102763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler 111f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler private boolean mDimmed = false; 11291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private boolean mScreenSaverMode = false; 113f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 1142ff01ef636c8896455e6780fbe14cd0dca207969Daniel Sandler private String mDateFormat; 11591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 116e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler private int mBatteryLevel = -1; 117e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler private boolean mPluggedIn = false; 1182763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler 1197dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler private boolean mLaunchedFromDock = false; 1207dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 12191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private Random mRNG; 12291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 123ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler private PendingIntent mMidnightIntent; 124ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler 125ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 126ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler @Override 127ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler public void onReceive(Context context, Intent intent) { 1283955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler final String action = intent.getAction(); 129e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler if (DEBUG) Log.d(LOG_TAG, "mIntentReceiver.onReceive: action=" + action + ", intent=" + intent); 130e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler if (Intent.ACTION_DATE_CHANGED.equals(action) || ACTION_MIDNIGHT.equals(action)) { 1313955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler refreshDate(); 1323955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 1333955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler handleBatteryUpdate( 1343b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0), 1353b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler intent.getIntExtra(BatteryManager.EXTRA_STATUS, BATTERY_STATUS_UNKNOWN), 1363b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)); 1377dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } else if (UiModeManager.ACTION_EXIT_DESK_MODE.equals(action)) { 1387dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler if (mLaunchedFromDock) { 1397dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler // moveTaskToBack(false); 1407dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler finish(); 1417dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } 1427dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler mLaunchedFromDock = false; 1437dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } else if (Intent.ACTION_DOCK_EVENT.equals(action)) { 1447dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler if (DEBUG) Log.d(LOG_TAG, "dock event extra " 1457dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler + intent.getExtras().getInt(Intent.EXTRA_DOCK_STATE)); 1467dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler if (mLaunchedFromDock && intent.getExtras().getInt(Intent.EXTRA_DOCK_STATE, 1477dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler Intent.EXTRA_DOCK_STATE_UNDOCKED) == Intent.EXTRA_DOCK_STATE_UNDOCKED) { 1487dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler finish(); 1497dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler mLaunchedFromDock = false; 1507dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } 1513955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } 152ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler } 153ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler }; 154ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 1552763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler private final Handler mHandy = new Handler() { 1562763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler @Override 1572763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler public void handleMessage(Message m) { 15891d3f291efe9d090dd7fe003955d9da2dec18a74Erik if (m.what == SCREEN_SAVER_TIMEOUT_MSG) { 15980ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler saveScreen(); 16091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } else if (m.what == SCREEN_SAVER_MOVE_MSG) { 16191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler moveScreenSaver(); 1622763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler } 1632763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler } 1642763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler }; 1650a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 1667fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov private View mAlarmButton; 1677fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov 16891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private void moveScreenSaver() { 16991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler moveScreenSaverTo(-1,-1); 17091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 17191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private void moveScreenSaverTo(int x, int y) { 17291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (!mScreenSaverMode) return; 17391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 1740c4449d6fd421c916ebaf9657ff6ae5a21eed2e7Daniel Sandler final View saver_view = findViewById(R.id.saver_view); 17591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 17691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler DisplayMetrics metrics = new DisplayMetrics(); 17791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler getWindowManager().getDefaultDisplay().getMetrics(metrics); 17891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 17991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (x < 0 || y < 0) { 1800c4449d6fd421c916ebaf9657ff6ae5a21eed2e7Daniel Sandler int myWidth = saver_view.getMeasuredWidth(); 1810c4449d6fd421c916ebaf9657ff6ae5a21eed2e7Daniel Sandler int myHeight = saver_view.getMeasuredHeight(); 18291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler x = (int)(mRNG.nextFloat()*(metrics.widthPixels - myWidth)); 18391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler y = (int)(mRNG.nextFloat()*(metrics.heightPixels - myHeight)); 18491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 18591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 1860a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler if (DEBUG) Log.d(LOG_TAG, String.format("screen saver: %d: jumping to (%d,%d)", 1870a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler System.currentTimeMillis(), x, y)); 1880a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 1890c4449d6fd421c916ebaf9657ff6ae5a21eed2e7Daniel Sandler saver_view.setLayoutParams(new AbsoluteLayout.LayoutParams( 19091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler ViewGroup.LayoutParams.WRAP_CONTENT, 19191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler ViewGroup.LayoutParams.WRAP_CONTENT, 19291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler x, 19391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler y)); 19491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 1950a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler // Synchronize our jumping so that it happens exactly on the second. 1960a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler mHandy.sendEmptyMessageDelayed(SCREEN_SAVER_MOVE_MSG, 1970a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler SCREEN_SAVER_MOVE_DELAY + 1980a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler (1000 - (System.currentTimeMillis() % 1000))); 19991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 20091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 201e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler private void setWakeLock(boolean hold) { 202e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler if (DEBUG) Log.d(LOG_TAG, (hold ? "hold" : " releas") + "ing wake lock"); 203e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler Window win = getWindow(); 204e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler WindowManager.LayoutParams winParams = win.getAttributes(); 205abc34112bd18bc0fc068ffa30ca07ae161bc9f0aMike Lockwood winParams.flags |= (WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 206abc34112bd18bc0fc068ffa30ca07ae161bc9f0aMike Lockwood | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 207abc34112bd18bc0fc068ffa30ca07ae161bc9f0aMike Lockwood | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON 208abc34112bd18bc0fc068ffa30ca07ae161bc9f0aMike Lockwood | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 209e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler if (hold) 210e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler winParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 211e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler else 212e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler winParams.flags &= (~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 213e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler win.setAttributes(winParams); 214e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler } 215e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler 21680ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler private void scheduleScreenSaver() { 2172c5f0979c70f8e16916766540ed4c96cdd127aacDmitri Plotnikov if (!getResources().getBoolean(R.bool.config_requiresScreenSaver)) { 2182c5f0979c70f8e16916766540ed4c96cdd127aacDmitri Plotnikov return; 2192c5f0979c70f8e16916766540ed4c96cdd127aacDmitri Plotnikov } 2202c5f0979c70f8e16916766540ed4c96cdd127aacDmitri Plotnikov 22180ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler // reschedule screen saver 22280ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler mHandy.removeMessages(SCREEN_SAVER_TIMEOUT_MSG); 22380ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler mHandy.sendMessageDelayed( 22480ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler Message.obtain(mHandy, SCREEN_SAVER_TIMEOUT_MSG), 22580ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler SCREEN_SAVER_TIMEOUT); 22680ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler } 22780ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler 22891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private void restoreScreen() { 22991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (!mScreenSaverMode) return; 2300a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler if (DEBUG) Log.d(LOG_TAG, "restoreScreen"); 23191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler mScreenSaverMode = false; 232c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler 23391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler initViews(); 23491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler doDim(false); // restores previous dim mode 23580ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler 23680ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler scheduleScreenSaver(); 23780ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler 23891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler refreshAll(); 23991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 24091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 24191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler // Special screen-saver mode for OLED displays that burn in quickly 24291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler private void saveScreen() { 24391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (mScreenSaverMode) return; 2440a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler if (DEBUG) Log.d(LOG_TAG, "saveScreen"); 24591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 24691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler // quickly stash away the x/y of the current date 24791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler final View oldTimeDate = findViewById(R.id.time_date); 24891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler int oldLoc[] = new int[2]; 249dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler oldLoc[0] = oldLoc[1] = -1; 250dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler if (oldTimeDate != null) { // monkeys tell us this is not always around 251dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler oldTimeDate.getLocationOnScreen(oldLoc); 252dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler } 25391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 25491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler mScreenSaverMode = true; 25591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler Window win = getWindow(); 25691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler WindowManager.LayoutParams winParams = win.getAttributes(); 25791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; 25891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler win.setAttributes(winParams); 25991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 260e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler // give up any internal focus before we switch layouts 261e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler final View focused = getCurrentFocus(); 262e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler if (focused != null) focused.clearFocus(); 263e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler 26491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler setContentView(R.layout.desk_clock_saver); 26591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 26691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler mTime = (DigitalClock) findViewById(R.id.time); 26791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler mDate = (TextView) findViewById(R.id.date); 26891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 26991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler final int color = mDimmed ? SCREEN_SAVER_COLOR_DIM : SCREEN_SAVER_COLOR; 27091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 2717fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov ((AndroidClockTextView)findViewById(R.id.timeDisplay)).setTextColor(color); 2727fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov ((AndroidClockTextView)findViewById(R.id.am_pm)).setTextColor(color); 27391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler mDate.setTextColor(color); 27491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 275c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler mTime.setSystemUiVisibility(View.STATUS_BAR_HIDDEN); 276c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler 27791d3f291efe9d090dd7fe003955d9da2dec18a74Erik mBatteryDisplay = null; 27891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 27991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler refreshDate(); 2800c4449d6fd421c916ebaf9657ff6ae5a21eed2e7Daniel Sandler refreshAlarm(); 28191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 282dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler if (oldLoc[0] >= 0) { 283dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler moveScreenSaverTo(oldLoc[0], oldLoc[1]); 284dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler } else { 285dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler moveScreenSaver(); 286dfc7092060dcf2cb5e5f38e55d5c878027b93060Daniel Sandler } 28791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 28891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 28991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler @Override 29091522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler public void onUserInteraction() { 29191522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (mScreenSaverMode) 29291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler restoreScreen(); 29391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 2942763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler 2953955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler // Adapted from KeyguardUpdateMonitor.java 2963b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler private void handleBatteryUpdate(int plugged, int status, int level) { 2973b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler final boolean pluggedIn = (plugged != 0); 298e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler if (pluggedIn != mPluggedIn) { 299e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler setWakeLock(pluggedIn); 300e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler } 3013b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler if (pluggedIn != mPluggedIn || level != mBatteryLevel) { 3023b2b8e183116d4a66acf0ed1c7db917950dc36bcDaniel Sandler mBatteryLevel = level; 3033955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler mPluggedIn = pluggedIn; 3043955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler refreshBattery(); 3053955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } 3063955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } 3073955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler 3083955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler private void refreshBattery() { 309d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik // UX wants the battery level removed. This makes it not visible but 310d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik // allows it to be easily turned back on if they change their mind. 311d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik if (!USE_BATTERY_DISPLAY) 312d5b02dee04b7011a2b6cb1086752c583dcc604e1Erik return; 31391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (mBatteryDisplay == null) return; 31491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 3153955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler if (mPluggedIn /* || mBatteryLevel < LOW_BATTERY_THRESHOLD */) { 3163955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler mBatteryDisplay.setCompoundDrawablesWithIntrinsicBounds( 3173955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler 0, 0, android.R.drawable.ic_lock_idle_charging, 0); 3183955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler mBatteryDisplay.setText( 3193955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler getString(R.string.battery_charging_level, mBatteryLevel)); 3203955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler mBatteryDisplay.setVisibility(View.VISIBLE); 3213955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } else { 3223955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler mBatteryDisplay.setVisibility(View.INVISIBLE); 3233955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } 3243955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler } 325ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 326ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler private void refreshDate() { 327ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler final Date now = new Date(); 328ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler if (DEBUG) Log.d(LOG_TAG, "refreshing date..." + now); 3292ff01ef636c8896455e6780fbe14cd0dca207969Daniel Sandler mDate.setText(DateFormat.format(mDateFormat, now)); 330ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler } 331ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 332f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler private void refreshAlarm() { 33391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (mNextAlarm == null) return; 33491522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 335f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler String nextAlarm = Settings.System.getString(getContentResolver(), 336f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler Settings.System.NEXT_ALARM_FORMATTED); 337ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler if (!TextUtils.isEmpty(nextAlarm)) { 338ee00759c00d94c50fed2eea0af7975b9d7fcbad4Dmitri Plotnikov mNextAlarm.setText(getString(R.string.control_set_alarm_with_existing, nextAlarm)); 339f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler mNextAlarm.setVisibility(View.VISIBLE); 3407fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov } else if (mAlarmButton != null) { 341f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler mNextAlarm.setVisibility(View.INVISIBLE); 3427fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov } else { 343ee00759c00d94c50fed2eea0af7975b9d7fcbad4Dmitri Plotnikov mNextAlarm.setText(R.string.control_set_alarm); 3447fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov mNextAlarm.setVisibility(View.VISIBLE); 345f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } 346f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } 347f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 3482763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler private void refreshAll() { 3492763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler refreshDate(); 3502763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler refreshAlarm(); 3512763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler refreshBattery(); 3522763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler } 3532763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler 3542763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler private void doDim(boolean fade) { 355f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler View tintView = findViewById(R.id.window_tint); 35691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler if (tintView == null) return; 357f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 358322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik mTime.setSystemUiVisibility(mDimmed ? View.SYSTEM_UI_FLAG_LOW_PROFILE 359322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik : View.SYSTEM_UI_FLAG_VISIBLE); 360c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler 361f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler Window win = getWindow(); 362f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler WindowManager.LayoutParams winParams = win.getAttributes(); 3633955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler 364e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler winParams.flags |= (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 365e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler winParams.flags |= (WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); 366e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler 3673955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler // dim the wallpaper somewhat (how much is determined below) 3683955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler winParams.flags |= (WindowManager.LayoutParams.FLAG_DIM_BEHIND); 3693955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler 370f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler if (mDimmed) { 371f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; 372b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler winParams.dimAmount = DIM_BEHIND_AMOUNT_DIMMED; 3738457946f5f77a9a6af079c44c8d0792c17d0ef27Daniel Sandler winParams.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF; 3743955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler 3753955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler // show the window tint 37691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler tintView.startAnimation(AnimationUtils.loadAnimation(this, 3772763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler fade ? R.anim.dim 3782763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler : R.anim.dim_instant)); 379f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } else { 380f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler winParams.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN); 381b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler winParams.dimAmount = DIM_BEHIND_AMOUNT_NORMAL; 3828457946f5f77a9a6af079c44c8d0792c17d0ef27Daniel Sandler winParams.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; 38391522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 3843955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler // hide the window tint 38591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler tintView.startAnimation(AnimationUtils.loadAnimation(this, 3862763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler fade ? R.anim.undim 3872763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler : R.anim.undim_instant)); 388f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } 38991522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 390f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler win.setAttributes(winParams); 391f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } 392f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 393f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler @Override 3943d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler public void onNewIntent(Intent newIntent) { 3953d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler super.onNewIntent(newIntent); 3963d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler if (DEBUG) Log.d(LOG_TAG, "onNewIntent with intent: " + newIntent); 3973d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler 3983d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler // update our intent so that we can consult it to determine whether or 3997fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov // not the most recent launch was via a dock event 4003d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler setIntent(newIntent); 4013d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler } 4023d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler 4033d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler @Override 4043f5052618fc262c22b9e00137014329bcc660524Daniel Sandler public void onStart() { 4053f5052618fc262c22b9e00137014329bcc660524Daniel Sandler super.onStart(); 406ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 407322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik SCREEN_SAVER_COLOR = getResources().getColor(R.color.screen_saver_color); 408322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik SCREEN_SAVER_COLOR_DIM = getResources().getColor(R.color.screen_saver_dim_color); 409322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik 410ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler IntentFilter filter = new IntentFilter(); 411ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler filter.addAction(Intent.ACTION_DATE_CHANGED); 4123955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler filter.addAction(Intent.ACTION_BATTERY_CHANGED); 4137dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler filter.addAction(Intent.ACTION_DOCK_EVENT); 4147dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE); 415ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler filter.addAction(ACTION_MIDNIGHT); 4163d4de660d654fee760cf96f609198489e4d6525dDaniel Sandler registerReceiver(mIntentReceiver, filter); 4173f5052618fc262c22b9e00137014329bcc660524Daniel Sandler } 4183f5052618fc262c22b9e00137014329bcc660524Daniel Sandler 4193f5052618fc262c22b9e00137014329bcc660524Daniel Sandler @Override 4203f5052618fc262c22b9e00137014329bcc660524Daniel Sandler public void onStop() { 4213f5052618fc262c22b9e00137014329bcc660524Daniel Sandler super.onStop(); 4223f5052618fc262c22b9e00137014329bcc660524Daniel Sandler 4233f5052618fc262c22b9e00137014329bcc660524Daniel Sandler unregisterReceiver(mIntentReceiver); 4243f5052618fc262c22b9e00137014329bcc660524Daniel Sandler } 4253f5052618fc262c22b9e00137014329bcc660524Daniel Sandler 4263f5052618fc262c22b9e00137014329bcc660524Daniel Sandler @Override 4273f5052618fc262c22b9e00137014329bcc660524Daniel Sandler public void onResume() { 4283f5052618fc262c22b9e00137014329bcc660524Daniel Sandler super.onResume(); 4293f5052618fc262c22b9e00137014329bcc660524Daniel Sandler if (DEBUG) Log.d(LOG_TAG, "onResume with intent: " + getIntent()); 4303f5052618fc262c22b9e00137014329bcc660524Daniel Sandler 4313f5052618fc262c22b9e00137014329bcc660524Daniel Sandler // reload the date format in case the user has changed settings 4323f5052618fc262c22b9e00137014329bcc660524Daniel Sandler // recently 4333f5052618fc262c22b9e00137014329bcc660524Daniel Sandler mDateFormat = getString(R.string.full_wday_month_day_no_year); 434ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler 435f6e3c42ec2bfd7e3440393bd5a0d498a513574c5Daniel Sandler // Elaborate mechanism to find out when the day rolls over 436ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler Calendar today = Calendar.getInstance(); 437e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler today.set(Calendar.HOUR_OF_DAY, 0); 438e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler today.set(Calendar.MINUTE, 0); 439e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler today.set(Calendar.SECOND, 0); 440ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler today.add(Calendar.DATE, 1); 4413a4bd4c68531b98db58626f60d0e9a7f5db54dc2Daniel Sandler long alarmTimeUTC = today.getTimeInMillis(); 4423a4bd4c68531b98db58626f60d0e9a7f5db54dc2Daniel Sandler 443ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler mMidnightIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_MIDNIGHT), 0); 444ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 445e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler am.setRepeating(AlarmManager.RTC, alarmTimeUTC, AlarmManager.INTERVAL_DAY, mMidnightIntent); 4463a4bd4c68531b98db58626f60d0e9a7f5db54dc2Daniel Sandler if (DEBUG) Log.d(LOG_TAG, "set repeating midnight event at UTC: " 4473a4bd4c68531b98db58626f60d0e9a7f5db54dc2Daniel Sandler + alarmTimeUTC + " (" 4483a4bd4c68531b98db58626f60d0e9a7f5db54dc2Daniel Sandler + (alarmTimeUTC - System.currentTimeMillis()) 4493a4bd4c68531b98db58626f60d0e9a7f5db54dc2Daniel Sandler + " ms from now) repeating every " 450e7c9540b179fdafb69cdc5e05a2d769f4be9463aDaniel Sandler + AlarmManager.INTERVAL_DAY + " with intent: " + mMidnightIntent); 451ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 452f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler // Adjust the display to reflect the currently chosen dim mode. 453c98ba511cbc433951f787ca9e9bd4472c18e4ab8Daniel Sandler doDim(false); 454c98ba511cbc433951f787ca9e9bd4472c18e4ab8Daniel Sandler 4557e77977037b89c775faa0a480c8ce70eb820dc20RoboErik if (!mScreenSaverMode) { 4567e77977037b89c775faa0a480c8ce70eb820dc20RoboErik restoreScreen(); // disable screen saver 4577e77977037b89c775faa0a480c8ce70eb820dc20RoboErik } else { 4587e77977037b89c775faa0a480c8ce70eb820dc20RoboErik // we have to set it to false because savescreen returns early if 4597e77977037b89c775faa0a480c8ce70eb820dc20RoboErik // it's true 4607e77977037b89c775faa0a480c8ce70eb820dc20RoboErik mScreenSaverMode = false; 4617e77977037b89c775faa0a480c8ce70eb820dc20RoboErik saveScreen(); 4627e77977037b89c775faa0a480c8ce70eb820dc20RoboErik } 4630a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler refreshAll(); // will schedule periodic weather fetch 4640a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 465e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler setWakeLock(mPluggedIn); 46691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 46780ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler scheduleScreenSaver(); 4687dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 4697dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler final boolean launchedFromDock 4707dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler = getIntent().hasCategory(Intent.CATEGORY_DESK_DOCK); 4717dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 4727dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler mLaunchedFromDock = launchedFromDock; 473ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler } 474ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 475ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler @Override 476ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler public void onPause() { 4770a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler if (DEBUG) Log.d(LOG_TAG, "onPause"); 4780a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 47980ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler // Turn off the screen saver and cancel any pending timeouts. 48080ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler // (But don't un-dim.) 48180ff42c1abf87a4e81cb422446412973b46a75bdDaniel Sandler mHandy.removeMessages(SCREEN_SAVER_TIMEOUT_MSG); 4820a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 483ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 484ba328cd4a23a13732467ba5533a94ac3d7cbbf4eDaniel Sandler am.cancel(mMidnightIntent); 4850a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler 4860a267d0f1c1e18e0f208b60a81bf2f73457a2c56Daniel Sandler super.onPause(); 487ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler } 488ef18177f9bbbeab8ef266c3f080175bc813dc34cDaniel Sandler 489d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler private void initViews() { 490e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler // give up any internal focus before we switch layouts 491e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler final View focused = getCurrentFocus(); 492e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler if (focused != null) focused.clearFocus(); 493e6cf24dbbea56d8b88a8d48bed9d3a6f26c2ddf0Daniel Sandler 494f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler setContentView(R.layout.desk_clock); 495f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 496f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler mTime = (DigitalClock) findViewById(R.id.time); 497f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler mDate = (TextView) findViewById(R.id.date); 4983955e05df4f0b1fa223ccc1cf8a44d5b5d5bd8a0Daniel Sandler mBatteryDisplay = (TextView) findViewById(R.id.battery); 499f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 500c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler mTime.setSystemUiVisibility(View.STATUS_BAR_VISIBLE); 5011878e99c5ccd7bd2288707a431e0bb5d39879985Daniel Sandler mTime.getRootView().requestFocus(); 5021878e99c5ccd7bd2288707a431e0bb5d39879985Daniel Sandler 503b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler final View.OnClickListener alarmClickListener = new View.OnClickListener() { 50491d3f291efe9d090dd7fe003955d9da2dec18a74Erik @Override 505f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler public void onClick(View v) { 506191b91f419a0ed35104b3436615364b302cfbd67Michael Chan mDimmed = false; 507191b91f419a0ed35104b3436615364b302cfbd67Michael Chan doDim(true); 508f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler startActivity(new Intent(DeskClock.this, AlarmClock.class)); 509f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } 510b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler }; 511b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler 512b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler mNextAlarm = (TextView) findViewById(R.id.nextAlarm); 513b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler mNextAlarm.setOnClickListener(alarmClickListener); 514b95b7a63c403a17c3725e1ccfbd65b4283fd6a0fDaniel Sandler 5157fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov mAlarmButton = findViewById(R.id.alarm_button); 5167fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov View alarmControl = mAlarmButton != null ? mAlarmButton : findViewById(R.id.nextAlarm); 5177fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov alarmControl.setOnClickListener(alarmClickListener); 518f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler 519ec04d6516961bac094fbb2dade7925adecac6c80Erik View touchView = findViewById(R.id.window_touch); 520ec04d6516961bac094fbb2dade7925adecac6c80Erik touchView.setOnClickListener(new View.OnClickListener() { 521ec04d6516961bac094fbb2dade7925adecac6c80Erik @Override 522ec04d6516961bac094fbb2dade7925adecac6c80Erik public void onClick(View v) { 523ec04d6516961bac094fbb2dade7925adecac6c80Erik // If the screen saver is on let onUserInteraction handle it 524ec04d6516961bac094fbb2dade7925adecac6c80Erik if (!mScreenSaverMode) { 525ec04d6516961bac094fbb2dade7925adecac6c80Erik mDimmed = !mDimmed; 5267fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov doDim(true); 5277fc983026decebf7940b9512116bdbff015fadf0Dmitri Plotnikov } 528f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler } 529f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler }); 530ec04d6516961bac094fbb2dade7925adecac6c80Erik touchView.setOnLongClickListener(new View.OnLongClickListener() { 531ec04d6516961bac094fbb2dade7925adecac6c80Erik @Override 532ec04d6516961bac094fbb2dade7925adecac6c80Erik public boolean onLongClick(View v) { 533ec04d6516961bac094fbb2dade7925adecac6c80Erik saveScreen(); 534ec04d6516961bac094fbb2dade7925adecac6c80Erik return true; 535f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler } 536f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler }); 537d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler } 538d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler 539d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler @Override 540d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler public void onConfigurationChanged(Configuration newConfig) { 541d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler super.onConfigurationChanged(newConfig); 542f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler if (mScreenSaverMode) { 543f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler moveScreenSaver(); 544f7bd3f7d1f14090b9ddf4a3d7b33ef98ad73c8aeDaniel Sandler } else { 54591522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler initViews(); 54691522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler doDim(false); 54791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler refreshAll(); 54891522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler } 549d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler } 550d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler 551d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler @Override 5527dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler public boolean onOptionsItemSelected(MenuItem item) { 5537dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler switch (item.getItemId()) { 5547dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler case R.id.menu_item_dock_settings: 5557dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler startActivity(new Intent(DOCK_SETTINGS_ACTION)); 5567dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler return true; 5577dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler default: 5587dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler return false; 5597dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } 5607dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } 5617dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 5627dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler @Override 5637dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler public boolean onCreateOptionsMenu(Menu menu) { 5647dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler MenuInflater inflater = getMenuInflater(); 5657dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler inflater.inflate(R.menu.desk_clock_menu, menu); 5667dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler return true; 5677dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } 5687dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 5697dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler @Override 5707dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler public boolean onPrepareOptionsMenu(Menu menu) { 5717dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler // Only show the "Dock settings" menu item if the device supports it. 5727dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler boolean isDockSupported = 5737dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler (getPackageManager().resolveActivity(new Intent(DOCK_SETTINGS_ACTION), 0) != null); 5747dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler menu.findItem(R.id.menu_item_dock_settings).setVisible(isDockSupported); 5757dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler return super.onPrepareOptionsMenu(menu); 5767dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler } 5777dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler 5787dd2d1f5fb1de58c8aef5bc102d21627924295cfDaniel Sandler @Override 579d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler protected void onCreate(Bundle icicle) { 580d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler super.onCreate(icicle); 5812763ab4cb6ee8d186eb8894ad006f699bfca3413Daniel Sandler 58291522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler mRNG = new Random(); 5837e77977037b89c775faa0a480c8ce70eb820dc20RoboErik if (icicle != null) { 5847e77977037b89c775faa0a480c8ce70eb820dc20RoboErik mDimmed = icicle.getBoolean(KEY_DIMMED, false); 5857e77977037b89c775faa0a480c8ce70eb820dc20RoboErik mScreenSaverMode = icicle.getBoolean(KEY_SCREEN_SAVER, false); 5867e77977037b89c775faa0a480c8ce70eb820dc20RoboErik } 58791522cd49090f40e2e5b96c9b2e310b1adf1218aDaniel Sandler 588d13733225cb1a3e16413b35336e94e400bf5d399Daniel Sandler initViews(); 589f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler } 5907e77977037b89c775faa0a480c8ce70eb820dc20RoboErik 5917e77977037b89c775faa0a480c8ce70eb820dc20RoboErik @Override 5927e77977037b89c775faa0a480c8ce70eb820dc20RoboErik protected void onSaveInstanceState(Bundle outState) { 5937e77977037b89c775faa0a480c8ce70eb820dc20RoboErik outState.putBoolean(KEY_DIMMED, mDimmed); 5947e77977037b89c775faa0a480c8ce70eb820dc20RoboErik outState.putBoolean(KEY_SCREEN_SAVER, mScreenSaverMode); 5957e77977037b89c775faa0a480c8ce70eb820dc20RoboErik } 596f8317ad7146b1cdfeded7acb23ae8f770b2d3f97Daniel Sandler} 597