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
17package com.android.deskclock;
18
19import android.app.Activity;
20import android.app.AlarmManager;
21import android.app.PendingIntent;
22import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
26import android.content.res.Configuration;
27import android.os.BatteryManager;
28import android.os.Handler;
29import android.util.Log;
30import android.view.View;
31import android.view.Window;
32import android.view.WindowManager;
33
34import com.android.deskclock.Utils.ScreensaverMoveSaverRunnable;
35
36public class ScreensaverActivity extends Activity {
37    static final boolean DEBUG = false;
38    static final String TAG = "DeskClock/ScreensaverActivity";
39
40    // This value must match android:defaultValue of
41    // android:key="screensaver_clock_style" in dream_settings.xml
42    static final String DEFAULT_CLOCK_STYLE = "digital";
43
44    private View mContentView, mSaverView;
45    private View mAnalogClock, mDigitalClock;
46
47    private final Handler mHandler = new Handler();
48    private final ScreensaverMoveSaverRunnable mMoveSaverRunnable;
49    private String mDateFormat;
50    private String mDateFormatForAccessibility;
51    private PendingIntent mQuarterlyIntent;
52    private String mClockStyle;
53    private boolean mPluggedIn = true;
54    private final int mFlags = (WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
55            | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
56            | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
57            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
58
59    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
60        @Override
61        public void onReceive(Context context, Intent intent) {
62            boolean changed = intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
63                    || intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
64            if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
65                mPluggedIn = true;
66                setWakeLock();
67            } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
68                mPluggedIn = false;
69                setWakeLock();
70            } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
71                finish();
72            } else if (intent.getAction().equals(Utils.ACTION_ON_QUARTER_HOUR) || changed) {
73                Utils.updateDate(mDateFormat, mDateFormatForAccessibility, mContentView);
74            }
75
76            if (changed) {
77                Utils.refreshAlarm(ScreensaverActivity.this, mContentView);
78                mQuarterlyIntent = Utils.refreshAlarmOnQuarterHour(
79                        ScreensaverActivity.this, mQuarterlyIntent);
80            }
81
82        }
83    };
84
85    public ScreensaverActivity() {
86        if (DEBUG) Log.d(TAG, "Screensaver allocated");
87        mMoveSaverRunnable = new ScreensaverMoveSaverRunnable(mHandler);
88    }
89
90    @Override
91    public void onStart() {
92        super.onStart();
93        IntentFilter filter = new IntentFilter();
94        filter.addAction(Intent.ACTION_POWER_CONNECTED);
95        filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
96        filter.addAction(Intent.ACTION_USER_PRESENT);
97        filter.addAction(Utils.ACTION_ON_QUARTER_HOUR);
98        filter.addAction(Intent.ACTION_TIME_CHANGED);
99        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
100        registerReceiver(mIntentReceiver, filter);
101    }
102
103    @Override
104    public void onResume() {
105        super.onResume();
106        Intent chargingIntent =
107                registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
108        int plugged = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
109        mPluggedIn = plugged == BatteryManager.BATTERY_PLUGGED_AC
110                || plugged == BatteryManager.BATTERY_PLUGGED_USB
111                || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
112
113        mDateFormat = getString(R.string.abbrev_wday_month_day_no_year);
114        mDateFormatForAccessibility = getString(R.string.full_wday_month_day_no_year);
115
116        setWakeLock();
117        layoutClockSaver();
118        mHandler.post(mMoveSaverRunnable);
119
120        mQuarterlyIntent = Utils.startAlarmOnQuarterHour(this);
121    }
122
123    @Override
124    public void onPause() {
125        mHandler.removeCallbacks(mMoveSaverRunnable);
126        Utils.cancelAlarmOnQuarterHour(this, mQuarterlyIntent);
127        finish();
128        super.onPause();
129    }
130
131    @Override
132    public void onStop() {
133        unregisterReceiver(mIntentReceiver);
134        super.onStop();
135   }
136
137    @Override
138    public void onConfigurationChanged(Configuration newConfig) {
139        if (DEBUG) Log.d(TAG, "Screensaver configuration changed");
140        super.onConfigurationChanged(newConfig);
141        mHandler.removeCallbacks(mMoveSaverRunnable);
142        layoutClockSaver();
143        mHandler.postDelayed(mMoveSaverRunnable, 250);
144    }
145
146    @Override
147    public void onUserInteraction() {
148        // We want the screen saver to exit upon user interaction.
149        finish();
150    }
151
152    private void setWakeLock() {
153        Window win = getWindow();
154        WindowManager.LayoutParams winParams = win.getAttributes();
155        winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
156        if (mPluggedIn)
157            winParams.flags |= mFlags;
158        else
159            winParams.flags &= (~mFlags);
160        win.setAttributes(winParams);
161    }
162
163    private void setClockStyle() {
164        Utils.setClockStyle(this, mDigitalClock, mAnalogClock,
165                SettingsActivity.KEY_CLOCK_STYLE);
166        mSaverView = findViewById(R.id.main_clock);
167        mClockStyle = (mSaverView == mDigitalClock ?
168                Utils.CLOCK_TYPE_DIGITAL : Utils.CLOCK_TYPE_ANALOG);
169        Utils.dimClockView(true, mSaverView);
170    }
171
172    private void layoutClockSaver() {
173        setContentView(R.layout.desk_clock_saver);
174        mDigitalClock = findViewById(R.id.digital_clock);
175        mAnalogClock = findViewById(R.id.analog_clock);
176        setClockStyle();
177        mContentView = (View) mSaverView.getParent();
178        mContentView.forceLayout();
179        mSaverView.forceLayout();
180        mSaverView.setAlpha(0);
181
182        mMoveSaverRunnable.registerViews(mContentView, mSaverView);
183
184        mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
185                | View.SYSTEM_UI_FLAG_FULLSCREEN
186                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
187
188        Utils.updateDate(mDateFormat, mDateFormatForAccessibility,mContentView);
189        Utils.refreshAlarm(ScreensaverActivity.this, mContentView);
190    }
191
192}
193