1f47699dd4704917713004099b5e3609be48653c4Patrick Scott/*
2f47699dd4704917713004099b5e3609be48653c4Patrick Scott * Copyright (C) 2009 The Android Open Source Project
3f47699dd4704917713004099b5e3609be48653c4Patrick Scott *
4f47699dd4704917713004099b5e3609be48653c4Patrick Scott * Licensed under the Apache License, Version 2.0 (the "License");
5f47699dd4704917713004099b5e3609be48653c4Patrick Scott * you may not use this file except in compliance with the License.
6f47699dd4704917713004099b5e3609be48653c4Patrick Scott * You may obtain a copy of the License at
7f47699dd4704917713004099b5e3609be48653c4Patrick Scott *
8f47699dd4704917713004099b5e3609be48653c4Patrick Scott *      http://www.apache.org/licenses/LICENSE-2.0
9f47699dd4704917713004099b5e3609be48653c4Patrick Scott *
10f47699dd4704917713004099b5e3609be48653c4Patrick Scott * Unless required by applicable law or agreed to in writing, software
11f47699dd4704917713004099b5e3609be48653c4Patrick Scott * distributed under the License is distributed on an "AS IS" BASIS,
12f47699dd4704917713004099b5e3609be48653c4Patrick Scott * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f47699dd4704917713004099b5e3609be48653c4Patrick Scott * See the License for the specific language governing permissions and
14f47699dd4704917713004099b5e3609be48653c4Patrick Scott * limitations under the License.
15f47699dd4704917713004099b5e3609be48653c4Patrick Scott */
16f47699dd4704917713004099b5e3609be48653c4Patrick Scott
17fa954248b41b567dfa2ddd7bd063d3936a51758eDaniel Sandlerpackage com.android.deskclock;
18f47699dd4704917713004099b5e3609be48653c4Patrick Scott
19aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.app.Activity;
20aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.app.Notification;
21aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.app.NotificationManager;
22aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.app.PendingIntent;
23aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.content.BroadcastReceiver;
241d5208e88385c9fc2ef7f7fa34a236832a192a5dDmitri Plotnikovimport android.content.Context;
25aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.content.Intent;
26aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.content.IntentFilter;
2735f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelsonimport android.content.pm.ActivityInfo;
28c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelsonimport android.content.res.Configuration;
2929dbeab977ead46e10efce114e1f21a55d556100Dianne Hackbornimport android.os.Bundle;
303012eefc84559507168982a7fc53dff667582b00Chiao Chengimport android.os.Handler;
313012eefc84559507168982a7fc53dff667582b00Chiao Chengimport android.os.Message;
32aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.preference.PreferenceManager;
33aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.view.KeyEvent;
34aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.view.LayoutInflater;
351d5208e88385c9fc2ef7f7fa34a236832a192a5dDmitri Plotnikovimport android.view.View;
36aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.view.Window;
3729dbeab977ead46e10efce114e1f21a55d556100Dianne Hackbornimport android.view.WindowManager;
38706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandlerimport android.widget.TextView;
39aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport android.widget.Toast;
40aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
413012eefc84559507168982a7fc53dff667582b00Chiao Chengimport com.android.deskclock.widget.multiwaveview.GlowPadView;
423012eefc84559507168982a7fc53dff667582b00Chiao Cheng
43aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scottimport java.util.Calendar;
44f47699dd4704917713004099b5e3609be48653c4Patrick Scott
45f47699dd4704917713004099b5e3609be48653c4Patrick Scott/**
46aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott * Alarm Clock alarm alert: pops visible indicator and plays alarm
47aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott * tone. This activity is the full screen version which shows over the lock
48aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott * screen with the wallpaper as the background.
49f47699dd4704917713004099b5e3609be48653c4Patrick Scott */
503012eefc84559507168982a7fc53dff667582b00Chiao Chengpublic class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTriggerListener {
51aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
52ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson    private final boolean LOG = true;
53aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    // These defaults must match the values in res/xml/settings.xml
54aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    private static final String DEFAULT_SNOOZE = "10";
55aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    protected static final String SCREEN_OFF = "screen_off";
56aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
57aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    protected Alarm mAlarm;
58aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    private int mVolumeBehavior;
59706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandler    boolean mFullscreenStyle;
603012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private GlowPadView mGlowPadView;
6135f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson    private boolean mIsDocked = false;
623012eefc84559507168982a7fc53dff667582b00Chiao Cheng
633012eefc84559507168982a7fc53dff667582b00Chiao Cheng    // Parameters for the GlowPadView "ping" animation; see triggerPing().
643012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private static final int PING_MESSAGE_WHAT = 101;
653012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private static final boolean ENABLE_PING_AUTO_REPEAT = true;
663012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private static final long PING_AUTO_REPEAT_DELAY_MSEC = 1200;
673012eefc84559507168982a7fc53dff667582b00Chiao Cheng
683012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private boolean mPingEnabled = true;
6930f1f6a8177e5742f4e8b67eb54b87d4f8bd2938Chiao Cheng
70a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram    // Receives the ALARM_KILLED action from the AlarmKlaxon,
71a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram    // and also ALARM_SNOOZE_ACTION / ALARM_DISMISS_ACTION from other applications
7263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
73aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        @Override
74aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        public void onReceive(Context context, Intent intent) {
75a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram            String action = intent.getAction();
76ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            if (LOG) {
77ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson                Log.v("AlarmAlertFullScreen - onReceive " + action);
78ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            }
79a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram            if (action.equals(Alarms.ALARM_SNOOZE_ACTION)) {
80a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram                snooze();
81a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram            } else if (action.equals(Alarms.ALARM_DISMISS_ACTION)) {
82be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas                dismiss(false, false);
83a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram            } else {
84a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram                Alarm alarm = intent.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA);
85be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas                boolean replaced = intent.getBooleanExtra(Alarms.ALARM_REPLACED, false);
86a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram                if (alarm != null && mAlarm.id == alarm.id) {
87be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas                    dismiss(true, replaced);
88a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram                }
89aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            }
90aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        }
91aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    };
92aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
933012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private final Handler mPingHandler = new Handler() {
943012eefc84559507168982a7fc53dff667582b00Chiao Cheng        @Override
953012eefc84559507168982a7fc53dff667582b00Chiao Cheng        public void handleMessage(Message msg) {
963012eefc84559507168982a7fc53dff667582b00Chiao Cheng            switch (msg.what) {
973012eefc84559507168982a7fc53dff667582b00Chiao Cheng                case PING_MESSAGE_WHAT:
983012eefc84559507168982a7fc53dff667582b00Chiao Cheng                    triggerPing();
993012eefc84559507168982a7fc53dff667582b00Chiao Cheng                    break;
1003012eefc84559507168982a7fc53dff667582b00Chiao Cheng            }
1013012eefc84559507168982a7fc53dff667582b00Chiao Cheng        }
1023012eefc84559507168982a7fc53dff667582b00Chiao Cheng    };
1033012eefc84559507168982a7fc53dff667582b00Chiao Cheng
104f47699dd4704917713004099b5e3609be48653c4Patrick Scott    @Override
10529dbeab977ead46e10efce114e1f21a55d556100Dianne Hackborn    protected void onCreate(Bundle icicle) {
10629dbeab977ead46e10efce114e1f21a55d556100Dianne Hackborn        super.onCreate(icicle);
107aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
108aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        mAlarm = getIntent().getParcelableExtra(Alarms.ALARM_INTENT_EXTRA);
109aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
110ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
111ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - onCreate");
112ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            if (mAlarm != null) {
113ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson                Log.v("AlarmAlertFullScreen - Alarm Id " + mAlarm.toString());
114ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            }
115ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
116ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson
117aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Get the volume/camera button behavior setting
118aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        final String vol =
119aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                PreferenceManager.getDefaultSharedPreferences(this)
120aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                .getString(SettingsActivity.KEY_VOLUME_BEHAVIOR,
121a3458d9448c4131b530361fb87edb28baebb647eIsaac Katzenelson                        SettingsActivity.DEFAULT_VOLUME_BEHAVIOR);
122aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        mVolumeBehavior = Integer.parseInt(vol);
123aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
124aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        final Window win = getWindow();
125aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
126aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
127aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Turn on the screen unless we are being launched from the AlarmAlert
128706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandler        // subclass as a result of the screen turning off.
129aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        if (!getIntent().getBooleanExtra(SCREEN_OFF, false)) {
130aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
131abc34112bd18bc0fc068ffa30ca07ae161bc9f0aMike Lockwood                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
132abc34112bd18bc0fc068ffa30ca07ae161bc9f0aMike Lockwood                    | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
133aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        }
134aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
135aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        updateLayout();
136aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
13735f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        // Check the docking status , if the device is docked , do not limit rotation
13835f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
13935f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        Intent dockStatus = registerReceiver(null, ifilter);
14035f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        if (dockStatus != null) {
14135f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson            mIsDocked = dockStatus.getIntExtra(Intent.EXTRA_DOCK_STATE, -1)
14235f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson                    != Intent.EXTRA_DOCK_STATE_UNDOCKED;
14335f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        }
14435f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson
145a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram        // Register to get the alarm killed/snooze/dismiss intent.
146a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram        IntentFilter filter = new IntentFilter(Alarms.ALARM_KILLED);
147a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram        filter.addAction(Alarms.ALARM_SNOOZE_ACTION);
148a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram        filter.addAction(Alarms.ALARM_DISMISS_ACTION);
149a3aba0c93c31e89045cca669418e85acfb4e22fbDavid Ingram        registerReceiver(mReceiver, filter);
150aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
151aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
152aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    private void setTitle() {
153706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandler        final String titleText = mAlarm.getLabelOrDefault(this);
154ba26bd379fa2840e699f8826465322fa6286160fJohn Spurlock
155ba26bd379fa2840e699f8826465322fa6286160fJohn Spurlock        TextView tv = (TextView) findViewById(R.id.alertTitle);
156ba26bd379fa2840e699f8826465322fa6286160fJohn Spurlock        tv.setText(titleText);
157ba26bd379fa2840e699f8826465322fa6286160fJohn Spurlock
158706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandler        setTitle(titleText);
159aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
160aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
161706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandler    protected int getLayoutResId() {
16230f1f6a8177e5742f4e8b67eb54b87d4f8bd2938Chiao Cheng        return R.layout.alarm_alert;
163706506639cb0da2c0db06ef88f2d2c9d75b084ccDaniel Sandler    }
16463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
165aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    private void updateLayout() {
166ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
167ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - updateLayout");
168ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
169ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson
170f3d6fa186ddf8a7bb8000b8b9a8700a42121e522Chiao Cheng        final LayoutInflater inflater = LayoutInflater.from(this);
171f3d6fa186ddf8a7bb8000b8b9a8700a42121e522Chiao Cheng        final View view = inflater.inflate(getLayoutResId(), null);
172f3d6fa186ddf8a7bb8000b8b9a8700a42121e522Chiao Cheng        view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
173f3d6fa186ddf8a7bb8000b8b9a8700a42121e522Chiao Cheng        setContentView(view);
174aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
1752b99424fe59984b9efabae3920fb42e77e653786Sam Blitzstein        /* Set the title from the passed in alarm */
1762b99424fe59984b9efabae3920fb42e77e653786Sam Blitzstein        setTitle();
1773012eefc84559507168982a7fc53dff667582b00Chiao Cheng
1783012eefc84559507168982a7fc53dff667582b00Chiao Cheng        mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
1793012eefc84559507168982a7fc53dff667582b00Chiao Cheng        mGlowPadView.setOnTriggerListener(this);
1803012eefc84559507168982a7fc53dff667582b00Chiao Cheng        triggerPing();
1813012eefc84559507168982a7fc53dff667582b00Chiao Cheng    }
1823012eefc84559507168982a7fc53dff667582b00Chiao Cheng
1833012eefc84559507168982a7fc53dff667582b00Chiao Cheng    private void triggerPing() {
1843012eefc84559507168982a7fc53dff667582b00Chiao Cheng        if (mPingEnabled) {
1853012eefc84559507168982a7fc53dff667582b00Chiao Cheng            mGlowPadView.ping();
1863012eefc84559507168982a7fc53dff667582b00Chiao Cheng
1873012eefc84559507168982a7fc53dff667582b00Chiao Cheng            if (ENABLE_PING_AUTO_REPEAT) {
1883012eefc84559507168982a7fc53dff667582b00Chiao Cheng                mPingHandler.sendEmptyMessageDelayed(PING_MESSAGE_WHAT, PING_AUTO_REPEAT_DELAY_MSEC);
1893012eefc84559507168982a7fc53dff667582b00Chiao Cheng            }
1903012eefc84559507168982a7fc53dff667582b00Chiao Cheng        }
191aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
192aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
193aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    // Attempt to snooze this alert.
194aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    private void snooze() {
195ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
196ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - snooze");
197ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
198ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson
199aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        final String snooze =
200aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                PreferenceManager.getDefaultSharedPreferences(this)
201aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                .getString(SettingsActivity.KEY_ALARM_SNOOZE, DEFAULT_SNOOZE);
202aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        int snoozeMinutes = Integer.parseInt(snooze);
203aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
204aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        final long snoozeTime = System.currentTimeMillis()
205aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                + (1000 * 60 * snoozeMinutes);
206aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        Alarms.saveSnoozeAlert(AlarmAlertFullScreen.this, mAlarm.id,
207aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                snoozeTime);
208aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
209aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Get the display time for the snooze and update the notification.
210aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        final Calendar c = Calendar.getInstance();
211aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        c.setTimeInMillis(snoozeTime);
2128978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        String snoozeTimeStr = Alarms.formatTime(this, c);
213aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        String label = mAlarm.getLabelOrDefault(this);
214aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
215aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Notify the user that the alarm has been snoozed.
2168978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        Intent dismissIntent = new Intent(this, AlarmReceiver.class);
2178978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        dismissIntent.setAction(Alarms.CANCEL_SNOOZE);
2188978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        dismissIntent.putExtra(Alarms.ALARM_INTENT_EXTRA, mAlarm);
2198978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein
2208978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        Intent openAlarm = new Intent(this, DeskClock.class);
2218978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        openAlarm.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2228978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        openAlarm.putExtra(Alarms.ALARM_INTENT_EXTRA, mAlarm);
2238978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        openAlarm.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.CLOCK_TAB_INDEX);
2248978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein
225aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        NotificationManager nm = getNotificationManager();
2268978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        Notification notif = new Notification.Builder(getApplicationContext())
2278978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setContentTitle(label)
2288978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setContentText(getResources().getString(R.string.alarm_alert_snooze_until, snoozeTimeStr))
2298978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setSmallIcon(R.drawable.stat_notify_alarm)
2308978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setOngoing(true)
2318978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setAutoCancel(false)
2328978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setPriority(Notification.PRIORITY_MAX)
2338978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .setWhen(0)
234c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson        .addAction(android.R.drawable.ic_menu_close_clear_cancel,
235c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson                getResources().getString(R.string.alarm_alert_dismiss_text),
2368978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein                PendingIntent.getBroadcast(this, mAlarm.id, dismissIntent, 0))
2378978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        .build();
2388978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        notif.contentIntent = PendingIntent.getActivity(this, mAlarm.id, openAlarm, 0);
2398978640131006269f4668d0abfb3d8e7bd20a9e1Sam Blitzstein        nm.notify(mAlarm.id, notif);
240aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
241aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        String displayTime = getString(R.string.alarm_alert_snooze_set,
242aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                snoozeMinutes);
243aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Intentionally log the snooze time for debugging.
244aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        Log.v(displayTime);
245aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
246aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Display the snooze minutes in a toast.
247aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        Toast.makeText(AlarmAlertFullScreen.this, displayTime,
248aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                Toast.LENGTH_LONG).show();
249aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        stopService(new Intent(Alarms.ALARM_ALERT_ACTION));
250aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        finish();
251aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
252aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
253aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    private NotificationManager getNotificationManager() {
254aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        return (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
255aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
256aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
257aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    // Dismiss the alarm.
258be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas    private void dismiss(boolean killed, boolean replaced) {
259ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
260ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - dismiss");
261ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
262ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson
263be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas        Log.i("Alarm id=" + mAlarm.id + (killed ? (replaced ? " replaced" : " killed") : " dismissed by user"));
264aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // The service told us that the alarm has been killed, do not modify
265aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // the notification or stop the service.
266aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        if (!killed) {
267aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            // Cancel the notification and stop playing the alarm
268aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            NotificationManager nm = getNotificationManager();
269aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            nm.cancel(mAlarm.id);
270aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            stopService(new Intent(Alarms.ALARM_ALERT_ACTION));
271aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        }
272be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas        if (!replaced) {
273be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas            finish();
274be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas        }
275aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
276aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
277aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    /**
278aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott     * this is called when a second alarm is triggered while a
279aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott     * previous alert window is still active.
280aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott     */
281aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    @Override
282aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    protected void onNewIntent(Intent intent) {
283aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        super.onNewIntent(intent);
284aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
285ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) Log.v("AlarmAlert.OnNewIntent()");
286aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
287aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        mAlarm = intent.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA);
288aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
289aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        setTitle();
290aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
291aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
292aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    @Override
293c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson    public void onConfigurationChanged(Configuration newConfig) {
294ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
295ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - onConfigChanged");
296ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
297c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson        updateLayout();
298c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson        super.onConfigurationChanged(newConfig);
299c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson    }
300c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson
301c4861cb16c93248e03bfe30b06d728318a990227Isaac Katzenelson    @Override
30222924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott    protected void onResume() {
30322924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott        super.onResume();
304ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
305ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - onResume");
306ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
30722924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott        // If the alarm was deleted at some point, disable snooze.
30822924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott        if (Alarms.getAlarm(getContentResolver(), mAlarm.id) == null) {
3093012eefc84559507168982a7fc53dff667582b00Chiao Cheng            mGlowPadView.setTargetResources(R.array.dismiss_drawables);
3103012eefc84559507168982a7fc53dff667582b00Chiao Cheng            mGlowPadView.setTargetDescriptionsResourceId(R.array.dismiss_descriptions);
3113012eefc84559507168982a7fc53dff667582b00Chiao Cheng            mGlowPadView.setDirectionDescriptionsResourceId(R.array.dismiss_direction_descriptions);
31222924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott        }
31335f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        // The activity is locked to the default orientation as a default set in the manifest
31435f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        // Override this settings if the device is docked or config set it differently
31535f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        if (getResources().getBoolean(R.bool.config_rotateAlarmAlert) || mIsDocked) {
31635f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
31735f68aa92e49331272104a7a5c72046b2c82496dIsaac Katzenelson        }
31822924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott    }
31922924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott
32022924b6afee333e16fb62a19f1ac044c87c528b5Patrick Scott    @Override
321aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    public void onDestroy() {
322aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        super.onDestroy();
3239e33fe399ce41766dc0a2d6e8f3e2fef0d30f6c1Robyn Coultas        if (LOG) Log.v("AlarmAlertFullScreen.onDestroy()");
324aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // No longer care about the alarm being killed.
325aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        unregisterReceiver(mReceiver);
326aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
327aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
328aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    @Override
329aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    public boolean dispatchKeyEvent(KeyEvent event) {
330aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        // Do this on key down to handle a few of the system keys.
331aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        boolean up = event.getAction() == KeyEvent.ACTION_UP;
332ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        if (LOG) {
333ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson            Log.v("AlarmAlertFullScreen - dispatchKeyEvent " + event.getKeyCode());
334ae45ac13dc2d3c9c1fa53ebda3b0e6890fe24f78Isaac Katzenelson        }
335aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        switch (event.getKeyCode()) {
336aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            // Volume keys and camera keys dismiss the alarm
337360468b9110ceba95099404265b8ee6e582391d9Chiao Cheng            case KeyEvent.KEYCODE_POWER:
338aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            case KeyEvent.KEYCODE_VOLUME_UP:
339aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            case KeyEvent.KEYCODE_VOLUME_DOWN:
340ab34252e7a7f8c39b402425a4e0941aeb039d12fJeff Brown            case KeyEvent.KEYCODE_VOLUME_MUTE:
341aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            case KeyEvent.KEYCODE_CAMERA:
342aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            case KeyEvent.KEYCODE_FOCUS:
343aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                if (up) {
344aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                    switch (mVolumeBehavior) {
345aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                        case 1:
346aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                            snooze();
347aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                            break;
348aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
349aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                        case 2:
350be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas                            dismiss(false, false);
351aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                            break;
352aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
353aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                        default:
354aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                            break;
355aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                    }
356aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                }
357aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                return true;
358aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott            default:
359aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott                break;
360aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        }
361aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott        return super.dispatchKeyEvent(event);
362aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott    }
363aa67778949c2506c7e66f37b1baeef4fc2f1ab27Patrick Scott
3648dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas    @Override
3658dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas    public void onBackPressed() {
3668dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas        // Don't allow back to dismiss. This method is overriden by AlarmAlert
3678dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas        // so that the dialog is dismissed.
3688dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas        if (LOG) {
3698dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas            Log.v("AlarmAlertFullScreen - onBackPressed");
3708dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas        }
3718dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas        return;
3728dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas    }
3738dac45cc62008a66d21107b00aa39faabdc1b6f2Robyn Coultas
3743012eefc84559507168982a7fc53dff667582b00Chiao Cheng
3753012eefc84559507168982a7fc53dff667582b00Chiao Cheng    @Override
3763012eefc84559507168982a7fc53dff667582b00Chiao Cheng    public void onGrabbed(View v, int handle) {
3773012eefc84559507168982a7fc53dff667582b00Chiao Cheng        mPingEnabled = false;
3783012eefc84559507168982a7fc53dff667582b00Chiao Cheng    }
3793012eefc84559507168982a7fc53dff667582b00Chiao Cheng
3803012eefc84559507168982a7fc53dff667582b00Chiao Cheng    @Override
3813012eefc84559507168982a7fc53dff667582b00Chiao Cheng    public void onReleased(View v, int handle) {
3823012eefc84559507168982a7fc53dff667582b00Chiao Cheng        mPingEnabled = true;
3833012eefc84559507168982a7fc53dff667582b00Chiao Cheng        triggerPing();
3843012eefc84559507168982a7fc53dff667582b00Chiao Cheng    }
3853012eefc84559507168982a7fc53dff667582b00Chiao Cheng
3863012eefc84559507168982a7fc53dff667582b00Chiao Cheng    @Override
3873012eefc84559507168982a7fc53dff667582b00Chiao Cheng    public void onTrigger(View v, int target) {
3883012eefc84559507168982a7fc53dff667582b00Chiao Cheng        final int resId = mGlowPadView.getResourceIdForTarget(target);
3893012eefc84559507168982a7fc53dff667582b00Chiao Cheng        switch (resId) {
3903012eefc84559507168982a7fc53dff667582b00Chiao Cheng            case R.drawable.ic_alarm_alert_snooze:
3913012eefc84559507168982a7fc53dff667582b00Chiao Cheng                snooze();
3923012eefc84559507168982a7fc53dff667582b00Chiao Cheng                break;
3933012eefc84559507168982a7fc53dff667582b00Chiao Cheng
3943012eefc84559507168982a7fc53dff667582b00Chiao Cheng            case R.drawable.ic_alarm_alert_dismiss:
395be452965e9b8467d2f640ccee1002119bb7d2761Robyn Coultas                dismiss(false, false);
3963012eefc84559507168982a7fc53dff667582b00Chiao Cheng                break;
3973012eefc84559507168982a7fc53dff667582b00Chiao Cheng            default:
3983012eefc84559507168982a7fc53dff667582b00Chiao Cheng                // Code should never reach here.
3993012eefc84559507168982a7fc53dff667582b00Chiao Cheng                Log.e("Trigger detected on unhandled resource. Skipping.");
4003012eefc84559507168982a7fc53dff667582b00Chiao Cheng        }
4013012eefc84559507168982a7fc53dff667582b00Chiao Cheng    }
4023012eefc84559507168982a7fc53dff667582b00Chiao Cheng
4033012eefc84559507168982a7fc53dff667582b00Chiao Cheng    @Override
4043012eefc84559507168982a7fc53dff667582b00Chiao Cheng    public void onGrabbedStateChange(View v, int handle) {
4053012eefc84559507168982a7fc53dff667582b00Chiao Cheng    }
4063012eefc84559507168982a7fc53dff667582b00Chiao Cheng
4073012eefc84559507168982a7fc53dff667582b00Chiao Cheng    @Override
4083012eefc84559507168982a7fc53dff667582b00Chiao Cheng    public void onFinishFinalAnimation() {
4093012eefc84559507168982a7fc53dff667582b00Chiao Cheng    }
410f47699dd4704917713004099b5e3609be48653c4Patrick Scott}
411