Home | History | Annotate | Download | only in deskclock
      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 
     96     public Screensaver() {
     97         if (DEBUG) Log.d(TAG, "Screensaver allocated");
     98         mMoveSaverRunnable = new ScreensaverMoveSaverRunnable(mHandler);
     99     }
    100 
    101     @Override
    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
    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
    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
    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 
    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 
    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