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