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