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.app.AlarmManager;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.content.res.Configuration;
25import android.os.Handler;
26import android.preference.PreferenceManager;
27import android.service.dreams.DreamService;
28import android.util.Log;
29import android.view.View;
30import android.widget.TextClock;
31
32import com.android.deskclock.Utils.ScreensaverMoveSaverRunnable;
33
34public class Screensaver extends DreamService {
35    static final boolean DEBUG = false;
36    static final String TAG = "DeskClock/Screensaver";
37
38    private View mContentView, mSaverView;
39    private View mAnalogClock, mDigitalClock;
40    private String mDateFormat;
41    private String mDateFormatForAccessibility;
42
43    private final Handler mHandler = new Handler();
44
45    private final ScreensaverMoveSaverRunnable mMoveSaverRunnable;
46
47    // Thread that runs every midnight and refreshes the date.
48    private final Runnable mMidnightUpdater = new Runnable() {
49        @Override
50        public void run() {
51            Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
52            Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
53        }
54    };
55
56    /**
57     * Receiver to handle time reference changes.
58     */
59    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
60        @Override
61        public void onReceive(Context context, Intent intent) {
62            final String action = intent.getAction();
63            if (DEBUG) Log.v(TAG, "Screensaver onReceive, action: " + action);
64
65            if (action == null) {
66                return;
67            }
68
69            if (action.equals(Intent.ACTION_TIME_CHANGED)
70                    || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
71                Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
72                Utils.refreshAlarm(Screensaver.this, mContentView);
73                Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
74            } else if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
75                Utils.refreshAlarm(Screensaver.this, mContentView);
76            }
77        }
78    };
79
80    public Screensaver() {
81        if (DEBUG) Log.d(TAG, "Screensaver allocated");
82        mMoveSaverRunnable = new ScreensaverMoveSaverRunnable(mHandler);
83    }
84
85    @Override
86    public void onCreate() {
87        if (DEBUG) Log.d(TAG, "Screensaver created");
88        super.onCreate();
89
90        setTheme(R.style.DeskClockParentTheme);
91
92        mDateFormat = getString(R.string.abbrev_wday_month_day_no_year);
93        mDateFormatForAccessibility = getString(R.string.full_wday_month_day_no_year);
94    }
95
96    @Override
97    public void onConfigurationChanged(Configuration newConfig) {
98        if (DEBUG) Log.d(TAG, "Screensaver configuration changed");
99        super.onConfigurationChanged(newConfig);
100        mHandler.removeCallbacks(mMoveSaverRunnable);
101        layoutClockSaver();
102        mHandler.post(mMoveSaverRunnable);
103    }
104
105    @Override
106    public void onAttachedToWindow() {
107        if (DEBUG) Log.d(TAG, "Screensaver attached to window");
108        super.onAttachedToWindow();
109
110        // We want the screen saver to exit upon user interaction.
111        setInteractive(false);
112
113        setFullscreen(true);
114
115        layoutClockSaver();
116
117        // Setup handlers for time reference changes and date updates.
118        IntentFilter filter = new IntentFilter();
119        filter.addAction(Intent.ACTION_TIME_CHANGED);
120        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
121        registerReceiver(mIntentReceiver, filter);
122        Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
123
124        mHandler.post(mMoveSaverRunnable);
125    }
126
127    @Override
128    public void onDetachedFromWindow() {
129        if (DEBUG) Log.d(TAG, "Screensaver detached from window");
130        super.onDetachedFromWindow();
131
132        mHandler.removeCallbacks(mMoveSaverRunnable);
133
134        // Tear down handlers for time reference changes and date updates.
135        Utils.cancelMidnightUpdater(mHandler, mMidnightUpdater);
136        unregisterReceiver(mIntentReceiver);
137    }
138
139    private void setClockStyle() {
140        Utils.setClockStyle(this, mDigitalClock, mAnalogClock,
141                ScreensaverSettingsActivity.KEY_CLOCK_STYLE);
142        mSaverView = findViewById(R.id.main_clock);
143        boolean dimNightMode = PreferenceManager.getDefaultSharedPreferences(this)
144                .getBoolean(ScreensaverSettingsActivity.KEY_NIGHT_MODE, false);
145        Utils.dimClockView(dimNightMode, mSaverView);
146        setScreenBright(!dimNightMode);
147    }
148
149    private void layoutClockSaver() {
150        setContentView(R.layout.desk_clock_saver);
151        mDigitalClock = findViewById(R.id.digital_clock);
152        mAnalogClock =findViewById(R.id.analog_clock);
153        setClockStyle();
154        Utils.setTimeFormat((TextClock)mDigitalClock,
155            (int)getResources().getDimension(R.dimen.main_ampm_font_size));
156
157        mContentView = (View) mSaverView.getParent();
158        mSaverView.setAlpha(0);
159
160        mMoveSaverRunnable.registerViews(mContentView, mSaverView);
161
162        Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
163        Utils.refreshAlarm(Screensaver.this, mContentView);
164    }
165}
166