Screensaver.java revision 1a7820902f3a6428f0bb586f8f1b5a2824838cb0
1c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler/*
2c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * Copyright (C) 2011 The Android Open Source Project
3c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler *
4c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License");
5c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * you may not use this file except in compliance with the License.
6c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * You may obtain a copy of the License at
7c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler *
8c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler *      http://www.apache.org/licenses/LICENSE-2.0
9c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler *
10c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * Unless required by applicable law or agreed to in writing, software
11c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS,
12c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * See the License for the specific language governing permissions and
14c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler * limitations under the License.
15c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler */
16c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
17c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerpackage com.android.deskclock;
18c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
19c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerimport android.animation.Animator;
20c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerimport android.animation.AnimatorSet;
2190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.animation.ObjectAnimator;
2290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.animation.TimeInterpolator;
23e269bd8658721a71fd9d42084b280042c5258945Daniel Sandlerimport android.content.BroadcastReceiver;
24c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerimport android.content.Context;
25e269bd8658721a71fd9d42084b280042c5258945Daniel Sandlerimport android.content.Intent;
26e269bd8658721a71fd9d42084b280042c5258945Daniel Sandlerimport android.content.IntentFilter;
2790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.content.res.Configuration;
289a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandlerimport android.graphics.drawable.Drawable;
299a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandlerimport android.graphics.PorterDuff;
3090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.os.BatteryManager;
3190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.os.Handler;
329a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandlerimport android.provider.Settings;
3390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.service.dreams.Dream;
3490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.util.Log;
359a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandlerimport android.view.MotionEvent;
36c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerimport android.view.View;
37c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerimport android.view.WindowManager;
3890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.view.animation.AccelerateInterpolator;
3990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.view.animation.DecelerateInterpolator;
409a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandlerimport android.widget.TextView;
41c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
4290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockpublic class Screensaver extends Dream {
43e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    static final boolean DEBUG = false;
44e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    static final String TAG = "DeskClock/Screensaver";
45c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
46322abb8230ff8a3ac2b58cf95863b1f8e78a99afErik    static int CLOCK_COLOR = 0xFF66AAFF;
47c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
48c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    static final long MOVE_DELAY = 60000; // DeskClock.SCREEN_SAVER_MOVE_DELAY;
49c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    static final long SLIDE_TIME = 10000;
50c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    static final long FADE_TIME = 1000;
51c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
52c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    static final boolean SLIDE = false;
53c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
54e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    private View mContentView, mSaverView;
559a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    private TextView mAlarmButton;
56e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler
5773327b39cf35c8f2f4e5ba1ac30c6fd41a99d10fErik    private static TimeInterpolator mSlowStartWithBrakes =
58c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        new TimeInterpolator() {
599a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            @Override
60c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            public float getInterpolation(float x) {
61c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                return (float)(Math.cos((Math.pow(x,3) + 1) * Math.PI) / 2.0f) + 0.5f;
62c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            }
63c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        };
64c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
65c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    private Handler mHandler = new Handler();
66c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
67e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    private boolean mPlugged = false;
68e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    private final BroadcastReceiver mPowerIntentReceiver = new BroadcastReceiver() {
69e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler        @Override
70e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler        public void onReceive(Context context, Intent intent) {
71e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler            final String action = intent.getAction();
72e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler            if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
73e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                // Only keep the screen on if we're plugged in.
74e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                boolean plugged = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
75e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                if (plugged != mPlugged) {
76e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    if (DEBUG) Log.v(TAG, plugged ? "plugged in" : "unplugged");
77e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    mPlugged = plugged;
78e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    if (mPlugged) {
79e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
80e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    } else {
81e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
82e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    }
83e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                }
84e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler            }
85e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler        }
86e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    };
87e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler
88e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    private final Runnable mMoveSaverRunnable = new Runnable() {
89c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        @Override
90c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        public void run() {
91c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            long delay = MOVE_DELAY;
92c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
9390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock            if (DEBUG) Log.d(TAG,
9490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock                    String.format("mContentView=(%d x %d) container=(%d x %d)",
9590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock                        mContentView.getWidth(), mContentView.getHeight(),
9690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock                        mSaverView.getWidth(), mSaverView.getHeight()
9790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock                        ));
980d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler            final float xrange = mContentView.getWidth() - mSaverView.getWidth();
990d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler            final float yrange = mContentView.getHeight() - mSaverView.getHeight();
100c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
1010d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler            if (xrange == 0 && yrange == 0) {
102c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                delay = 500; // back in a split second
103c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            } else {
104c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                final int nextx = (int) (Math.random() * xrange);
105c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                final int nexty = (int) (Math.random() * yrange);
106c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
1070d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                if (mSaverView.getAlpha() == 0f) {
108c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    // jump right there
1090d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    mSaverView.setX(nextx);
1100d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    mSaverView.setY(nexty);
1110d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f)
112c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        .setDuration(FADE_TIME)
113c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        .start();
114c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                } else {
115c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    AnimatorSet s = new AnimatorSet();
1160d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    Animator xMove   = ObjectAnimator.ofFloat(mSaverView,
1170d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                                         "x", mSaverView.getX(), nextx);
1180d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    Animator yMove   = ObjectAnimator.ofFloat(mSaverView,
1190d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                                         "y", mSaverView.getY(), nexty);
120c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
121e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    Animator xShrink = ObjectAnimator.ofFloat(mSaverView, "scaleX", 1f, 0.85f);
122e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    Animator xGrow   = ObjectAnimator.ofFloat(mSaverView, "scaleX", 0.85f, 1f);
123c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
124e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    Animator yShrink = ObjectAnimator.ofFloat(mSaverView, "scaleY", 1f, 0.85f);
125e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                    Animator yGrow   = ObjectAnimator.ofFloat(mSaverView, "scaleY", 0.85f, 1f);
126c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    AnimatorSet shrink = new AnimatorSet(); shrink.play(xShrink).with(yShrink);
127c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    AnimatorSet grow = new AnimatorSet(); grow.play(xGrow).with(yGrow);
128c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
1290d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    Animator fadeout = ObjectAnimator.ofFloat(mSaverView, "alpha", 1f, 0f);
1300d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler                    Animator fadein = ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f);
131c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
132c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
133c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    if (SLIDE) {
134c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(xMove).with(yMove);
135c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.setDuration(SLIDE_TIME);
136c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
137c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(shrink.setDuration(SLIDE_TIME/2));
138c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(grow.setDuration(SLIDE_TIME/2)).after(shrink);
139c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.setInterpolator(mSlowStartWithBrakes);
140c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    } else {
141c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        AccelerateInterpolator accel = new AccelerateInterpolator();
142c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        DecelerateInterpolator decel = new DecelerateInterpolator();
143c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
144c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        shrink.setDuration(FADE_TIME).setInterpolator(accel);
145c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        fadeout.setDuration(FADE_TIME).setInterpolator(accel);
146c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        grow.setDuration(FADE_TIME).setInterpolator(decel);
147c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        fadein.setDuration(FADE_TIME).setInterpolator(decel);
148c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(shrink);
149c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(fadeout);
150c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(xMove.setDuration(0)).after(FADE_TIME);
151c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(yMove.setDuration(0)).after(FADE_TIME);
152c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(fadein).after(FADE_TIME);
153c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        s.play(grow).after(FADE_TIME);
154c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    }
155c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                    s.start();
156c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                }
157c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
158c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                long now = System.currentTimeMillis();
159c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                long adjust = (now % 60000);
160c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                delay = delay
161c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        + (MOVE_DELAY - adjust) // minute aligned
162c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        - (SLIDE ? 0 : FADE_TIME) // start moving before the fade
163c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler                        ;
1649a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                if (DEBUG) Log.d(TAG,
165e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler                        "will move again in " + delay + " now=" + now + " adjusted by " + adjust);
166c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            }
167c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
168c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            mHandler.removeCallbacks(this);
169c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler            mHandler.postDelayed(this, delay);
170c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        }
171c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    };
172c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
17390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public Screensaver() {
17490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver allocated");
17590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    }
17690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
17790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    @Override
17890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onCreate() {
17990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver created");
18090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onCreate();
1819a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    }
1829a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
1839a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    @Override
1849a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    public boolean dispatchTouchEvent(MotionEvent event) {
1859a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // Hack: we want this to be *mostly* non-interactive, but still allow the user to click
1869a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // on the alarms button. The Dream class doesn't make this super easy right now, so
1879a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // we want to skip over Dream.dispatchTouchEvent() (which would finish() the saver
1889a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // immediately in non-interactive mode) and handle touches ourself.
1899a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        return getWindow().superDispatchTouchEvent(event);
19090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    }
19190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
192c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    @Override
193c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    public void onStart() {
19490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver started");
195c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        super.onStart();
196c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
1979a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // We want the screen saver to exit upon user interaction.
1989a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        setInteractive(false);
1999a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // However, we *do* actually want to trap some touch events, so
2009a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // see dispatchTouchEvent above
201c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
2029a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // XXX: should be done by Dream base class
203e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler        final IntentFilter filter = new IntentFilter();
204e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
205e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler        registerReceiver(mPowerIntentReceiver, filter);
206e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    }
207e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler
208e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    @Override
20990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onConfigurationChanged(Configuration newConfig) {
21090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver configuration changed");
21190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onConfigurationChanged(newConfig);
21290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mHandler.removeCallbacks(mMoveSaverRunnable);
21390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        layoutClockSaver();
21490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mHandler.post(mMoveSaverRunnable);
215e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    }
216e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler
217e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    @Override
21890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onAttachedToWindow() {
21990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver attached to window");
22090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onAttachedToWindow();
221c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
2221a7820902f3a6428f0bb586f8f1b5a2824838cb0Daniel Sandler        lightsOut(); // lights out, fullscreen
2231a7820902f3a6428f0bb586f8f1b5a2824838cb0Daniel Sandler
2249a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        CLOCK_COLOR = getResources().getColor(R.color.screen_saver_color);
2259a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        layoutClockSaver();
2269a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
2270d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler        mHandler.post(mMoveSaverRunnable);
228c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    }
229c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
230c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    @Override
23190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onDetachedFromWindow() {
23290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver detached from window");
23390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onDetachedFromWindow();
23490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
235c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        mHandler.removeCallbacks(mMoveSaverRunnable);
236c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    }
237c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
23873327b39cf35c8f2f4e5ba1ac30c6fd41a99d10fErik    @Override
23990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onDestroy() {
24090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver destroyed");
24190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onDestroy();
24290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
24390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        unregisterReceiver(mPowerIntentReceiver);
244c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    }
24590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
2469a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    private void refreshAlarm() {
2479a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        if (mAlarmButton == null) return;
2489a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
2499a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        String nextAlarm = Settings.System.getString(getContentResolver(),
2509a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                Settings.System.NEXT_ALARM_FORMATTED);
2519a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        mAlarmButton.setText(nextAlarm);
2529a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        mAlarmButton.setAlpha("".equals(nextAlarm) ? 0.5f : 1.0f);
2539a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    }
2549a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
25590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    private void layoutClockSaver() {
25690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        setContentView(R.layout.desk_clock_saver);
2579a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        mSaverView = findViewById(R.id.time_date);
25890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mContentView = (View) mSaverView.getParent();
25990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mSaverView.setAlpha(0);
2609a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // Here's where we get back our touch-to-dismiss functionality,
2619a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        // unless you click on the alarm button.
2629a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        mContentView.setOnTouchListener(new View.OnTouchListener() {
2639a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            @Override
2649a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            public boolean onTouch(View v, MotionEvent e) {
2659a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                finish();
2669a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                return false;
2679a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            }
2689a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        });
2699a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
2709a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        mAlarmButton = (TextView) findViewById(R.id.saverAlarm);
2719a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        refreshAlarm();
27290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
27390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        AndroidClockTextView timeDisplay = (AndroidClockTextView) findViewById(R.id.timeDisplay);
27490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (timeDisplay != null) {
27590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock            timeDisplay.setTextColor(CLOCK_COLOR);
27690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock            AndroidClockTextView amPm = (AndroidClockTextView)findViewById(R.id.am_pm);
27790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock            if (amPm != null) amPm.setTextColor(CLOCK_COLOR);
27890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        }
2799a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
2809a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        Drawable alarmClock = getResources().getDrawable(R.drawable.stat_notify_alarm);
2819a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        alarmClock.setColorFilter(CLOCK_COLOR, PorterDuff.Mode.MULTIPLY);
2829a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        TextView alarmText = (TextView) findViewById(R.id.saverAlarm);
2839a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        if (DEBUG) Log.d(TAG, "alarmText:" + alarmText);
2849a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        if (alarmText != null) {
2859a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            alarmText.setCompoundDrawablesWithIntrinsicBounds(alarmClock, null, null, null);
2869a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
2879a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            alarmText.setOnClickListener(new View.OnClickListener() {
2889a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                @Override
2899a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                public void onClick(View v) {
2909a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                    startActivity(
2919a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                        new Intent(Screensaver.this, AlarmClock.class)
2929a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
2939a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                    finish();
2949a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler                }
2959a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler            });
2969a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
2979a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        }
29890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    }
29990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
300c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler}
301