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