MountService.java revision 3697229cc7adfd89493e87ba8b6401c8b68bdd71
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Notification; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.NotificationManager; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IMountService; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Environment; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.UEventObserver; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileReader; 383697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehatimport java.lang.IllegalStateException; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MountService implements an to the mount service daemon 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass MountService extends IMountService.Stub { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "MountService"; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 487fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat class VolumeState { 497fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Init = -1; 507fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int NoMedia = 0; 517fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Idle = 1; 527fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Pending = 2; 537fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Checking = 3; 547fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Mounted = 4; 557fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Unmounting = 5; 567fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Formatting = 6; 577fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int Shared = 7; 587fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public static final int SharedMnt = 8; 597fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 607fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Binder context for this service 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * listener object for communicating with the mount service daemon 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MountListener mListener; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The notification that is shown when a USB mass storage host 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is connected. 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is lazily created, so use {@link #setUsbStorageNotification()}. 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Notification mUsbStorageNotification; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The notification that is shown when the following media events occur: 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - Media is being checked 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - Media is blank (or unknown filesystem) 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - Media is corrupt 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - Media is safe to unmount 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - Media is missing 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is lazily created, so use {@link #setMediaStorageNotification()}. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Notification mMediaStorageNotification; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mShowSafeUnmountNotificationWhenUnmounted; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mPlaySounds; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMounted; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 98ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project private boolean mAutoStartUms; 99ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 1007fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat private boolean mUmsConnected = false; 1017fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat private boolean mUmsEnabled = false; 1027fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1037fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat private String mLegacyState = Environment.MEDIA_REMOVED; 1047fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructs a new MountService instance 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context Binder context for this service 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MountService(Context context) { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Register a BOOT_COMPLETED handler so that we can start 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // MountListener. We defer the startup so that we don't 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // start processing events before we ought-to 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(mBroadcastReceiver, 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = new MountListener(this); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowSafeUnmountNotificationWhenUnmounted = false; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlaySounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1"); 123ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 124ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mAutoStartUms = SystemProperties.get("persist.service.mount.umsauto", "0").equals("1"); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread thread = new Thread(mListener, MountListener.class.getName()); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread.start(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if USB mass storage support is enabled. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1393697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public boolean getMassStorageEnabled() { 1407fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return mUmsEnabled; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables or disables USB mass storage support. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enable true to enable USB mass storage support 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1483697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public void setMassStorageEnabled(boolean enable) throws IllegalStateException { 1497fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat try { 1507fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat String vp = Environment.getExternalStorageDirectory().getPath(); 1517fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat String vs = getVolumeState(vp); 1527fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1537fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (enable && vs.equals(Environment.MEDIA_MOUNTED)) { 1547fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.d(TAG, "Unmounting media before UMS enable"); 1557fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat unmountMedia(vp); 1567fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 1577fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1587fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mListener.setShareMethodEnabled(Environment 1597fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat .getExternalStorageDirectory() 1607fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat .getPath(), 1617fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat "ums", enable); 1627fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mUmsEnabled = enable; 1637fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (!enable) { 1647fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.d(TAG, "Mounting media after UMS disable"); 1657fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mountMedia(vp); 1667fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 1673697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } catch (IllegalStateException rex) { 1687fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.e(TAG, "Failed to set ums enable {" + enable + "}"); 1697fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return; 1707fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if USB mass storage is connected. 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1763697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public boolean getMassStorageConnected() { 1777fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return mUmsConnected; 1787fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 1797fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1807fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat /** 1817fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat * @return state of the volume at the specified mount point 1827fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat */ 1833697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public String getVolumeState(String mountPoint) throws IllegalStateException { 1847fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat /* 1857fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat * XXX: Until we have multiple volume discovery, just hardwire 1867fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat * this to /sdcard 1877fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat */ 1887fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (!mountPoint.equals(Environment.getExternalStorageDirectory().getPath())) { 1897fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "getVolumeState(" + mountPoint + "): Unknown volume"); 1907fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat throw new IllegalArgumentException(); 1917fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 1927fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1937fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return mLegacyState; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1957fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Attempt to mount external media 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2003697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public void mountMedia(String mountPath) throws IllegalStateException { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission"); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2067fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mListener.mountVolume(mountPath); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Attempt to unmount external media to prepare for eject 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2123697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public void unmountMedia(String mountPath) throws IllegalStateException { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission"); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set a flag so that when we get the unmounted event, we know 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to display the notification 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowSafeUnmountNotificationWhenUnmounted = true; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // tell mountd to unmount the media 2247fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mListener.unmountVolume(mountPath); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Attempt to format external media 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2303697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public void formatMedia(String formatPath) throws IllegalStateException { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS) 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires MOUNT_FORMAT_FILESYSTEMS permission"); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2377fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mListener.formatVolume(formatPath); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if we're playing media notification sounds. 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPlayNotificationSounds() { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPlaySounds; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set whether or not we're playing media notification sounds. 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPlayNotificationSounds(boolean enabled) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.WRITE_SETTINGS) 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires WRITE_SETTINGS permission"); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlaySounds = enabled; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SystemProperties.set("persist.service.mount.playsnd", (enabled ? "1" : "0")); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 261ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * Returns true if we auto-start UMS on cable insertion. 262ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project */ 263ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project public boolean getAutoStartUms() { 264ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project return mAutoStartUms; 265ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 266ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 267ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project /** 268ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * Set whether or not we're playing media notification sounds. 269ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project */ 270ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project public void setAutoStartUms(boolean enabled) { 271ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 272ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project android.Manifest.permission.WRITE_SETTINGS) 273ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 274ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project throw new SecurityException("Requires WRITE_SETTINGS permission"); 275ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 276ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mAutoStartUms = enabled; 277ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project SystemProperties.set("persist.service.mount.umsauto", (enabled ? "1" : "0")); 278ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 279ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 2807fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat void updatePublicVolumeState(String mountPoint, String state) { 2817fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (!mountPoint.equals(Environment.getExternalStorageDirectory().getPath())) { 2827fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "Multiple volumes not currently supported"); 2837fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return; 2847fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 2857fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "State for {" + mountPoint + "} = {" + state + "}"); 2867fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mLegacyState = state; 2877fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 2887fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 289ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project /** 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update the state of the USB mass storage notification 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void updateUsbMassStorageNotification(boolean suppressIfConnected, boolean sound) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getMassStorageConnected() && !suppressIfConnected) { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.setClass(mContext, com.android.internal.app.UsbStorageActivity.class); 2999517443904e341ee77c38648763d55687cd88760Mike Lockwood intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setUsbStorageNotification( 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.usb_storage_notification_title, 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.usb_storage_notification_message, 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.drawable.stat_sys_data_usb, 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sound, true, pi); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setUsbStorageNotification(0, 0, 0, false, false, null); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3093697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } catch (IllegalStateException e) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Nothing to do 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void handlePossibleExplicitUnmountBroadcast(String path) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMounted) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMounted = false; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3237fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat void onVoldConnected() { 3247fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat new Thread() { 3257fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public void run() { 3267fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat try { 3277fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (!getVolumeState(Environment.getExternalStorageDirectory().getPath()) 3287fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat .equals(Environment.MEDIA_MOUNTED)) { 3297fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat try { 3307fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mountMedia(Environment.getExternalStorageDirectory().getPath()); 3317fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.d(TAG, "Connection-mount suceeded"); 3327fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } catch (Exception ex) { 3337fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "Connection-mount failed"); 3347fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3357fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else { 3367fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.d(TAG, "Skipping connection-mount; already mounted"); 3377fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3383697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } catch (IllegalStateException rex) { 3397fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.e(TAG, "Exception while handling connection mount " + rex); 3407fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3417fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 3427fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat try { 3437fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat boolean avail = mListener.getShareAvailable("ums"); 3447fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyShareAvailabilityChange("ums", avail); 3457fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } catch (Exception ex) { 3467fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "Failed to get share availability"); 3477fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3487fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3497fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat }.start(); 3507fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3517fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 3527fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat void notifyVolumeStateChange(String label, String mountPoint, int oldState, 3533697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat int newState) throws IllegalStateException { 3547fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat String vs = getVolumeState(mountPoint); 3557fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 3567fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (newState == VolumeState.Init) { 3577fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.NoMedia) { 3587fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // NoMedia is handled via Disk Remove events 3597fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Idle) { 3607fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Don't notify if we're in BAD_REMOVAL, NOFS, or UNMOUNTABLE 3617fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (!vs.equals(Environment.MEDIA_BAD_REMOVAL) && 3627fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat !vs.equals(Environment.MEDIA_NOFS) && 3637fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat !vs.equals(Environment.MEDIA_UNMOUNTABLE)) { 3647fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyMediaUnmounted(mountPoint); 3657fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3667fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Pending) { 3677fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Checking) { 3687fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyMediaChecking(mountPoint); 3697fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Mounted) { 3707fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyMediaMounted(mountPoint, false); 3717fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Unmounting) { 3727fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyMediaUnmounting(mountPoint); 3737fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Formatting) { 3747fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.Shared) { 3757fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyMediaShared(mountPoint, false); 3767fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else if (newState == VolumeState.SharedMnt) { 3777fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyMediaShared(mountPoint, true); 3787fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else { 3797fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.e(TAG, "Unhandled VolumeState {" + newState + "}"); 3807fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3817fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 3827fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 3837fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the USB mass storage connected event to all clients. 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyUmsConnected() { 3887fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mUmsConnected = true; 3897fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String storageState = Environment.getExternalStorageState(); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!storageState.equals(Environment.MEDIA_REMOVED) && 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !storageState.equals(Environment.MEDIA_BAD_REMOVAL) && 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !storageState.equals(Environment.MEDIA_CHECKING)) { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 395ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project if (mAutoStartUms) { 396ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project try { 397ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project setMassStorageEnabled(true); 3983697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } catch (IllegalStateException e) { 399ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 400ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else { 401ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project updateUsbMassStorageNotification(false, true); 402ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_UMS_CONNECTED); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4097fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat void notifyShareAvailabilityChange(String method, boolean avail) { 4107fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.d(TAG, "Share method {" + method + "} availability now " + avail); 4117fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (!method.equals("ums")) { 4127fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "Ignoring unsupported share method {" + method + "}"); 4137fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return; 4147fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4157fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (avail) { 4167fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyUmsConnected(); 4177fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } else { 4187fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat notifyUmsDisconnected(); 4197fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4207fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4217fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the USB mass storage disconnected event to all clients. 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyUmsDisconnected() { 4267fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mUmsConnected = false; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(false, false); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_UMS_DISCONNECTED); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4323697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat void notifyMediaInserted(final String path) throws IllegalStateException { 4337fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat new Thread() { 4347fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat public void run() { 4357fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat try { 4367fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.d(TAG, "Mounting media after insertion"); 4377fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat mountMedia(path); 4387fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } catch (Exception ex) { 4397fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.w(TAG, "Failed to mount media on insertion"); 4407fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4417fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4427fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat }.start(); 4437fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4447fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media removed event to all clients. 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4483697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat void notifyMediaRemoved(String path) throws IllegalStateException { 4497fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4507fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Suppress this on bad removal 4517fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (getVolumeState(path).equals(Environment.MEDIA_BAD_REMOVAL)) { 4527fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return; 4537fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 4547fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4557fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_REMOVED); 4567fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(true, false); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification( 4607fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat com.android.internal.R.string.ext_media_nomedia_notification_title, 4617fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat com.android.internal.R.string.ext_media_nomedia_notification_message, 4627fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat com.android.internal.R.drawable.stat_notify_sdcard_usb, 4637fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat true, false, null); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlePossibleExplicitUnmountBroadcast(path); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4667fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_REMOVED"); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_REMOVED, 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media unmounted event to all clients. 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyMediaUnmounted(String path) { 4767fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4777fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED); 4787fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowSafeUnmountNotificationWhenUnmounted) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification( 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_safe_unmount_notification_title, 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_safe_unmount_notification_message, 483de46acddf597da5637b99a8a6e52ffd642ae913eMike Lockwood com.android.internal.R.drawable.stat_notify_sdcard, 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project true, true, null); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowSafeUnmountNotificationWhenUnmounted = false; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification(0, 0, 0, false, false, null); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(false, false); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4917fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_UNMOUNTED"); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media checking event to all clients. 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyMediaChecking(String path) { 5017fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_CHECKING); 5027fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification( 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_checking_notification_title, 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_checking_notification_message, 506de46acddf597da5637b99a8a6e52ffd642ae913eMike Lockwood com.android.internal.R.drawable.stat_notify_sdcard_prepare, 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project true, false, null); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(true, false); 5107fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_CHECKING"); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_CHECKING, 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media nofs event to all clients. 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyMediaNoFs(String path) { 5207fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_NOFS); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification(com.android.internal.R.string.ext_media_nofs_notification_title, 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_nofs_notification_message, 528a7ef2698a6c9182ffd41574495a18da1ffc2be2cMike Lockwood com.android.internal.R.drawable.stat_notify_sdcard_usb, 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project true, false, pi); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(false, false); 5317fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_NOFS"); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent = new Intent(Intent.ACTION_MEDIA_NOFS, 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media mounted event to all clients. 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyMediaMounted(String path, boolean readOnly) { 5417fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_MOUNTED); 5427fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification(0, 0, 0, false, false, null); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(false, false); 5457fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_MOUNTED"); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("read-only", readOnly); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMounted = true; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media shared event to all clients. 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5567fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat void notifyMediaShared(String path, boolean mounted) { 5577fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat if (mounted) { 5587fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat Log.e(TAG, "Live shared mounts not supported yet!"); 5597fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat return; 5607fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat } 5617fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 5627fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_SHARED); 5637fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.setClass(mContext, com.android.internal.app.UsbStorageStopActivity.class); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setUsbStorageNotification(com.android.internal.R.string.usb_storage_stop_notification_title, 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.usb_storage_stop_notification_message, 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.drawable.stat_sys_warning, 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project false, true, pi); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlePossibleExplicitUnmountBroadcast(path); 5727fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_SHARED"); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent = new Intent(Intent.ACTION_MEDIA_SHARED, 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media bad removal event to all clients. 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyMediaBadRemoval(String path) { 5827fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_BAD_REMOVAL); 5837fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(true, false); 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification(com.android.internal.R.string.ext_media_badremoval_notification_title, 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_badremoval_notification_message, 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.drawable.stat_sys_warning, 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project true, true, null); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlePossibleExplicitUnmountBroadcast(path); 5917fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_BAD_REMOVAL"); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_BAD_REMOVAL, 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media unmountable event to all clients. 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void notifyMediaUnmountable(String path) { 6017fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTABLE); 6027fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMediaStorageNotification(com.android.internal.R.string.ext_media_unmountable_notification_title, 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.string.ext_media_unmountable_notification_message, 609a7ef2698a6c9182ffd41574495a18da1ffc2be2cMike Lockwood com.android.internal.R.drawable.stat_notify_sdcard_usb, 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project true, false, pi); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateUsbMassStorageNotification(false, false); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlePossibleExplicitUnmountBroadcast(path); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6157fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_UNMOUNTABLE"); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTABLE, 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcasts the media eject event to all clients. 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6247fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat void notifyMediaUnmounting(String path) { 6257fd0fee968f4a3e474e1ea9933fc03552fe5f50aSan Mehat // Log.d(TAG, "Sending ACTION_MEDIA_EJECT"); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_MEDIA_EJECT, 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Uri.parse("file://" + path)); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the USB storage notification. 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon, boolean sound, boolean visible, 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent pi) { 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!visible && mUsbStorageNotification == null) { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NotificationManager notificationManager = (NotificationManager) mContext 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getSystemService(Context.NOTIFICATION_SERVICE); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notificationManager == null) { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visible) { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r = Resources.getSystem(); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence title = r.getText(titleId); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence message = r.getText(messageId); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUsbStorageNotification == null) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification = new Notification(); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.icon = icon; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.when = 0; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sound && mPlaySounds) { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.defaults |= Notification.DEFAULT_SOUND; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.defaults &= ~Notification.DEFAULT_SOUND; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.flags = Notification.FLAG_ONGOING_EVENT; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.tickerText = title; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi == null) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int notificationId = mUsbStorageNotification.icon; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visible) { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.notify(notificationId, mUsbStorageNotification); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.cancel(notificationId); 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized boolean getMediaStorageNotificationDismissable() { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mMediaStorageNotification != null) && 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mMediaStorageNotification.flags & Notification.FLAG_AUTO_CANCEL) == 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Notification.FLAG_AUTO_CANCEL)) 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the media storage notification. 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized void setMediaStorageNotification(int titleId, int messageId, int icon, boolean visible, 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean dismissable, PendingIntent pi) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!visible && mMediaStorageNotification == null) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NotificationManager notificationManager = (NotificationManager) mContext 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getSystemService(Context.NOTIFICATION_SERVICE); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notificationManager == null) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMediaStorageNotification != null && visible) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Dismiss the previous notification - we're about to 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * re-use it. 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int notificationId = mMediaStorageNotification.icon; 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.cancel(notificationId); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visible) { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r = Resources.getSystem(); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence title = r.getText(titleId); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence message = r.getText(messageId); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMediaStorageNotification == null) { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification = new Notification(); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.when = 0; 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlaySounds) { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.defaults |= Notification.DEFAULT_SOUND; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.defaults &= ~Notification.DEFAULT_SOUND; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dismissable) { 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.flags = Notification.FLAG_AUTO_CANCEL; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.flags = Notification.FLAG_ONGOING_EVENT; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.tickerText = title; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi == null) { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(); 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.icon = icon; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int notificationId = mMediaStorageNotification.icon; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visible) { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.notify(notificationId, mMediaStorageNotification); 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.cancel(notificationId); 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7583697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7593697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public String[] getSecureCacheList() throws IllegalStateException { 7603697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat return mListener.listAsec(); 7613697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } 7623697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7633697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public String createSecureCache(String id, int sizeMb, String fstype, 7643697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat String key, int ownerUid) throws IllegalStateException { 7653697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat return mListener.createAsec(id, sizeMb, fstype, key, ownerUid); 7663697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } 7673697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7683697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public void finalizeSecureCache(String id) throws IllegalStateException { 7693697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat mListener.finalizeAsec(id); 7703697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } 7713697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7723697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public void destroySecureCache(String id) throws IllegalStateException { 7733697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat mListener.destroyAsec(id); 7743697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } 7753697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7763697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public String mountSecureCache(String id, String key, int ownerUid) throws IllegalStateException { 7773697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat return mListener.mountAsec(id, key, ownerUid); 7783697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } 7793697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7803697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat public String getSecureCachePath(String id) throws IllegalStateException { 7813697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat return mListener.getAsecPath(id); 7823697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat } 7833697229cc7adfd89493e87ba8b6401c8b68bdd71San Mehat 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 786