StorageNotification.java revision d39d515b9110d7405d0f03dbf612ba5c9b8ac566
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
17fe4f3ae33c8da86585399b4167fd7987c8a16066Joe Onoratopackage com.android.systemui.usb;
1864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
1964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.Notification;
2064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.NotificationManager;
2164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.PendingIntent;
2264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.Context;
2364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.Intent;
2464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.res.Resources;
2564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.os.Environment;
26b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageEventListener;
27b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageManager;
28c07907e0389f20f83fdfe01319023b8c7d5e4bbdDaniel Sandlerimport android.provider.Settings;
298a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
3064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
31b104340496e3a531e26c8f428c808eca0e039f50San Mehatpublic class StorageNotification extends StorageEventListener {
3264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private static final String TAG = "StorageNotification";
3364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
34c07907e0389f20f83fdfe01319023b8c7d5e4bbdDaniel Sandler    private static final boolean POP_UMS_ACTIVITY_ON_CONNECT = true;
35c07907e0389f20f83fdfe01319023b8c7d5e4bbdDaniel Sandler
3664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
3764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Binder context for this service
3864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
3964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private Context mContext;
4064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
4164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
4264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * The notification that is shown when a USB mass storage host
4364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * is connected.
4464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * <p>
4564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * This is lazily created, so use {@link #setUsbStorageNotification()}.
4664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
4764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private Notification mUsbStorageNotification;
4864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
4964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
5064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * The notification that is shown when the following media events occur:
5164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is being checked
5264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is blank (or unknown filesystem)
5364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is corrupt
5464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is safe to unmount
5564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     *     - Media is missing
5664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * <p>
5764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * This is lazily created, so use {@link #setMediaStorageNotification()}.
5864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
59b104340496e3a531e26c8f428c808eca0e039f50San Mehat    private Notification   mMediaStorageNotification;
60b104340496e3a531e26c8f428c808eca0e039f50San Mehat    private boolean        mUmsAvailable;
61b104340496e3a531e26c8f428c808eca0e039f50San Mehat    private StorageManager mStorageManager;
6264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
6364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    public StorageNotification(Context context) {
6464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        mContext = context;
6564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
66b104340496e3a531e26c8f428c808eca0e039f50San Mehat        mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
67fe4f3ae33c8da86585399b4167fd7987c8a16066Joe Onorato        final boolean connected = mStorageManager.isUsbMassStorageConnected();
688a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.d(TAG, String.format( "Startup with UMS connection %s (media state %s)", mUmsAvailable,
69b104340496e3a531e26c8f428c808eca0e039f50San Mehat                Environment.getExternalStorageState()));
70fe4f3ae33c8da86585399b4167fd7987c8a16066Joe Onorato        onUsbMassStorageConnectionChanged(connected);
7164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
7264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
73b104340496e3a531e26c8f428c808eca0e039f50San Mehat    /*
74b104340496e3a531e26c8f428c808eca0e039f50San Mehat     * @override com.android.os.storage.StorageEventListener
75b104340496e3a531e26c8f428c808eca0e039f50San Mehat     */
76b104340496e3a531e26c8f428c808eca0e039f50San Mehat    @Override
77b104340496e3a531e26c8f428c808eca0e039f50San Mehat    public void onUsbMassStorageConnectionChanged(boolean connected) {
78b104340496e3a531e26c8f428c808eca0e039f50San Mehat        mUmsAvailable = connected;
7964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        /*
80b104340496e3a531e26c8f428c808eca0e039f50San Mehat         * Even though we may have a UMS host connected, we the SD card
81b104340496e3a531e26c8f428c808eca0e039f50San Mehat         * may not be in a state for export.
8264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat         */
83b104340496e3a531e26c8f428c808eca0e039f50San Mehat        String st = Environment.getExternalStorageState();
8464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
858a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.i(TAG, String.format("UMS connection changed to %s (media state %s)", connected, st));
86b104340496e3a531e26c8f428c808eca0e039f50San Mehat
87b104340496e3a531e26c8f428c808eca0e039f50San Mehat        if (connected && (st.equals(
88b104340496e3a531e26c8f428c808eca0e039f50San Mehat                Environment.MEDIA_REMOVED) || st.equals(Environment.MEDIA_CHECKING))) {
89b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
90b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * No card or card being checked = don't display
91b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
92b104340496e3a531e26c8f428c808eca0e039f50San Mehat            connected = false;
9364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
94b104340496e3a531e26c8f428c808eca0e039f50San Mehat        updateUsbMassStorageNotification(connected);
9564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
9664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
97b104340496e3a531e26c8f428c808eca0e039f50San Mehat    /*
98b104340496e3a531e26c8f428c808eca0e039f50San Mehat     * @override com.android.os.storage.StorageEventListener
99b104340496e3a531e26c8f428c808eca0e039f50San Mehat     */
100b104340496e3a531e26c8f428c808eca0e039f50San Mehat    @Override
101b104340496e3a531e26c8f428c808eca0e039f50San Mehat    public void onStorageStateChanged(String path, String oldState, String newState) {
1028a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.i(TAG, String.format(
103b104340496e3a531e26c8f428c808eca0e039f50San Mehat                "Media {%s} state changed from {%s} -> {%s}", path, oldState, newState));
10464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (newState.equals(Environment.MEDIA_SHARED)) {
105b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
106b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now shared. Modify the UMS notification
107b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * for stopping UMS.
108b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
10964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
110fe4f3ae33c8da86585399b4167fd7987c8a16066Joe Onorato            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
11164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
11264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setUsbStorageNotification(
11364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_stop_notification_title,
11464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_stop_notification_message,
11564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_sys_warning, false, true, pi);
11664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_CHECKING)) {
117b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
118b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now checking. Update media notification and disable
119b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * UMS notification.
120b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
12164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(
12264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_checking_notification_title,
12364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_checking_notification_message,
12464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_prepare, true, false, null);
12564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(false);
12664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_MOUNTED)) {
127b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
128b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now mounted. Dismiss any media notifications,
129b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and enable UMS notification if connected.
130b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
13164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(0, 0, 0, false, false, null);
13264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(mUmsAvailable);
13364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_UNMOUNTED)) {
134b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
135b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is now unmounted. We may have been unmounted
136b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * because the user is enabling/disabling UMS, in which case we don't
137b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * want to display the 'safe to unmount' notification.
138b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
139b104340496e3a531e26c8f428c808eca0e039f50San Mehat            if (!mStorageManager.isUsbMassStorageEnabled()) {
140b104340496e3a531e26c8f428c808eca0e039f50San Mehat                if (oldState.equals(Environment.MEDIA_SHARED)) {
141b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    /*
142b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * The unmount was due to UMS being enabled. Dismiss any
143b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * media notifications, and enable UMS notification if connected
144b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     */
145b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    setMediaStorageNotification(0, 0, 0, false, false, null);
146b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    updateUsbMassStorageNotification(mUmsAvailable);
147b104340496e3a531e26c8f428c808eca0e039f50San Mehat                } else {
148b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    /*
149b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * Show safe to unmount media notification, and enable UMS
150b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     * notification if connected.
151b104340496e3a531e26c8f428c808eca0e039f50San Mehat                     */
152d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                    if (Environment.isExternalStorageRemovable()) {
153d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                        setMediaStorageNotification(
154d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                                com.android.internal.R.string.ext_media_safe_unmount_notification_title,
155d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                                com.android.internal.R.string.ext_media_safe_unmount_notification_message,
156d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                                com.android.internal.R.drawable.stat_notify_sdcard, true, true, null);
157d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                    } else {
158d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                        // This device does not have removable storage, so
159d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                        // don't tell the user they can remove it.
160d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                        setMediaStorageNotification(0, 0, 0, false, false, null);
161d39d515b9110d7405d0f03dbf612ba5c9b8ac566Dianne Hackborn                    }
162b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    updateUsbMassStorageNotification(mUmsAvailable);
163b104340496e3a531e26c8f428c808eca0e039f50San Mehat                }
16464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            } else {
165b104340496e3a531e26c8f428c808eca0e039f50San Mehat                /*
166b104340496e3a531e26c8f428c808eca0e039f50San Mehat                 * The unmount was due to UMS being enabled. Dismiss any
167b104340496e3a531e26c8f428c808eca0e039f50San Mehat                 * media notifications, and disable the UMS notification
168b104340496e3a531e26c8f428c808eca0e039f50San Mehat                 */
16964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                setMediaStorageNotification(0, 0, 0, false, false, null);
170b104340496e3a531e26c8f428c808eca0e039f50San Mehat                updateUsbMassStorageNotification(false);
17164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
17264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_NOFS)) {
173b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
174b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage has no filesystem. Show blank media notification,
175b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and enable UMS notification if connected.
176b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
17764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
17864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
17964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
18064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
18164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(
18264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_nofs_notification_title,
18364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_nofs_notification_message,
18464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi);
18564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(mUmsAvailable);
18664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else if (newState.equals(Environment.MEDIA_UNMOUNTABLE)) {
187b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
188b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage is corrupt. Show corrupt media notification,
189b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and enable UMS notification if connected.
190b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
19164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
19264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
19364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
19464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
19564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setMediaStorageNotification(
19664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_unmountable_notification_title,
19764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.ext_media_unmountable_notification_message,
19864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi);
19964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            updateUsbMassStorageNotification(mUmsAvailable);
200b104340496e3a531e26c8f428c808eca0e039f50San Mehat        } else if (newState.equals(Environment.MEDIA_REMOVED)) {
201b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
202b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage has been removed. Show nomedia media notification,
203b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and disable UMS notification regardless of connection state.
204b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
205b104340496e3a531e26c8f428c808eca0e039f50San Mehat            setMediaStorageNotification(
206b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_nomedia_notification_title,
207b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_nomedia_notification_message,
208b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.drawable.stat_notify_sdcard_usb,
209b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    true, false, null);
210b104340496e3a531e26c8f428c808eca0e039f50San Mehat            updateUsbMassStorageNotification(false);
211b104340496e3a531e26c8f428c808eca0e039f50San Mehat        } else if (newState.equals(Environment.MEDIA_BAD_REMOVAL)) {
212b104340496e3a531e26c8f428c808eca0e039f50San Mehat            /*
213b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * Storage has been removed unsafely. Show bad removal media notification,
214b104340496e3a531e26c8f428c808eca0e039f50San Mehat             * and disable UMS notification regardless of connection state.
215b104340496e3a531e26c8f428c808eca0e039f50San Mehat             */
216b104340496e3a531e26c8f428c808eca0e039f50San Mehat            setMediaStorageNotification(
217b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_badremoval_notification_title,
218b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.string.ext_media_badremoval_notification_message,
219b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    com.android.internal.R.drawable.stat_sys_warning,
220b104340496e3a531e26c8f428c808eca0e039f50San Mehat                    true, true, null);
221b104340496e3a531e26c8f428c808eca0e039f50San Mehat            updateUsbMassStorageNotification(false);
222b104340496e3a531e26c8f428c808eca0e039f50San Mehat        } else {
2238a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, String.format("Ignoring unknown state {%s}", newState));
22464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
22564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
22664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
22764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
22864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Update the state of the USB mass storage notification
22964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
23064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    void updateUsbMassStorageNotification(boolean available) {
23164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
23264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (available) {
23364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Intent intent = new Intent();
234fe4f3ae33c8da86585399b4167fd7987c8a16066Joe Onorato            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
23564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
236c07907e0389f20f83fdfe01319023b8c7d5e4bbdDaniel Sandler
23764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
23864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setUsbStorageNotification(
23964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_notification_title,
24064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.string.usb_storage_notification_message,
24164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    com.android.internal.R.drawable.stat_sys_data_usb,
24264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    false, true, pi);
24364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else {
24464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            setUsbStorageNotification(0, 0, 0, false, false, null);
24564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
24664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
24764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
24864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
24964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Sets the USB storage notification.
25064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
2514154c07c5cabc74029a2df379075391d782a682cSan Mehat    private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon,
2524154c07c5cabc74029a2df379075391d782a682cSan Mehat            boolean sound, boolean visible, PendingIntent pi) {
25364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
25464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (!visible && mUsbStorageNotification == null) {
25564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
25664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
25764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
25864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        NotificationManager notificationManager = (NotificationManager) mContext
25964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                .getSystemService(Context.NOTIFICATION_SERVICE);
26064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
26164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (notificationManager == null) {
26264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
26364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
26464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
26564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
26664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Resources r = Resources.getSystem();
26764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence title = r.getText(titleId);
26864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence message = r.getText(messageId);
26964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
27064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (mUsbStorageNotification == null) {
27164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification = new Notification();
27264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.icon = icon;
27364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.when = 0;
27464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
27564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
27664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (sound) {
27764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.defaults |= Notification.DEFAULT_SOUND;
27864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            } else {
27964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mUsbStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
28064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
28164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
28264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mUsbStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;
28364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
28464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mUsbStorageNotification.tickerText = title;
28564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (pi == null) {
28664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                Intent intent = new Intent();
28764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
28864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
28964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
29064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi);
291f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler            final boolean adbOn = 1 == Settings.Secure.getInt(
292f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                mContext.getContentResolver(),
293f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                Settings.Secure.ADB_ENABLED,
294f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                0);
295f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler
296f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler            if (POP_UMS_ACTIVITY_ON_CONNECT && !adbOn) {
297f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // Pop up a full-screen alert to coach the user through enabling UMS. The average
298f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // user has attached the device to USB either to charge the phone (in which case
299f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // this is harmless) or transfer files, and in the latter case this alert saves
300f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // several steps (as well as subtly indicates that you shouldn't mix UMS with other
301f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // activities on the device).
302f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                //
303f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // If ADB is enabled, however, we suppress this dialog (under the assumption that a
304f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // developer (a) knows how to enable UMS, and (b) is probably using USB to install
305f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                // builds or use adb commands.
306f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler                mUsbStorageNotification.fullScreenIntent = pi;
307f7d2b4a2e096ae1f8ac3a2ed8b2f0e30a237f732Daniel Sandler            }
30864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
30964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
31064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        final int notificationId = mUsbStorageNotification.icon;
31164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
31264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.notify(notificationId, mUsbStorageNotification);
31364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else {
31464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.cancel(notificationId);
31564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
31664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
31764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
31864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private synchronized boolean getMediaStorageNotificationDismissable() {
31964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if ((mMediaStorageNotification != null) &&
32064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            ((mMediaStorageNotification.flags & Notification.FLAG_AUTO_CANCEL) ==
32164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                    Notification.FLAG_AUTO_CANCEL))
32264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return true;
32364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
32464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        return false;
32564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
32664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
32764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    /**
32864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     * Sets the media storage notification.
32964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat     */
33064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    private synchronized void setMediaStorageNotification(int titleId, int messageId, int icon, boolean visible,
33164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                                                          boolean dismissable, PendingIntent pi) {
33264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
33364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (!visible && mMediaStorageNotification == null) {
33464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
33564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
33664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
33764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        NotificationManager notificationManager = (NotificationManager) mContext
33864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                .getSystemService(Context.NOTIFICATION_SERVICE);
33964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
34064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (notificationManager == null) {
34164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            return;
34264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
34364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
34464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (mMediaStorageNotification != null && visible) {
34564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            /*
34664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat             * Dismiss the previous notification - we're about to
34764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat             * re-use it.
34864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat             */
34964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            final int notificationId = mMediaStorageNotification.icon;
35064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.cancel(notificationId);
35164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
35264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
35364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
35464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            Resources r = Resources.getSystem();
35564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence title = r.getText(titleId);
35664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            CharSequence message = r.getText(messageId);
35764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
35864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (mMediaStorageNotification == null) {
35964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification = new Notification();
36064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification.when = 0;
36164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
36264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
36364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
36464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
36564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (dismissable) {
36664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification.flags = Notification.FLAG_AUTO_CANCEL;
36764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            } else {
36864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                mMediaStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;
36964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
37064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
37164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.tickerText = title;
37264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            if (pi == null) {
37364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                Intent intent = new Intent();
37464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat                pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
37564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            }
37664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
37764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.icon = icon;
37864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi);
37964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
38064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat
38164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        final int notificationId = mMediaStorageNotification.icon;
38264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        if (visible) {
38364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.notify(notificationId, mMediaStorageNotification);
38464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        } else {
38564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat            notificationManager.cancel(notificationId);
38664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat        }
38764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat    }
38864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat}
389