Screensaver.java revision c57490dff5bfbf601d4b708fdae029df99f807b2
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.view.animation.AccelerateInterpolator;
20import android.view.animation.DecelerateInterpolator;
21import android.animation.TimeInterpolator;
22import android.animation.ObjectAnimator;
23import android.animation.Animator;
24import android.animation.AnimatorSet;
25import android.app.Activity;
26import android.os.Handler;
27import android.content.Context;
28import android.util.AttributeSet;
29import android.view.View;
30import android.view.ViewGroup;
31import android.view.WindowManager;
32import android.widget.FrameLayout;
33import android.widget.TextView;
34import java.lang.Runnable;
35import android.util.Log;
36
37public class Screensaver extends Activity {
38    View mContainer;
39
40    static final int CLOCK_COLOR = 0xFF66AAFF;
41
42    static final long MOVE_DELAY = 60000; // DeskClock.SCREEN_SAVER_MOVE_DELAY;
43    static final long SLIDE_TIME = 10000;
44    static final long FADE_TIME = 1000;
45
46    static final boolean SLIDE = false;
47
48    private static TimeInterpolator mSlowStartWithBrakes =
49        new TimeInterpolator() {
50            public float getInterpolation(float x) {
51                return (float)(Math.cos((Math.pow(x,3) + 1) * Math.PI) / 2.0f) + 0.5f;
52            }
53        };
54
55    private Handler mHandler = new Handler();
56
57    private Runnable mMoveSaverRunnable = new Runnable() {
58        @Override
59        public void run() {
60            long delay = MOVE_DELAY;
61
62            View parent = (View)mContainer.getParent();
63            //Log.d("DeskClock/Screensaver", String.format("parent=(%d x %d)",
64//                        parent.getWidth(), parent.getHeight()));
65            final float xrange = parent.getWidth() - mContainer.getWidth();
66            final float yrange = parent.getHeight() - mContainer.getHeight();
67
68            if (xrange == 0) {
69                delay = 500; // back in a split second
70            } else {
71                final int nextx = (int) (Math.random() * xrange);
72                final int nexty = (int) (Math.random() * yrange);
73
74                if (mContainer.getAlpha() == 0f) {
75                    // jump right there
76                    mContainer.setX(nextx);
77                    mContainer.setY(nexty);
78                    ObjectAnimator.ofFloat(mContainer, "alpha", 0f, 1f)
79                        .setDuration(FADE_TIME)
80                        .start();
81                } else {
82                    AnimatorSet s = new AnimatorSet();
83                    Animator xMove   = ObjectAnimator.ofFloat(mContainer,
84                                         "x", mContainer.getX(), nextx);
85                    Animator yMove   = ObjectAnimator.ofFloat(mContainer,
86                                         "y", mContainer.getY(), nexty);
87
88                    Animator xShrink = ObjectAnimator.ofFloat(mContainer, "scaleX", 1f, 0.75f);
89                    Animator xGrow   = ObjectAnimator.ofFloat(mContainer, "scaleX", 0.75f, 1f);
90
91                    Animator yShrink = ObjectAnimator.ofFloat(mContainer, "scaleY", 1f, 0.75f);
92                    Animator yGrow   = ObjectAnimator.ofFloat(mContainer, "scaleY", 0.75f, 1f);
93                    AnimatorSet shrink = new AnimatorSet(); shrink.play(xShrink).with(yShrink);
94                    AnimatorSet grow = new AnimatorSet(); grow.play(xGrow).with(yGrow);
95
96                    Animator fadeout = ObjectAnimator.ofFloat(mContainer, "alpha", 1f, 0f);
97                    Animator fadein = ObjectAnimator.ofFloat(mContainer, "alpha", 0f, 1f);
98
99
100                    if (SLIDE) {
101                        s.play(xMove).with(yMove);
102                        s.setDuration(SLIDE_TIME);
103
104                        s.play(shrink.setDuration(SLIDE_TIME/2));
105                        s.play(grow.setDuration(SLIDE_TIME/2)).after(shrink);
106                        s.setInterpolator(mSlowStartWithBrakes);
107                    } else {
108                        AccelerateInterpolator accel = new AccelerateInterpolator();
109                        DecelerateInterpolator decel = new DecelerateInterpolator();
110
111                        shrink.setDuration(FADE_TIME).setInterpolator(accel);
112                        fadeout.setDuration(FADE_TIME).setInterpolator(accel);
113                        grow.setDuration(FADE_TIME).setInterpolator(decel);
114                        fadein.setDuration(FADE_TIME).setInterpolator(decel);
115                        s.play(shrink);
116                        s.play(fadeout);
117                        s.play(xMove.setDuration(0)).after(FADE_TIME);
118                        s.play(yMove.setDuration(0)).after(FADE_TIME);
119                        s.play(fadein).after(FADE_TIME);
120                        s.play(grow).after(FADE_TIME);
121                    }
122                    s.start();
123                }
124
125                long now = System.currentTimeMillis();
126                long adjust = (now % 60000);
127                delay = delay
128                        + (MOVE_DELAY - adjust) // minute aligned
129                        - (SLIDE ? 0 : FADE_TIME) // start moving before the fade
130                        ;
131                //Log.d("DeskClock/Screensaver", "will move again in " + delay + " now=" + now + " adjusted by " + adjust);
132            }
133
134            mHandler.removeCallbacks(this);
135            mHandler.postDelayed(this, delay);
136        }
137    };
138
139    @Override
140    public void onStart() {
141        super.onStart();
142        setContentView(R.layout.desk_clock_saver);
143        mContainer = findViewById(R.id.saver_view);
144        mContainer.setAlpha(0);
145        mContainer.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
146        mContainer.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
147
148        AndroidClockTextView timeDisplay = (AndroidClockTextView) findViewById(R.id.timeDisplay);
149        if (timeDisplay != null) {
150            timeDisplay.setTextColor(CLOCK_COLOR);
151            AndroidClockTextView amPm = (AndroidClockTextView)findViewById(R.id.am_pm);
152            if (amPm != null) amPm.setTextColor(CLOCK_COLOR);
153        }
154
155        getWindow().addFlags(
156                  WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
157                | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
158                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
159                );
160    }
161
162    @Override
163    public void onResume() {
164        super.onResume();
165
166        mMoveSaverRunnable.run();
167    }
168
169    @Override
170    public void onPause() {
171        super.onPause();
172
173        mHandler.removeCallbacks(mMoveSaverRunnable);
174    }
175
176    public void onUserInteraction() {
177        finish();
178    }
179}
180