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