Screensaver.java revision 0d4404c04475a66c9bcbda6960bd94597985b785
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 mContentView, mSaverView;
39
40    static 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//            Log.d("DeskClock/Screensaver",
63//                    String.format("mContentView=(%d x %d) container=(%d x %d)",
64//                        mContentView.getWidth(), mContentView.getHeight(),
65//                        mSaverView.getWidth(), mSaverView.getHeight()
66//                        ));
67            final float xrange = mContentView.getWidth() - mSaverView.getWidth();
68            final float yrange = mContentView.getHeight() - mSaverView.getHeight();
69
70            if (xrange == 0 && yrange == 0) {
71                delay = 500; // back in a split second
72            } else {
73                final int nextx = (int) (Math.random() * xrange);
74                final int nexty = (int) (Math.random() * yrange);
75
76                if (mSaverView.getAlpha() == 0f) {
77                    // jump right there
78                    mSaverView.setX(nextx);
79                    mSaverView.setY(nexty);
80                    ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f)
81                        .setDuration(FADE_TIME)
82                        .start();
83                } else {
84                    AnimatorSet s = new AnimatorSet();
85                    Animator xMove   = ObjectAnimator.ofFloat(mSaverView,
86                                         "x", mSaverView.getX(), nextx);
87                    Animator yMove   = ObjectAnimator.ofFloat(mSaverView,
88                                         "y", mSaverView.getY(), nexty);
89
90                    Animator xShrink = ObjectAnimator.ofFloat(mSaverView, "scaleX", 1f, 0.75f);
91                    Animator xGrow   = ObjectAnimator.ofFloat(mSaverView, "scaleX", 0.75f, 1f);
92
93                    Animator yShrink = ObjectAnimator.ofFloat(mSaverView, "scaleY", 1f, 0.75f);
94                    Animator yGrow   = ObjectAnimator.ofFloat(mSaverView, "scaleY", 0.75f, 1f);
95                    AnimatorSet shrink = new AnimatorSet(); shrink.play(xShrink).with(yShrink);
96                    AnimatorSet grow = new AnimatorSet(); grow.play(xGrow).with(yGrow);
97
98                    Animator fadeout = ObjectAnimator.ofFloat(mSaverView, "alpha", 1f, 0f);
99                    Animator fadein = ObjectAnimator.ofFloat(mSaverView, "alpha", 0f, 1f);
100
101
102                    if (SLIDE) {
103                        s.play(xMove).with(yMove);
104                        s.setDuration(SLIDE_TIME);
105
106                        s.play(shrink.setDuration(SLIDE_TIME/2));
107                        s.play(grow.setDuration(SLIDE_TIME/2)).after(shrink);
108                        s.setInterpolator(mSlowStartWithBrakes);
109                    } else {
110                        AccelerateInterpolator accel = new AccelerateInterpolator();
111                        DecelerateInterpolator decel = new DecelerateInterpolator();
112
113                        shrink.setDuration(FADE_TIME).setInterpolator(accel);
114                        fadeout.setDuration(FADE_TIME).setInterpolator(accel);
115                        grow.setDuration(FADE_TIME).setInterpolator(decel);
116                        fadein.setDuration(FADE_TIME).setInterpolator(decel);
117                        s.play(shrink);
118                        s.play(fadeout);
119                        s.play(xMove.setDuration(0)).after(FADE_TIME);
120                        s.play(yMove.setDuration(0)).after(FADE_TIME);
121                        s.play(fadein).after(FADE_TIME);
122                        s.play(grow).after(FADE_TIME);
123                    }
124                    s.start();
125                }
126
127                long now = System.currentTimeMillis();
128                long adjust = (now % 60000);
129                delay = delay
130                        + (MOVE_DELAY - adjust) // minute aligned
131                        - (SLIDE ? 0 : FADE_TIME) // start moving before the fade
132                        ;
133//                Log.d("DeskClock/Screensaver", "will move again in " + delay + " now=" + now + " adjusted by " + adjust);
134            }
135
136            mHandler.removeCallbacks(this);
137            mHandler.postDelayed(this, delay);
138        }
139    };
140
141    @Override
142    public void onStart() {
143        super.onStart();
144        CLOCK_COLOR = getResources().getColor(R.color.screen_saver_color);
145        setContentView(R.layout.desk_clock_saver);
146        mSaverView = findViewById(R.id.saver_view);
147        mContentView = (View) mSaverView.getParent();
148        mSaverView.setAlpha(0);
149        mSaverView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
150
151        AndroidClockTextView timeDisplay = (AndroidClockTextView) findViewById(R.id.timeDisplay);
152        if (timeDisplay != null) {
153            timeDisplay.setTextColor(CLOCK_COLOR);
154            AndroidClockTextView amPm = (AndroidClockTextView)findViewById(R.id.am_pm);
155            if (amPm != null) amPm.setTextColor(CLOCK_COLOR);
156        }
157
158        getWindow().addFlags(
159                  WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
160                | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
161                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
162                );
163    }
164
165    @Override
166    public void onResume() {
167        super.onResume();
168//        Log.d("DeskClock/Screensaver", "resume");
169        mHandler.post(mMoveSaverRunnable);
170    }
171
172    @Override
173    public void onPause() {
174        super.onPause();
175
176        mHandler.removeCallbacks(mMoveSaverRunnable);
177    }
178
179    @Override
180    public void onUserInteraction() {
181        finish();
182    }
183}
184