Screensaver.java revision 3d6adf080cb4a1469244e393807f6921b9f1149b
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.deskclock;
18
19import android.animation.Animator;
20import android.animation.AnimatorSet;
21import android.animation.ObjectAnimator;
22import android.animation.TimeInterpolator;
23import android.content.BroadcastReceiver;
24import android.content.Context;
25import android.content.Intent;
26import android.content.IntentFilter;
27import android.content.SharedPreferences;
28import android.content.res.Configuration;
29import android.graphics.drawable.Drawable;
30import android.graphics.PorterDuff;
31import android.os.BatteryManager;
32import android.os.Handler;
33import android.preference.PreferenceManager;
34import android.provider.Settings;
35import android.service.dreams.Dream;
36import android.util.Log;
37import android.view.MotionEvent;
38import android.view.View;
39import android.view.WindowManager;
40import android.view.animation.AccelerateInterpolator;
41import android.view.animation.DecelerateInterpolator;
42import android.widget.TextView;
43
44public class Screensaver extends Dream {
45    static final boolean DEBUG = false;
46    static final String TAG = "DeskClock/Screensaver";
47
48    static final long MOVE_DELAY = 60000; // DeskClock.SCREEN_SAVER_MOVE_DELAY;
49    static final long SLIDE_TIME = 10000;
50    static final long FADE_TIME = 3000;
51
52    static final boolean SLIDE = false;
53
54    private View mContentView, mSaverView;
55    private View mAnalogClock, mDigitalClock;
56
57    private static TimeInterpolator mSlowStartWithBrakes =
58        new TimeInterpolator() {
59            @Override
60            public float getInterpolation(float x) {
61                return (float)(Math.cos((Math.pow(x,3) + 1) * Math.PI) / 2.0f) + 0.5f;
62            }
63        };
64
65    private final Handler mHandler = new Handler();
66
67
68    private final Runnable mMoveSaverRunnable = new Runnable() {
69        @Override
70        public void run() {
71            long delay = MOVE_DELAY;
72
73            if (DEBUG) Log.d(TAG,
74                    String.format("mContentView=(%d x %d) container=(%d x %d)",
75                        mContentView.getWidth(), mContentView.getHeight(),
76                        mSaverView.getWidth(), mSaverView.getHeight()
77                        ));
78            final float xrange = mContentView.getWidth() - mSaverView.getWidth();
79            final float yrange = mContentView.getHeight() - mSaverView.getHeight();
80
81            if (xrange == 0 && yrange == 0) {
82                delay = 500; // back in a split second
83            } else {
84                final int nextx = (int) (Math.random() * xrange);
85                final int nexty = (int) (Math.random() * yrange);
86
87                if (mSaverView.getAlpha() == 0f) {
88                    // jump right there
89                    mSaverView.setX(nextx);
90                    mSaverView.setY(nexty);
91                    ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f)
92                        .setDuration(FADE_TIME)
93                        .start();
94                } else {
95                    AnimatorSet s = new AnimatorSet();
96                    Animator xMove   = ObjectAnimator.ofFloat(mSaverView,
97                                         "x", mSaverView.getX(), nextx);
98                    Animator yMove   = ObjectAnimator.ofFloat(mSaverView,
99                                         "y", mSaverView.getY(), nexty);
100
101                    Animator xShrink = ObjectAnimator.ofFloat(mSaverView, "scaleX", 1f, 0.85f);
102                    Animator xGrow   = ObjectAnimator.ofFloat(mSaverView, "scaleX", 0.85f, 1f);
103
104                    Animator yShrink = ObjectAnimator.ofFloat(mSaverView, "scaleY", 1f, 0.85f);
105                    Animator yGrow   = ObjectAnimator.ofFloat(mSaverView, "scaleY", 0.85f, 1f);
106                    AnimatorSet shrink = new AnimatorSet(); shrink.play(xShrink).with(yShrink);
107                    AnimatorSet grow = new AnimatorSet(); grow.play(xGrow).with(yGrow);
108
109                    Animator fadeout = ObjectAnimator.ofFloat(mSaverView, "alpha", 1f, 0f);
110                    Animator fadein = ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f);
111
112
113                    if (SLIDE) {
114                        s.play(xMove).with(yMove);
115                        s.setDuration(SLIDE_TIME);
116
117                        s.play(shrink.setDuration(SLIDE_TIME/2));
118                        s.play(grow.setDuration(SLIDE_TIME/2)).after(shrink);
119                        s.setInterpolator(mSlowStartWithBrakes);
120                    } else {
121                        AccelerateInterpolator accel = new AccelerateInterpolator();
122                        DecelerateInterpolator decel = new DecelerateInterpolator();
123
124                        shrink.setDuration(FADE_TIME).setInterpolator(accel);
125                        fadeout.setDuration(FADE_TIME).setInterpolator(accel);
126                        grow.setDuration(FADE_TIME).setInterpolator(decel);
127                        fadein.setDuration(FADE_TIME).setInterpolator(decel);
128                        s.play(shrink);
129                        s.play(fadeout);
130                        s.play(xMove.setDuration(0)).after(FADE_TIME);
131                        s.play(yMove.setDuration(0)).after(FADE_TIME);
132                        s.play(fadein).after(FADE_TIME);
133                        s.play(grow).after(FADE_TIME);
134                    }
135                    s.start();
136                }
137
138                long now = System.currentTimeMillis();
139                long adjust = (now % 60000);
140                delay = delay
141                        + (MOVE_DELAY - adjust) // minute aligned
142                        - (SLIDE ? 0 : FADE_TIME) // start moving before the fade
143                        ;
144                if (DEBUG) Log.d(TAG,
145                        "will move again in " + delay + " now=" + now + " adjusted by " + adjust);
146            }
147
148            mHandler.removeCallbacks(this);
149            mHandler.postDelayed(this, delay);
150        }
151    };
152
153    public Screensaver() {
154        if (DEBUG) Log.d(TAG, "Screensaver allocated");
155    }
156
157    @Override
158    public void onCreate() {
159        if (DEBUG) Log.d(TAG, "Screensaver created");
160        super.onCreate();
161    }
162
163
164    @Override
165    public void onStart() {
166        if (DEBUG) Log.d(TAG, "Screensaver started");
167        super.onStart();
168
169        // We want the screen saver to exit upon user interaction.
170        setInteractive(false);
171
172    }
173
174    @Override
175    public void onConfigurationChanged(Configuration newConfig) {
176        if (DEBUG) Log.d(TAG, "Screensaver configuration changed");
177        super.onConfigurationChanged(newConfig);
178        mHandler.removeCallbacks(mMoveSaverRunnable);
179        layoutClockSaver();
180        mHandler.post(mMoveSaverRunnable);
181    }
182
183    @Override
184    public void onAttachedToWindow() {
185        if (DEBUG) Log.d(TAG, "Screensaver attached to window");
186        super.onAttachedToWindow();
187
188        setFullscreen(true);
189
190        layoutClockSaver();
191
192        mHandler.post(mMoveSaverRunnable);
193    }
194
195    @Override
196    public void onDetachedFromWindow() {
197        if (DEBUG) Log.d(TAG, "Screensaver detached from window");
198        super.onDetachedFromWindow();
199
200        mHandler.removeCallbacks(mMoveSaverRunnable);
201    }
202
203    private void setClockStyle() {
204        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
205        String style = sharedPref.getString(SettingsActivity.KEY_CLOCK_STYLE, "analog");
206        if (style.equals("analog")) {
207            mDigitalClock.setVisibility(View.GONE);
208            mAnalogClock.setVisibility(View.VISIBLE);
209            mSaverView = mAnalogClock;
210        } else if (style.equals("digital")) {
211            mDigitalClock.setVisibility(View.VISIBLE);
212            mAnalogClock.setVisibility(View.GONE);
213            mSaverView = mDigitalClock;
214        }
215    }
216
217
218    private void layoutClockSaver() {
219        setContentView(R.layout.desk_clock_saver);
220        mDigitalClock = findViewById(R.id.digital_clock);
221        mAnalogClock =findViewById(R.id.analog_clock);
222        setClockStyle();
223        mContentView = (View) mSaverView.getParent();
224        mSaverView.setAlpha(0);
225    }
226
227}
228