CellBroadcastAlertFullScreen.java revision 00b87064abfb9d254fbbf72110643d2e626365e6
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
17package com.android.cellbroadcastreceiver;
18
19import android.app.Activity;
20import android.app.NotificationManager;
21import android.content.Context;
22import android.content.Intent;
23import android.graphics.drawable.Drawable;
24import android.os.Bundle;
25import android.os.Handler;
26import android.os.Message;
27import android.view.LayoutInflater;
28import android.view.View;
29import android.view.Window;
30import android.view.WindowManager;
31import android.widget.Button;
32import android.widget.ImageView;
33import android.widget.TextView;
34
35/**
36 * Full-screen emergency alert with flashing warning icon.
37 * Alert audio and text-to-speech handled by {@link CellBroadcastAlertAudio}.
38 * Keyguard handling based on {@code AlarmAlertFullScreen} class from DeskClock app.
39 */
40public class CellBroadcastAlertFullScreen extends Activity {
41
42    /**
43     * Intent extra for full screen alert launched from dialog subclass as a result of the
44     * screen turning off.
45     */
46    static final String SCREEN_OFF = "screen_off";
47
48    /** Whether to show the flashing warning icon. */
49    private boolean mIsEmergencyAlert;
50
51    /** The cell broadcast message to display. */
52    CellBroadcastMessage mMessage;
53
54    /** Length of time for the warning icon to be visible. */
55    private static final int WARNING_ICON_ON_DURATION_MSEC = 800;
56
57    /** Length of time for the warning icon to be off. */
58    private static final int WARNING_ICON_OFF_DURATION_MSEC = 800;
59
60    /** Warning icon state. false = visible, true = off */
61    private boolean mIconAnimationState;
62
63    /** Stop animating icon after {@link #onStop()} is called. */
64    private boolean mStopAnimation;
65
66    /** The warning icon Drawable. */
67    private Drawable mWarningIcon;
68
69    /** The View containing the warning icon. */
70    private ImageView mWarningIconView;
71
72    /** Icon animation handler for flashing warning alerts. */
73    private final Handler mAnimationHandler = new Handler() {
74        @Override
75        public void handleMessage(Message msg) {
76            if (mIconAnimationState) {
77                mWarningIconView.setAlpha(255);
78                if (!mStopAnimation) {
79                    mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_ON_DURATION_MSEC);
80                }
81            } else {
82                mWarningIconView.setAlpha(0);
83                if (!mStopAnimation) {
84                    mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_OFF_DURATION_MSEC);
85                }
86            }
87            mIconAnimationState = !mIconAnimationState;
88            mWarningIconView.invalidateDrawable(mWarningIcon);
89        }
90    };
91
92    @Override
93    protected void onCreate(Bundle savedInstanceState) {
94        super.onCreate(savedInstanceState);
95
96        final Window win = getWindow();
97
98        // We use a custom title, so remove the standard dialog title bar
99        win.requestFeature(Window.FEATURE_NO_TITLE);
100
101        // Full screen alerts display above the keyguard and when device is locked.
102        win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
103                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
104                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
105
106        // Turn on the screen unless we're being launched from the dialog subclass as a result of
107        // the screen turning off.
108        if (!getIntent().getBooleanExtra(SCREEN_OFF, false)) {
109            win.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
110                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
111        }
112
113        // Save message for passing from dialog to fullscreen activity, and for marking read.
114        mMessage = getIntent().getParcelableExtra(
115                CellBroadcastMessage.SMS_CB_MESSAGE_EXTRA);
116
117        updateLayout(mMessage);
118    }
119
120    protected int getLayoutResId() {
121        return R.layout.cell_broadcast_alert_fullscreen;
122    }
123
124    private void updateLayout(CellBroadcastMessage message) {
125        LayoutInflater inflater = LayoutInflater.from(this);
126
127        setContentView(inflater.inflate(getLayoutResId(), null));
128
129        /* Initialize dialog text from alert message. */
130        int titleId = message.getDialogTitleResource();
131        setTitle(titleId);
132        ((TextView) findViewById(R.id.alertTitle)).setText(titleId);
133        ((TextView) findViewById(R.id.message)).setText(message.getFormattedMessageBody(this));
134
135        /* dismiss button: close notification */
136        findViewById(R.id.dismissButton).setOnClickListener(
137                new Button.OnClickListener() {
138                    public void onClick(View v) {
139                        dismiss();
140                    }
141                });
142
143        mIsEmergencyAlert = message.isPublicAlertMessage() || CellBroadcastConfigService
144                .isOperatorDefinedEmergencyId(message.getServiceCategory());
145
146        if (mIsEmergencyAlert) {
147            mWarningIcon = getResources().getDrawable(R.drawable.ic_warning_large);
148            mWarningIconView = (ImageView) findViewById(R.id.icon);
149            if (mWarningIconView != null) {
150                mWarningIconView.setImageDrawable(mWarningIcon);
151            }
152
153            // Dismiss the notification that brought us here
154            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
155                    .cancel((int) message.getDeliveryTime());
156        }
157    }
158
159    /**
160     * Start animating warning icon.
161     */
162    @Override
163    protected void onStart() {
164        super.onStart();
165        if (mIsEmergencyAlert) {
166            // start icon animation
167            mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_ON_DURATION_MSEC);
168        }
169    }
170
171    /**
172     * Stop animating warning icon and stop the {@link CellBroadcastAlertAudio}
173     * service if necessary.
174     */
175    void dismiss() {
176        // Stop playing alert sound/vibration/speech (if started)
177        stopService(new Intent(this, CellBroadcastAlertAudio.class));
178
179        // Start database service to mark broadcast as read
180        Intent intent = new Intent(this, CellBroadcastDatabaseService.class);
181        intent.setAction(CellBroadcastDatabaseService.ACTION_MARK_BROADCAST_READ);
182        // Select by delivery time because we don't know the database row ID.
183        intent.putExtra(CellBroadcastDatabaseService.DATABASE_DELIVERY_TIME_EXTRA,
184                mMessage.getDeliveryTime());
185        startService(intent);
186
187        if (mIsEmergencyAlert) {
188            // stop animating emergency alert icon
189            mStopAnimation = true;
190        } else {
191            // decrement unread non-emergency alert count
192            CellBroadcastReceiverApp.decrementUnreadAlertCount();
193        }
194        finish();
195    }
196
197    /**
198     * Ignore the back button for emergency alerts (overridden by alert dialog so that the dialog
199     * is dismissed).
200     */
201    @Override
202    public void onBackPressed() {
203        // ignored
204    }
205}
206