Screensaver.java revision eb3a1f0714e209a8335d84142778465aa6b44c5c
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
19ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertimport android.content.BroadcastReceiver;
20ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertimport android.content.Context;
21ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertimport android.content.Intent;
22ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertimport android.content.IntentFilter;
2390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.content.res.Configuration;
24ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertimport android.database.ContentObserver;
2590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.os.Handler;
264560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelsonimport android.preference.PreferenceManager;
27ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertimport android.provider.Settings;
2817b4ca405a8b0d154f4d8354ab62044cd25b2204Daniel Sandlerimport android.service.dreams.DreamService;
2990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockimport android.util.Log;
30c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandlerimport android.view.View;
31c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
3278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzsteinimport com.android.deskclock.Utils.ScreensaverMoveSaverRunnable;
3378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein
3417b4ca405a8b0d154f4d8354ab62044cd25b2204Daniel Sandlerpublic class Screensaver extends DreamService {
35e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    static final boolean DEBUG = false;
36e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    static final String TAG = "DeskClock/Screensaver";
37c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
38e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    private View mContentView, mSaverView;
394560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson    private View mAnalogClock, mDigitalClock;
40c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson    private String mDateFormat;
41c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson    private String mDateFormatForAccessibility;
42e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler
439df9aff951dce59b327f56f5821386a7b40798bdIsaac Katzenelson    private final Handler mHandler = new Handler();
44c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
4578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein    private final ScreensaverMoveSaverRunnable mMoveSaverRunnable;
464560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson
47ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert    private final ContentObserver mSettingsContentObserver = new ContentObserver(mHandler) {
48ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert        @Override
49ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert        public void onChange(boolean selfChange) {
50ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert            Utils.refreshAlarm(Screensaver.this, mContentView);
51ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert        }
52ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert    };
53ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert
54eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas    // Thread that runs every midnight and refreshes the date.
55eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas    private final Runnable mMidnightUpdater = new Runnable() {
56eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        @Override
57eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        public void run() {
58eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas            Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
59eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas            Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
60eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        }
61eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas    };
62eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas
63eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas    /**
64eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas     * Receiver to handle time reference changes.
65eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas     */
66eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
67eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        @Override
68eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        public void onReceive(Context context, Intent intent) {
69eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas            final String action = intent.getAction();
70eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas            if (action != null && (action.equals(Intent.ACTION_TIME_CHANGED)
71eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas                    || action.equals(Intent.ACTION_TIMEZONE_CHANGED))) {
72eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas                Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
73eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas                Utils.refreshAlarm(Screensaver.this, mContentView);
74eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas                Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
75eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas            }
76eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        }
77eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas    };
78eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas
7990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public Screensaver() {
8090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver allocated");
8178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein        mMoveSaverRunnable = new ScreensaverMoveSaverRunnable(mHandler);
8290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    }
834560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson
8490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    @Override
8590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onCreate() {
8690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver created");
8790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onCreate();
88c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson
89c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson        mDateFormat = getString(R.string.abbrev_wday_month_day_no_year);
90c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson        mDateFormatForAccessibility = getString(R.string.full_wday_month_day_no_year);
919a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler    }
929a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
93e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    @Override
9490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onConfigurationChanged(Configuration newConfig) {
9590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver configuration changed");
9690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onConfigurationChanged(newConfig);
9790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mHandler.removeCallbacks(mMoveSaverRunnable);
9890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        layoutClockSaver();
9990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mHandler.post(mMoveSaverRunnable);
100e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    }
101e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler
102e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler    @Override
10390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onAttachedToWindow() {
10490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver attached to window");
10590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onAttachedToWindow();
106c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
10757ca681913fa5b9cd86a7342a91cfe4cc5b910dfDaniel Sandler        // We want the screen saver to exit upon user interaction.
10857ca681913fa5b9cd86a7342a91cfe4cc5b910dfDaniel Sandler        setInteractive(false);
10957ca681913fa5b9cd86a7342a91cfe4cc5b910dfDaniel Sandler
1103d6adf080cb4a1469244e393807f6921b9f1149bJohn Spurlock        setFullscreen(true);
1111a7820902f3a6428f0bb586f8f1b5a2824838cb0Daniel Sandler
1129a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler        layoutClockSaver();
1139a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
114eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        // Setup handlers for time reference changes and date updates.
115eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        IntentFilter filter = new IntentFilter();
116eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        filter.addAction(Intent.ACTION_TIME_CHANGED);
117eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
118eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        registerReceiver(mIntentReceiver, filter);
119eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
120eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas
121ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert        getContentResolver().registerContentObserver(
122ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert                Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED),
123ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert                false,
124ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert                mSettingsContentObserver);
1250d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler        mHandler.post(mMoveSaverRunnable);
126c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    }
127c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
128c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    @Override
12990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    public void onDetachedFromWindow() {
13090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        if (DEBUG) Log.d(TAG, "Screensaver detached from window");
13190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        super.onDetachedFromWindow();
13290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock
133c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler        mHandler.removeCallbacks(mMoveSaverRunnable);
134ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert        getContentResolver().unregisterContentObserver(mSettingsContentObserver);
135eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas
136eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        // Tear down handlers for time reference changes and date updates.
137eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        Utils.resetMidnightUpdater(mHandler, mMidnightUpdater);
138eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        unregisterReceiver(mIntentReceiver);
139c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler    }
140c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler
1414560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson    private void setClockStyle() {
142b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson        Utils.setClockStyle(this, mDigitalClock, mAnalogClock,
14378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein                ScreensaverSettingsActivity.KEY_CLOCK_STYLE);
144b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson        mSaverView = findViewById(R.id.main_clock);
14578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein        boolean dimNightMode = PreferenceManager.getDefaultSharedPreferences(this)
14678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein                .getBoolean(ScreensaverSettingsActivity.KEY_NIGHT_MODE, false);
14778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein        Utils.dimClockView(dimNightMode, mSaverView);
14878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein        setScreenBright(!dimNightMode);
1498f873a2bca1277f37cc8d08655d73385e5508232Daniel Sandler    }
1509a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler
15190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    private void layoutClockSaver() {
15290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        setContentView(R.layout.desk_clock_saver);
153b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson        mDigitalClock = findViewById(R.id.digital_clock);
154b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson        mAnalogClock =findViewById(R.id.analog_clock);
1554560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson        setClockStyle();
15690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mContentView = (View) mSaverView.getParent();
15790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock        mSaverView.setAlpha(0);
15878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein
15978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein        mMoveSaverRunnable.registerViews(mContentView, mSaverView);
160c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson
161eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas        Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
162c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson        Utils.refreshAlarm(Screensaver.this, mContentView);
16390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock    }
164c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler}
165