1 /*
2  * Copyright (C) 2012 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.BatteryManager;
27 import android.os.Handler;
28 import android.provider.Settings;
29 import android.support.v7.app.AppCompatActivity;
30 import android.util.TypedValue;
31 import android.view.View;
32 import android.view.Window;
33 import android.view.WindowManager;
34 import android.widget.TextClock;
35 
36 import com.android.deskclock.Utils.ScreensaverMoveSaverRunnable;
37 
38 public class ScreensaverActivity extends AppCompatActivity {
39     static final boolean DEBUG = false;
40     static final String TAG = "DeskClock/ScreensaverActivity";
41 
42     private View mContentView, mSaverView;
43     private View mAnalogClock, mDigitalClock;
44 
45     private final Handler mHandler = new Handler();
46     private final ScreensaverMoveSaverRunnable mMoveSaverRunnable;
47     private String mDateFormat;
48     private String mDateFormatForAccessibility;
49     private boolean mPluggedIn = true;
50     private final int mFlags = (WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
51             | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
52             | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
53             | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
54 
55     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
56         @Override
57         public void onReceive(Context context, Intent intent) {
58             LogUtils.v(TAG, "ScreensaverActivity onReceive, action: " + intent.getAction());
59 
60             boolean changed = intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
61                     || intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
62             if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
63                 mPluggedIn = true;
64                 setWakeLock();
65             } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
66                 mPluggedIn = false;
67                 setWakeLock();
68             } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
69                 finish();
70             }
71 
72             if (changed) {
73                 Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
74                 Utils.refreshAlarm(ScreensaverActivity.this, mContentView);
75                 Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
76             }
77 
78             if (intent.getAction().equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
79                 Utils.refreshAlarm(ScreensaverActivity.this, mContentView);
80             }
81         }
82     };
83 
84     /* Register ContentObserver to see alarm changes for pre-L */
85     private final ContentObserver mSettingsContentObserver = Utils.isPreL()
86         ? new ContentObserver(mHandler) {
87             @Override
88             public void onChange(boolean selfChange) {
89                 Utils.refreshAlarm(ScreensaverActivity.this, mContentView);
90             }
91         }
92         : null;
93 
94     // Thread that runs every midnight and refreshes the date.
95     private final Runnable mMidnightUpdater = new Runnable() {
96         @Override
97         public void run() {
98             Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
99             Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
100         }
101     };
102 
ScreensaverActivity()103     public ScreensaverActivity() {
104         LogUtils.d(TAG, "Screensaver allocated");
105         mMoveSaverRunnable = new ScreensaverMoveSaverRunnable(mHandler);
106     }
107 
108     @Override
onStart()109     public void onStart() {
110         super.onStart();
111         IntentFilter filter = new IntentFilter();
112         filter.addAction(Intent.ACTION_POWER_CONNECTED);
113         filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
114         filter.addAction(Intent.ACTION_USER_PRESENT);
115         filter.addAction(Intent.ACTION_TIME_CHANGED);
116         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
117         registerReceiver(mIntentReceiver, filter);
118         if (Utils.isPreL()) {
119             getContentResolver().registerContentObserver(
120                 Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED),
121                 false,
122                 mSettingsContentObserver);
123         }
124     }
125 
126     @Override
onResume()127     public void onResume() {
128         super.onResume();
129         Intent chargingIntent =
130                 registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
131         int plugged = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
132         mPluggedIn = plugged == BatteryManager.BATTERY_PLUGGED_AC
133                 || plugged == BatteryManager.BATTERY_PLUGGED_USB
134                 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
135 
136         mDateFormat = getString(R.string.abbrev_wday_month_day_no_year);
137         mDateFormatForAccessibility = getString(R.string.full_wday_month_day_no_year);
138 
139         setWakeLock();
140         layoutClockSaver();
141         mHandler.post(mMoveSaverRunnable);
142 
143         Utils.setMidnightUpdater(mHandler, mMidnightUpdater);
144     }
145 
146     @Override
onPause()147     public void onPause() {
148         mHandler.removeCallbacks(mMoveSaverRunnable);
149         Utils.cancelMidnightUpdater(mHandler, mMidnightUpdater);
150         super.onPause();
151     }
152 
153     @Override
onStop()154     public void onStop() {
155         if (Utils.isPreL()) {
156             getContentResolver().unregisterContentObserver(mSettingsContentObserver);
157         }
158         unregisterReceiver(mIntentReceiver);
159         super.onStop();
160    }
161 
162     @Override
onConfigurationChanged(Configuration newConfig)163     public void onConfigurationChanged(Configuration newConfig) {
164         LogUtils.d(TAG, "Screensaver configuration changed");
165         super.onConfigurationChanged(newConfig);
166         mHandler.removeCallbacks(mMoveSaverRunnable);
167         layoutClockSaver();
168         mHandler.postDelayed(mMoveSaverRunnable, Screensaver.ORIENTATION_CHANGE_DELAY_MS);
169     }
170 
171     @Override
onUserInteraction()172     public void onUserInteraction() {
173         // We want the screen saver to exit upon user interaction.
174         finish();
175     }
176 
setWakeLock()177     private void setWakeLock() {
178         Window win = getWindow();
179         WindowManager.LayoutParams winParams = win.getAttributes();
180         winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
181         if (mPluggedIn)
182             winParams.flags |= mFlags;
183         else
184             winParams.flags &= (~mFlags);
185         win.setAttributes(winParams);
186     }
187 
setClockStyle()188     private void setClockStyle() {
189         Utils.setClockStyle(mDigitalClock, mAnalogClock);
190         mSaverView = findViewById(R.id.main_clock);
191         Utils.dimClockView(true, mSaverView);
192     }
193 
layoutClockSaver()194     private void layoutClockSaver() {
195         setContentView(R.layout.desk_clock_saver);
196         mDigitalClock = findViewById(R.id.digital_clock);
197         mAnalogClock = findViewById(R.id.analog_clock);
198         setClockStyle();
199         Utils.setTimeFormat(this, (TextClock) mDigitalClock);
200 
201         mContentView = (View) mSaverView.getParent();
202         mContentView.forceLayout();
203         mSaverView.forceLayout();
204         mSaverView.setAlpha(0);
205 
206         mMoveSaverRunnable.registerViews(mContentView, mSaverView);
207 
208         mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
209                 | View.SYSTEM_UI_FLAG_FULLSCREEN
210                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
211 
212         Utils.updateDate(mDateFormat, mDateFormatForAccessibility,mContentView);
213         Utils.refreshAlarm(ScreensaverActivity.this, mContentView);
214     }
215 }