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