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