StorageNotification.java revision 4154c07c5cabc74029a2df379075391d782a682c
164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat/*
264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * Copyright (C) 2010 Google Inc.
364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat *
464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * you may not use this file except in compliance with the License.
664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * You may obtain a copy of the License at
764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat *
864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat *
1064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * Unless required by applicable law or agreed to in writing, software
1164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
1264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * See the License for the specific language governing permissions and
1464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * limitations under the License.
1564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat */
1664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
174154c07c5cabc74029a2df379075391d782a682cSan Mehatpackage com.android.server.status;
1864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
1964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.Activity;
2064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.Notification;
2164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.NotificationManager;
2264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.PendingIntent;
2364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.BroadcastReceiver;
2464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.Context;
2564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.DialogInterface;
2664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.Intent;
2764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.IntentFilter;
2864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.pm.PackageManager;
2964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.res.Resources;
3064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.os.Bundle;
3164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.os.Environment;
3264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.os.Handler;
33b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.IMountService;
3464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.os.Message;
3564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.os.ServiceManager;
36b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageEventListener;
37b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageManager;
38b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageResultCode;
3964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.util.Log;
4064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.view.View;
4164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.widget.Button;
4264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.widget.ImageView;
4364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.widget.TextView;
4464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.widget.Toast;
4564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
46b104340496e3a531e26c8f428c808eca0e039f50San Mehatpublic class StorageNotification extends StorageEventListener {
4764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private static final String TAG = "StorageNotification";
4864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
4964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
5064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Binder context for this service
5164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
5264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private Context mContext;
5364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
5464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
5564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * The notification that is shown when a USB mass storage host
5664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * is connected.
5764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * <p>
5864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * This is lazily created, so use {@link #setUsbStorageNotification()}.
5964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
6064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private Notification mUsbStorageNotification;
6164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
6264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
6364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * The notification that is shown when the following media events occur:
6464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is being checked
6564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is blank (or unknown filesystem)
6664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is corrupt
6764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is safe to unmount
6864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is missing
6964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * <p>
7064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * This is lazily created, so use {@link #setMediaStorageNotification()}.
7164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
72b104340496e3a531e26c8f428c808eca0e039f50San Mehat    private Notification   mMediaStorageNotification;
73b104340496e3a531e26c8f428c808eca0e039f50San Mehat    private boolean        mUmsAvailable;
74b104340496e3a531e26c8f428c808eca0e039f50San Mehat    private StorageManager mStorageManager;
7564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
7664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    public StorageNotification(Context context) {
7764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        mContext = context;
7864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
79b104340496e3a531e26c8f428c808eca0e039f50San Mehat        mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
80b104340496e3a531e26c8f428c808eca0e039f50San Mehat        mUmsAvailable = mStorageManager.isUsbMassStorageConnected();
81b104340496e3a531e26c8f428c808eca0e039f50San Mehat        Log.d(TAG, String.format( "Startup with UMS connection %s (media state %s)", mUmsAvailable,
82b104340496e3a531e26c8f428c808eca0e039f50San Mehat                Environment.getExternalStorageState()));
8364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
8464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
85b104340496e3a531e26c8f428c808eca0e039f50San Mehat    /*
86b104340496e3a531e26c8f428c808eca0e039f50San Mehat     * @override com.android.os.storage.StorageEventListener
87b104340496e3a531e26c8f428c808eca0e039f50San Mehat     */
88b104340496e3a531e26c8f428c808eca0e039f50San Mehat    @Override
89b104340496e3a531e26c8f428c808eca0e039f50San Mehat    public void onUsbMassStorageConnectionChanged(boolean connected) {
90b104340496e3a531e26c8f428c808eca0e039f50San Mehat        mUmsAvailable = connected;
9164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        /*
92b104340496e3a531e26c8f428c808eca0e039f50San Mehat         * Even though we may have a UMS host connected, we the SD card
93b104340496e3a531e26c8f428c808eca0e039f50San Mehat         * may not be in a state for export.
9464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat         */
95b104340496e3a531e26c8f428c808eca0e039f50San Mehat        String st = Environment.getExternalStorageState();
9664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
97b104340496e3a531e26c8f428c808eca0e039f50San Mehat        Log.i(TAG, String.format("UMS connection changed to %s (media state %s)", connected, st));
98b104340496e3a531e26c8f428c808eca0e039f50San Mehat
99b104340496e3a531e26c8f428c808eca0e039f50San Mehat        if (connected && (st.equals(
100b104340496e3a531e26c8f428c808eca0e039f50San Mehat                Environment.MEDIA_REMOVED) || st.equals(Environment.MEDIA_CHECKING))) {
101b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
102b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * No card or card being checked = don't display
103b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
104b104340496e3a531e26c8f428c808eca0e039f50San Mehat            connected = false;
10564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
106b104340496e3a531e26c8f428c808eca0e039f50San Mehat        updateUsbMassStorageNotification(connected);
10764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
10864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
109b104340496e3a531e26c8f428c808eca0e039f50San Mehat    /*
110b104340496e3a531e26c8f428c808eca0e039f50San Mehat     * @override com.android.os.storage.StorageEventListener
111b104340496e3a531e26c8f428c808eca0e039f50San Mehat     */
112b104340496e3a531e26c8f428c808eca0e039f50San Mehat    @Override
113b104340496e3a531e26c8f428c808eca0e039f50San Mehat    public void onStorageStateChanged(String path, String oldState, String newState) {
114b104340496e3a531e26c8f428c808eca0e039f50San Mehat        Log.i(TAG, String.format(
115b104340496e3a531e26c8f428c808eca0e039f50San Mehat                "Media {%s} state changed from {%s} -> {%s}", path, oldState, newState));
11664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (newState.equals(Environment.MEDIA_SHARED)) {
117b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
118b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now shared. Modify the UMS notification
119b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * for stopping UMS.
120b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
12164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
1224154c07c5cabc74029a2df379075391d782a682cSan Mehat            intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
12364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
12464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setUsbStorageNotification(
12564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_stop_notification_title,
12664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_stop_notification_message,
12764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_sys_warning, false, true, pi);
12864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_CHECKING)) {
129b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
130b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now checking. Update media notification and disable
131b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * UMS notification.
132b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
13364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(
13464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_checking_notification_title,
13564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_checking_notification_message,
13664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_prepare, true, false, null);
13764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(false);
13864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_MOUNTED)) {
139b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
140b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now mounted. Dismiss any media notifications,
141b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and enable UMS notification if connected.
142b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
14364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(0, 0, 0, false, false, null);
14464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(mUmsAvailable);
14564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_UNMOUNTED)) {
146b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
147b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now unmounted. We may have been unmounted
148b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * because the user is enabling/disabling UMS, in which case we don't
149b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * want to display the 'safe to unmount' notification.
150b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
151b104340496e3a531e26c8f428c808eca0e039f50San Mehat            if (!mStorageManager.isUsbMassStorageEnabled()) {
152b104340496e3a531e26c8f428c808eca0e039f50San Mehat                if (oldState.equals(Environment.MEDIA_SHARED)) {
153b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    /*
154b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * The unmount was due to UMS being enabled. Dismiss any
155b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * media notifications, and enable UMS notification if connected
156b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     */
157b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    setMediaStorageNotification(0, 0, 0, false, false, null);
158b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    updateUsbMassStorageNotification(mUmsAvailable);
159b104340496e3a531e26c8f428c808eca0e039f50San Mehat                } else {
160b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    /*
161b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * Show safe to unmount media notification, and enable UMS
162b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * notification if connected.
163b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     */
164b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    setMediaStorageNotification(
165b104340496e3a531e26c8f428c808eca0e039f50San Mehat                            com.android.internal.R.string.ext_media_safe_unmount_notification_title,
166b104340496e3a531e26c8f428c808eca0e039f50San Mehat                            com.android.internal.R.string.ext_media_safe_unmount_notification_message,
167b104340496e3a531e26c8f428c808eca0e039f50San Mehat                            com.android.internal.R.drawable.stat_notify_sdcard, true, true, null);
168b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    updateUsbMassStorageNotification(mUmsAvailable);
169b104340496e3a531e26c8f428c808eca0e039f50San Mehat                }
17064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            } else {
171b104340496e3a531e26c8f428c808eca0e039f50San Mehat                /*
172b104340496e3a531e26c8f428c808eca0e039f50San Mehat                 * The unmount was due to UMS being enabled. Dismiss any
173b104340496e3a531e26c8f428c808eca0e039f50San Mehat                 * media notifications, and disable the UMS notification
174b104340496e3a531e26c8f428c808eca0e039f50San Mehat                 */
17564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                setMediaStorageNotification(0, 0, 0, false, false, null);
176b104340496e3a531e26c8f428c808eca0e039f50San Mehat                updateUsbMassStorageNotification(false);
17764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
17864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_NOFS)) {
179b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
180b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage has no filesystem. Show blank media notification,
181b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and enable UMS notification if connected.
182b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
18364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
18464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
18564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
18664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
18764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(
18864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_nofs_notification_title,
18964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_nofs_notification_message,
19064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi);
19164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(mUmsAvailable);
19264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_UNMOUNTABLE)) {
193b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
194b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is corrupt. Show corrupt media notification,
195b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and enable UMS notification if connected.
196b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
19764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
19864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
19964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
20064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
20164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(
20264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_unmountable_notification_title,
20364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_unmountable_notification_message,
20464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi);
20564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(mUmsAvailable);
206b104340496e3a531e26c8f428c808eca0e039f50San Mehat        } else if (newState.equals(Environment.MEDIA_REMOVED)) {
207b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
208b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage has been removed. Show nomedia media notification,
209b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and disable UMS notification regardless of connection state.
210b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
211b104340496e3a531e26c8f428c808eca0e039f50San Mehat            setMediaStorageNotification(
212b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_nomedia_notification_title,
213b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_nomedia_notification_message,
214b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_usb,
215b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    true, false, null);
216b104340496e3a531e26c8f428c808eca0e039f50San Mehat            updateUsbMassStorageNotification(false);
217b104340496e3a531e26c8f428c808eca0e039f50San Mehat        } else if (newState.equals(Environment.MEDIA_BAD_REMOVAL)) {
218b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
219b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage has been removed unsafely. Show bad removal media notification,
220b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and disable UMS notification regardless of connection state.
221b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
222b104340496e3a531e26c8f428c808eca0e039f50San Mehat            setMediaStorageNotification(
223b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_badremoval_notification_title,
224b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_badremoval_notification_message,
225b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.drawable.stat_sys_warning,
226b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    true, true, null);
227b104340496e3a531e26c8f428c808eca0e039f50San Mehat            updateUsbMassStorageNotification(false);
228b104340496e3a531e26c8f428c808eca0e039f50San Mehat        } else {
229b104340496e3a531e26c8f428c808eca0e039f50San Mehat            Log.w(TAG, String.format("Ignoring unknown state {%s}", newState));
23064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
23164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
23264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
23364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
23464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Update the state of the USB mass storage notification
23564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
23664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    void updateUsbMassStorageNotification(boolean available) {
23764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
23864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (available) {
23964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
2404154c07c5cabc74029a2df379075391d782a682cSan Mehat            intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
24164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
24264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
24364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setUsbStorageNotification(
24464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_notification_title,
24564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_notification_message,
24664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_sys_data_usb,
24764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    false, true, pi);
24864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else {
24964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setUsbStorageNotification(0, 0, 0, false, false, null);
25064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
25164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
25264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
25364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
25464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Sets the USB storage notification.
25564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
2564154c07c5cabc74029a2df379075391d782a682cSan Mehat    private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon,
2574154c07c5cabc74029a2df379075391d782a682cSan Mehat            boolean sound, boolean visible, PendingIntent pi) {
25864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
25964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (!visible && mUsbStorageNotification == null) {
26064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
26164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
26264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
26364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        NotificationManager notificationManager = (NotificationManager) mContext
26464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                .getSystemService(Context.NOTIFICATION_SERVICE);
26564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
26664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (notificationManager == null) {
26764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
26864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
26964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
27064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
27164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Resources r = Resources.getSystem();
27264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence title = r.getText(titleId);
27364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence message = r.getText(messageId);
27464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
27564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (mUsbStorageNotification == null) {
27664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification = new Notification();
27764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.icon = icon;
27864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.when = 0;
27964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
28064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
28164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (sound) {
28264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.defaults |= Notification.DEFAULT_SOUND;
28364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            } else {
28464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
28564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
28664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
28764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mUsbStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;
28864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
28964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mUsbStorageNotification.tickerText = title;
29064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (pi == null) {
29164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                Intent intent = new Intent();
29264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
29364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
29464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
29564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi);
29664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
29764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
29864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        final int notificationId = mUsbStorageNotification.icon;
29964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
30064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.notify(notificationId, mUsbStorageNotification);
30164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else {
30264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.cancel(notificationId);
30364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
30464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
30564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
30664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private synchronized boolean getMediaStorageNotificationDismissable() {
30764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if ((mMediaStorageNotification != null) &&
30864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            ((mMediaStorageNotification.flags & Notification.FLAG_AUTO_CANCEL) ==
30964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    Notification.FLAG_AUTO_CANCEL))
31064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return true;
31164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
31264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        return false;
31364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
31464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
31564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
31664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Sets the media storage notification.
31764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
31864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private synchronized void setMediaStorageNotification(int titleId, int messageId, int icon, boolean visible,
31964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                                                          boolean dismissable, PendingIntent pi) {
32064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
32164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (!visible && mMediaStorageNotification == null) {
32264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
32364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
32464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
32564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        NotificationManager notificationManager = (NotificationManager) mContext
32664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                .getSystemService(Context.NOTIFICATION_SERVICE);
32764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
32864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (notificationManager == null) {
32964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
33064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
33164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
33264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (mMediaStorageNotification != null && visible) {
33364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            /*
33464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat             * Dismiss the previous notification - we're about to
33564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat             * re-use it.
33664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat             */
33764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            final int notificationId = mMediaStorageNotification.icon;
33864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.cancel(notificationId);
33964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
34064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
34164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
34264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Resources r = Resources.getSystem();
34364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence title = r.getText(titleId);
34464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence message = r.getText(messageId);
34564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
34664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (mMediaStorageNotification == null) {
34764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification = new Notification();
34864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification.when = 0;
34964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
35064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
35164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
35264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
35364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (dismissable) {
35464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification.flags = Notification.FLAG_AUTO_CANCEL;
35564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            } else {
35664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;
35764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
35864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
35964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.tickerText = title;
36064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (pi == null) {
36164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                Intent intent = new Intent();
36264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
36364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
36464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
36564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.icon = icon;
36664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi);
36764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
36864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
36964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        final int notificationId = mMediaStorageNotification.icon;
37064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
37164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.notify(notificationId, mMediaStorageNotification);
37264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else {
37364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.cancel(notificationId);
37464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
37564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
37664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat}
377