Home | History | Annotate | Download | only in deskclock
      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 
     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.BatteryManager;
     27 import android.os.Build;
     28 import android.os.Handler;
     29 import android.provider.Settings;
     30 import android.support.v7.app.AppCompatActivity;
     31 import android.view.View;
     32 import android.view.Window;
     33 import android.view.WindowManager;
     34 import android.widget.TextClock;
     35 
     36 import com.android.deskclock.Utils.ScreensaverMoveSaverRunnable;
     37 
     38 public 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