diff options
| author | San Mehat <san@google.com> | 2010-02-05 08:26:50 -0800 |
|---|---|---|
| committer | San Mehat <san@google.com> | 2010-02-09 11:03:16 -0800 |
| commit | b104340496e3a531e26c8f428c808eca0e039f50 (patch) | |
| tree | 11247cb68359d43ca4871c0cb0165c9bec339a6f /core | |
| parent | 3ee1317173260252d475772fec09d492f8fcfd33 (diff) | |
| download | frameworks_base-b104340496e3a531e26c8f428c808eca0e039f50.zip frameworks_base-b104340496e3a531e26c8f428c808eca0e039f50.tar.gz frameworks_base-b104340496e3a531e26c8f428c808eca0e039f50.tar.bz2 | |
Framework: Clean up / Refactor Mount APIs
- Move android.storage.* -> android.os.storage.* and refactor users
- Refactor generic shares back to explicit ums enable/disable/isEnabled
- Remove media insert/removed event callbacks (not ready for Froyo)
- Remove 'label' from volume state change callbacks
- Add public API functions for enabling/disabling USB mass storage (permissions enforced
in MountSevice)
- Remove some stray un-needed import lines
- Move android.os.IMountService / android.os.IMountServiceListener -> android.os.storage
- Improve code comments
Updated:
MountService: Add dup state check and move debugging behind a conditional
UsbStorageActivity: Fix review comments + a TODO
StorageNotification: Add @Override tags
StorageManager: Don't use a static Listener list
MountService: Reduce bloat and fix == where I meant .equals()
PackageManagerTests: Update for new API
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'core')
20 files changed, 621 insertions, 654 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 45d7546..4923eee 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -84,7 +84,7 @@ import android.os.ServiceManager; import android.os.StatFs; import android.os.Vibrator; import android.os.FileUtils.FileStatus; -import android.storage.StorageManager; +import android.os.storage.StorageManager; import android.telephony.TelephonyManager; import android.text.ClipboardManager; import android.util.AndroidRuntimeException; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 5aefe4c..b4a0bf8 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1110,7 +1110,7 @@ public abstract class Context { * @see #SENSOR_SERVICE * @see android.hardware.SensorManager * @see #STORAGE_SERVICE - * @see android.storage.StorageManager + * @see android.os.storage.StorageManager * @see #VIBRATOR_SERVICE * @see android.os.Vibrator * @see #CONNECTIVITY_SERVICE @@ -1243,11 +1243,11 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a {@link - * android.storage.StorageManager} for accesssing system storage + * android.os.storage.StorageManager} for accesssing system storage * functions. * * @see #getSystemService - * @see android.storage.StorageManager + * @see android.os.storage.StorageManager */ public static final String STORAGE_SERVICE = "storage"; diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 9491bd4..ef1f3be 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -18,7 +18,7 @@ package android.os; import java.io.File; -import android.os.IMountService; +import android.os.storage.IMountService; /** * Provides access to environment variables. diff --git a/core/java/android/os/IMountServiceListener.aidl b/core/java/android/os/IMountServiceListener.aidl deleted file mode 100644 index 3df64b2..0000000 --- a/core/java/android/os/IMountServiceListener.aidl +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.os; - -/** - * Callback class for receiving events from MountService. - * - * @hide - */ -interface IMountServiceListener { - /** - * A sharing method has changed availability state. - * - * @param method The share method which has changed. - * @param available The share availability state. - */ - void onShareAvailabilityChanged(String method, boolean available); - - /** - * Media has been inserted - * - * @param label The volume label. - * @param path The volume mount path. - * @param major The backing device major number. - * @param minor The backing device minor number. - */ - void onMediaInserted(String label, String path, int major, int minor); - - /** - * Media has been removed - * - * @param label The volume label. - * @param path The volume mount path. - * @param major The backing device major number. - * @param minor The backing device minor number. - * @param clean Indicates if the removal was clean (unmounted first). - */ - void onMediaRemoved(String label, String path, int major, int minor, boolean clean); - - /** - * Volume state has changed. - * - * @param label The volume label. - * @param path The volume mount path. - * @param oldState The old state of the volume. - * @param newState The new state of the volume. - * - * Note: State is one of the values returned by Environment.getExternalStorageState() - */ - void onVolumeStateChanged(String label, String path, String oldState, String newState); - -} diff --git a/core/java/android/os/MountServiceListener.java b/core/java/android/os/MountServiceListener.java deleted file mode 100644 index a68f464..0000000 --- a/core/java/android/os/MountServiceListener.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.os; - -/** - * Callback class for receiving progress reports during a restore operation. These - * methods will all be called on your application's main thread. - * @hide - */ -public abstract class MountServiceListener { - /** - * A sharing method has changed availability state. - * - * @param method The share method which has changed. - * @param available The share availability state. - */ - void shareAvailabilityChange(String method, boolean available) { - } - - /** - * Media has been inserted - * - * @param label The volume label. - * @param path The volume mount path. - * @param major The backing device major number. - * @param minor The backing device minor number. - */ - void mediaInserted(String label, String path, int major, int minor) { - } - - /** - * Media has been removed - * - * @param label The volume label. - * @param path The volume mount path. - * @param major The backing device major number. - * @param minor The backing device minor number. - * @param clean Indicates if the removal was clean (unmounted first). - */ - void mediaRemoved(String label, String path, int major, int minor, boolean clean) { - } - - /** - * Volume state has changed. - * - * @param label The volume label. - * @param path The volume mount path. - * @param oldState The old state of the volume. - * @param newState The new state of the volume. - * - * Note: State is one of the values returned by Environment.getExternalStorageState() - */ - void volumeStateChange(String label, String path, String oldState, String newState) { - } -} diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java index bc76180..b3df522 100644 --- a/core/java/android/os/Power.java +++ b/core/java/android/os/Power.java @@ -18,7 +18,7 @@ package android.os; import java.io.IOException; import android.os.ServiceManager; -import android.os.IMountService; +import android.os.storage.IMountService; /** * Class that provides access to some of the power management functions. diff --git a/core/java/android/os/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl index a5828f6..84e3f58 100644 --- a/core/java/android/os/IMountService.aidl +++ b/core/java/android/os/storage/IMountService.aidl @@ -15,14 +15,15 @@ ** limitations under the License. */ -package android.os; +package android.os.storage; -import android.os.IMountServiceListener; +import android.os.storage.IMountServiceListener; /** WARNING! Update IMountService.h and IMountService.cpp if you change this file. * In particular, the ordering of the methods below must match the * _TRANSACTION enum in IMountService.cpp - * @hide + * @hide - Applications should use android.os.storage.StorageManager to access + * storage functions. */ interface IMountService { @@ -38,31 +39,19 @@ interface IMountService void unregisterListener(IMountServiceListener listener); /** - * Gets an Array of supported share methods + * Returns true if a USB mass storage host is connected */ - String[] getShareMethodList(); + boolean isUsbMassStorageConnected(); /** - * Returns true if the share method is available + * Enables / disables USB mass storage. */ - boolean getShareMethodAvailable(String method); + int setUsbMassStorageEnabled(boolean enable); /** - * Shares a volume via the specified method - * Returns an int consistent with MountServiceResultCode - */ - int shareVolume(String path, String method); - - /** - * Unshares a volume via the specified method - * Returns an int consistent with MountServiceResultCode - */ - int unshareVolume(String path, String method); - - /** - * Returns true if the volume is shared via the specified method. + * Returns true if a USB mass storage host is enabled (media is shared) */ - boolean getVolumeShared(String path, String method); + boolean isUsbMassStorageEnabled(); /** * Mount external storage at given mount point. diff --git a/core/java/android/os/storage/IMountServiceListener.aidl b/core/java/android/os/storage/IMountServiceListener.aidl new file mode 100644 index 0000000..883413a --- /dev/null +++ b/core/java/android/os/storage/IMountServiceListener.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.storage; + +/** + * Callback class for receiving events from MountService. + * + * @hide - Applications should use android.os.storage.IStorageEventListener + * for storage event callbacks. + */ +interface IMountServiceListener { + /** + * Detection state of USB Mass Storage has changed + * + * @param available true if a UMS host is connected. + */ + void onUsbMassStorageConnectionChanged(boolean connected); + + /** + * Storage state has changed. + * + * @param path The volume mount path. + * @param oldState The old state of the volume. + * @param newState The new state of the volume. + * + * Note: State is one of the values returned by Environment.getExternalStorageState() + */ + void onStorageStateChanged(String path, String oldState, String newState); +} diff --git a/core/java/android/os/storage/MountServiceListener.java b/core/java/android/os/storage/MountServiceListener.java new file mode 100644 index 0000000..bebb3f6 --- /dev/null +++ b/core/java/android/os/storage/MountServiceListener.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.storage; + +/** + * Callback class for receiving progress reports during a restore operation. These + * methods will all be called on your application's main thread. + * @hide + */ +public abstract class MountServiceListener { + /** + * USB Mass storage connection state has changed. + * + * @param connected True if UMS is connected. + */ + void onUsbMassStorageConnectionChanged(boolean connected) { + } + + /** + * Storage state has changed. + * + * @param path The volume mount path. + * @param oldState The old state of the volume. + * @param newState The new state of the volume. + * + * @Note: State is one of the values returned by Environment.getExternalStorageState() + */ + void onStorageStateChange(String path, String oldState, String newState) { + } +} diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java new file mode 100644 index 0000000..d3d39d6 --- /dev/null +++ b/core/java/android/os/storage/StorageEventListener.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.storage; + +/** + * Used for receiving notifications from the StorageManager + */ +public abstract class StorageEventListener { + /** + * Called when the detection state of a USB Mass Storage host has changed. + * @param connected true if the USB mass storage is connected. + */ + public void onUsbMassStorageConnectionChanged(boolean connected) { + } + + /** + * Called when storage has changed state + * @param path the filesystem path for the storage + * @param oldState the old state as returned by {@link android.os.Environment#getExternalStorageState()}. + * @param newState the old state as returned by {@link android.os.Environment#getExternalStorageState()}. + */ + public void onStorageStateChanged(String path, String oldState, String newState) { + } +} diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java new file mode 100644 index 0000000..e421ea5 --- /dev/null +++ b/core/java/android/os/storage/StorageManager.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.storage; + +import android.content.Context; +import android.os.Binder; +import android.os.Bundle; +import android.os.Looper; +import android.os.Parcelable; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.RemoteException; +import android.os.Handler; +import android.os.Message; +import android.os.ServiceManager; +import android.os.storage.IMountService; +import android.os.storage.IMountServiceListener; +import android.util.Log; +import android.util.SparseArray; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +/** + * StorageManager is the interface to the systems storage service. + * Get an instance of this class by calling + * {@link android.content.Context#getSystemService(java.lang.String)} with an argument + * of {@link android.content.Context#STORAGE_SERVICE}. + * + */ + +public class StorageManager +{ + private static final String TAG = "StorageManager"; + + /* + * Our internal MountService binder reference + */ + private IMountService mMountService; + + /* + * The looper target for callbacks + */ + Looper mTgtLooper; + + /* + * Target listener for binder callbacks + */ + private MountServiceBinderListener mBinderListener; + + /* + * List of our listeners + */ + private ArrayList<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>(); + + private class MountServiceBinderListener extends IMountServiceListener.Stub { + public void onUsbMassStorageConnectionChanged(boolean available) { + final int size = mListeners.size(); + for (int i = 0; i < size; i++) { + mListeners.get(i).sendShareAvailabilityChanged(available); + } + } + + public void onStorageStateChanged(String path, String oldState, String newState) { + final int size = mListeners.size(); + for (int i = 0; i < size; i++) { + mListeners.get(i).sendStorageStateChanged(path, oldState, newState); + } + } + } + + /** + * Private base class for messages sent between the callback thread + * and the target looper handler. + */ + private class StorageEvent { + public static final int EVENT_UMS_CONNECTION_CHANGED = 1; + public static final int EVENT_STORAGE_STATE_CHANGED = 2; + + private Message mMessage; + + public StorageEvent(int what) { + mMessage = Message.obtain(); + mMessage.what = what; + mMessage.obj = this; + } + + public Message getMessage() { + return mMessage; + } + } + + /** + * Message sent on a USB mass storage connection change. + */ + private class UmsConnectionChangedStorageEvent extends StorageEvent { + public boolean available; + + public UmsConnectionChangedStorageEvent(boolean a) { + super(EVENT_UMS_CONNECTION_CHANGED); + available = a; + } + } + + /** + * Message sent on volume state change. + */ + private class StorageStateChangedStorageEvent extends StorageEvent { + public String path; + public String oldState; + public String newState; + + public StorageStateChangedStorageEvent(String p, String oldS, String newS) { + super(EVENT_STORAGE_STATE_CHANGED); + path = p; + oldState = oldS; + newState = newS; + } + } + + /** + * Private class containing sender and receiver code for StorageEvents. + */ + private class ListenerDelegate { + final StorageEventListener mStorageEventListener; + private final Handler mHandler; + + ListenerDelegate(StorageEventListener listener) { + mStorageEventListener = listener; + mHandler = new Handler(mTgtLooper) { + @Override + public void handleMessage(Message msg) { + StorageEvent e = (StorageEvent) msg.obj; + + if (msg.what == StorageEvent.EVENT_UMS_CONNECTION_CHANGED) { + UmsConnectionChangedStorageEvent ev = (UmsConnectionChangedStorageEvent) e; + mStorageEventListener.onUsbMassStorageConnectionChanged(ev.available); + } else if (msg.what == StorageEvent.EVENT_STORAGE_STATE_CHANGED) { + StorageStateChangedStorageEvent ev = (StorageStateChangedStorageEvent) e; + mStorageEventListener.onStorageStateChanged(ev.path, ev.oldState, ev.newState); + } else { + Log.e(TAG, "Unsupported event " + msg.what); + } + } + }; + } + + StorageEventListener getListener() { + return mStorageEventListener; + } + + void sendShareAvailabilityChanged(boolean available) { + UmsConnectionChangedStorageEvent e = new UmsConnectionChangedStorageEvent(available); + mHandler.sendMessage(e.getMessage()); + } + + void sendStorageStateChanged(String path, String oldState, String newState) { + StorageStateChangedStorageEvent e = new StorageStateChangedStorageEvent(path, oldState, newState); + mHandler.sendMessage(e.getMessage()); + } + } + + /** + * Constructs a StorageManager object through which an application can + * can communicate with the systems mount service. + * + * @param tgtLooper The {@android.os.Looper} which events will be received on. + * + * <p>Applications can get instance of this class by calling + * {@link android.content.Context#getSystemService(java.lang.String)} with an argument + * of {@link android.content.Context#STORAGE_SERVICE}. + * + * @hide + */ + public StorageManager(Looper tgtLooper) throws RemoteException { + mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); + if (mMountService == null) { + Log.e(TAG, "Unable to connect to mount service! - is it running yet?"); + return; + } + mTgtLooper = tgtLooper; + mBinderListener = new MountServiceBinderListener(); + mMountService.registerListener(mBinderListener); + } + + + /** + * Registers a {@link android.os.storage.StorageEventListener StorageEventListener}. + * + * @param listener A {@link android.os.storage.StorageEventListener StorageEventListener} object. + * + */ + public void registerListener(StorageEventListener listener) { + if (listener == null) { + return; + } + + synchronized (mListeners) { + mListeners.add(new ListenerDelegate(listener)); + } + } + + /** + * Unregisters a {@link android.os.storage.StorageEventListener StorageEventListener}. + * + * @param listener A {@link android.os.storage.StorageEventListener StorageEventListener} object. + * + */ + public void unregisterListener(StorageEventListener listener) { + if (listener == null) { + return; + } + + synchronized (mListeners) { + final int size = mListeners.size(); + for (int i=0 ; i<size ; i++) { + ListenerDelegate l = mListeners.get(i); + if (l.getListener() == listener) { + mListeners.remove(i); + break; + } + } + } + } + + /** + * Enables USB Mass Storage (UMS) on the device. + * @return an integer value representing the outcome of the operation. + * @see android.os.storage.StorageResultCode + */ + public int enableUsbMassStorage() { + try { + return mMountService.setUsbMassStorageEnabled(true); + } catch (Exception ex) { + Log.e(TAG, "Failed to enable UMS", ex); + } + return StorageResultCode.OperationFailedInternalError; + } + + /** + * Disables USB Mass Storage (UMS) on the device. + * @return an integer value representing the outcome of the operation. + * @see android.os.storage.StorageResultCode + */ + public int disableUsbMassStorage() { + try { + return mMountService.setUsbMassStorageEnabled(false); + } catch (Exception ex) { + Log.e(TAG, "Failed to disable UMS", ex); + } + return StorageResultCode.OperationFailedInternalError; + } + + /** + * Query if a USB Mass Storage (UMS) host is connected. + * @return true if UMS host is connected. + */ + public boolean isUsbMassStorageConnected() { + try { + return mMountService.isUsbMassStorageConnected(); + } catch (Exception ex) { + Log.e(TAG, "Failed to get UMS connection state", ex); + } + return false; + } + + /** + * Query if a USB Mass Storage (UMS) is enabled on the device. + * @return true if UMS host is enabled. + */ + public boolean isUsbMassStorageEnabled() { + try { + return mMountService.isUsbMassStorageEnabled(); + } catch (RemoteException rex) { + Log.e(TAG, "Failed to get UMS enable state", rex); + } + return false; + } +} diff --git a/core/java/android/os/MountServiceResultCode.java b/core/java/android/os/storage/StorageResultCode.java index e71dbf4..584f160 100644 --- a/core/java/android/os/MountServiceResultCode.java +++ b/core/java/android/os/storage/StorageResultCode.java @@ -14,21 +14,47 @@ * limitations under the License. */ -package android.os; - -import java.io.IOException; +package android.os.storage; /** - * Class that provides access to constants returned from MountService APIs - * - * {@hide} + * Class that provides access to constants returned from StorageManager + * and lower level MountService APIs. */ -public class MountServiceResultCode +public class StorageResultCode { + /** + * Operation succeeded. + * @see android.os.storage.StorageManager + */ public static final int OperationSucceeded = 0; + + /** + * Operation failed: Internal error. + * @see android.os.storage.StorageManager + */ public static final int OperationFailedInternalError = -1; + + /** + * Operation failed: Missing media. + * @see android.os.storage.StorageManager + */ public static final int OperationFailedNoMedia = -2; + + /** + * Operation failed: Media is blank. + * @see android.os.storage.StorageManager + */ public static final int OperationFailedMediaBlank = -3; + + /** + * Operation failed: Media is corrupt. + * @see android.os.storage.StorageManager + */ public static final int OperationFailedMediaCorrupt = -4; + + /** + * Operation failed: Media not mounted. + * @see android.os.storage.StorageManager + */ public static final int OperationFailedVolumeNotMounted = -5; } diff --git a/core/java/android/storage/StorageEventListener.java b/core/java/android/storage/StorageEventListener.java deleted file mode 100644 index cd71090..0000000 --- a/core/java/android/storage/StorageEventListener.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.storage; - -/** - * Used for receiving notifications from the StorageManager - */ -public interface StorageEventListener { - /** - * Called when the ability to share a volume has changed. - * @param method the share-method which has changed. - * @param available true if the share is available. - */ - public void onShareAvailabilityChanged(String method, boolean available); - - /** - * Called when media has been inserted - * @param label the system defined label for the volume. - * @param path the filesystem path for the volume. - * @param major the major number of the device. - * @param minor the minor number of the device. - */ - public void onMediaInserted(String label, String path, int major, int minor); - - /** - * Called when media has been removed - * @param label the system defined label for the volume. - * @param path the filesystem path for the volume. - * @param major the major number of the device. - * @param minor the minor number of the device. - * @param clean the media was removed cleanly. - */ - public void onMediaRemoved(String label, String path, int major, int minor, boolean clean); - - /** - * Called when a volume has changed state - * @param label the system defined label for the volume. - * @param path the filesystem path for the volume. - * @param oldState the old state as returned by {@link android.os.Environment#getExternalStorageState()}. - * @param newState the old state as returned by {@link android.os.Environment#getExternalStorageState()}. - */ - public void onVolumeStateChanged(String label, String path, String oldState, String newState); -} diff --git a/core/java/android/storage/StorageManager.java b/core/java/android/storage/StorageManager.java deleted file mode 100644 index 924d169..0000000 --- a/core/java/android/storage/StorageManager.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.storage; - -import android.content.Context; -import android.os.Binder; -import android.os.Bundle; -import android.os.Looper; -import android.os.Parcelable; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.os.RemoteException; -import android.os.Handler; -import android.os.Message; -import android.os.ServiceManager; -import android.os.IMountService; -import android.os.IMountServiceListener; -import android.util.Log; -import android.util.SparseArray; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -/** - * Class that lets you access the device's storage management functions. Get an instance of this - * class by calling {@link android.content.Context#getSystemService(java.lang.String) - * Context.getSystemService()} with an argument of {@link android.content.Context#STORAGE_SERVICE}. - */ -public class StorageManager -{ - private static final String TAG = "StorageManager"; - - /* - * Our internal MountService binder reference - */ - private IMountService mMountService; - - /* - * The looper target for callbacks - */ - Looper mTgtLooper; - - /* - * Target listener for binder callbacks - */ - private MountServiceBinderListener mBinderListener; - - /* - * *static* list of our listeners - */ - static final ArrayList<ListenerDelegate> sListeners = new ArrayList<ListenerDelegate>(); - - private class MountServiceBinderListener extends IMountServiceListener.Stub { - public void onShareAvailabilityChanged(String method, boolean available) { - final int size = sListeners.size(); - for (int i = 0; i < size; i++) { - sListeners.get(i).sendShareAvailabilityChanged(method, available); - } - } - - public void onMediaInserted(String label, String path, int major, int minor) { - final int size = sListeners.size(); - for (int i = 0; i < size; i++) { - sListeners.get(i).sendMediaInserted(label, path, major, minor); - } - } - - public void onMediaRemoved(String label, String path, int major, int minor, boolean clean) { - final int size = sListeners.size(); - for (int i = 0; i < size; i++) { - sListeners.get(i).sendMediaRemoved(label, path, major, minor, clean); - } - } - - public void onVolumeStateChanged(String label, String path, String oldState, String newState) { - final int size = sListeners.size(); - for (int i = 0; i < size; i++) { - sListeners.get(i).sendVolumeStateChanged(label, path, oldState, newState); - } - } - } - - /** - * Private base class for messages sent between the callback thread - * and the target looper handler - */ - private class StorageEvent { - public static final int EVENT_SHARE_AVAILABILITY_CHANGED = 1; - public static final int EVENT_MEDIA_INSERTED = 2; - public static final int EVENT_MEDIA_REMOVED = 3; - public static final int EVENT_VOLUME_STATE_CHANGED = 4; - - private Message mMessage; - - public StorageEvent(int what) { - mMessage = Message.obtain(); - mMessage.what = what; - mMessage.obj = this; - } - - public Message getMessage() { - return mMessage; - } - } - - /** - * Message sent on a share availability change. - */ - private class ShareAvailabilityChangedStorageEvent extends StorageEvent { - public String method; - public boolean available; - - public ShareAvailabilityChangedStorageEvent(String m, boolean a) { - super(EVENT_SHARE_AVAILABILITY_CHANGED); - method = m; - available = a; - } - } - - /** - * Message sent on media insertion - */ - private class MediaInsertedStorageEvent extends StorageEvent { - public String label; - public String path; - public int major; - public int minor; - - public MediaInsertedStorageEvent(String l, String p, int maj, int min) { - super(EVENT_MEDIA_INSERTED); - label = l; - path = p; - major = maj; - minor = min; - } - } - - /** - * Message sent on media removal - */ - private class MediaRemovedStorageEvent extends StorageEvent { - public String label; - public String path; - public int major; - public int minor; - public boolean clean; - - public MediaRemovedStorageEvent(String l, String p, int maj, int min, boolean c) { - super(EVENT_MEDIA_REMOVED); - label = l; - path = p; - major = maj; - minor = min; - clean = c; - } - } - - /** - * Message sent on volume state change - */ - private class VolumeStateChangedStorageEvent extends StorageEvent { - public String label; - public String path; - public String oldState; - public String newState; - - public VolumeStateChangedStorageEvent(String l, String p, String oldS, String newS) { - super(EVENT_VOLUME_STATE_CHANGED); - label = l; - path = p; - oldState = oldS; - newState = newS; - } - } - - /** - * Private class containing sender and receiver code for StorageEvents - */ - private class ListenerDelegate { - final StorageEventListener mStorageEventListener; - private final Handler mHandler; - - ListenerDelegate(StorageEventListener listener) { - mStorageEventListener = listener; - mHandler = new Handler(mTgtLooper) { - @Override - public void handleMessage(Message msg) { - StorageEvent e = (StorageEvent) msg.obj; - - if (msg.what == StorageEvent.EVENT_SHARE_AVAILABILITY_CHANGED) { - ShareAvailabilityChangedStorageEvent ev = (ShareAvailabilityChangedStorageEvent) e; - mStorageEventListener.onShareAvailabilityChanged(ev.method, ev.available); - } else if (msg.what == StorageEvent.EVENT_MEDIA_INSERTED) { - MediaInsertedStorageEvent ev = (MediaInsertedStorageEvent) e; - mStorageEventListener.onMediaInserted(ev.label, ev.path, ev.major, ev.minor); - } else if (msg.what == StorageEvent.EVENT_MEDIA_REMOVED) { - MediaRemovedStorageEvent ev = (MediaRemovedStorageEvent) e; - mStorageEventListener.onMediaRemoved(ev.label, ev.path, ev.major, ev.minor, ev.clean); - } else if (msg.what == StorageEvent.EVENT_VOLUME_STATE_CHANGED) { - VolumeStateChangedStorageEvent ev = (VolumeStateChangedStorageEvent) e; - mStorageEventListener.onVolumeStateChanged(ev.label, ev.path, ev.oldState, ev.newState); - } else { - Log.e(TAG, "Unsupported event " + msg.what); - } - } - }; - } - - StorageEventListener getListener() { - return mStorageEventListener; - } - - void sendShareAvailabilityChanged(String method, boolean available) { - ShareAvailabilityChangedStorageEvent e = new ShareAvailabilityChangedStorageEvent(method, available); - mHandler.sendMessage(e.getMessage()); - } - - void sendMediaInserted(String label, String path, int major, int minor) { - MediaInsertedStorageEvent e = new MediaInsertedStorageEvent(label, path, major, minor); - mHandler.sendMessage(e.getMessage()); - } - - void sendMediaRemoved(String label, String path, int major, int minor, boolean clean) { - MediaRemovedStorageEvent e = new MediaRemovedStorageEvent(label, path, major, minor, clean); - mHandler.sendMessage(e.getMessage()); - } - - void sendVolumeStateChanged(String label, String path, String oldState, String newState) { - VolumeStateChangedStorageEvent e = new VolumeStateChangedStorageEvent(label, path, oldState, newState); - mHandler.sendMessage(e.getMessage()); - } - } - - /** - * {@hide} - */ - public StorageManager(Looper tgtLooper) throws RemoteException { - mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); - if (mMountService == null) { - Log.e(TAG, "Unable to connect to mount service! - is it running yet?"); - return; - } - mTgtLooper = tgtLooper; - mBinderListener = new MountServiceBinderListener(); - mMountService.registerListener(mBinderListener); - } - - - /** - * Registers a {@link android.storage.StorageEventListener StorageEventListener}. - * - * @param listener A {@link android.storage.StorageEventListener StorageEventListener} object. - * - */ - public void registerListener(StorageEventListener listener) { - if (listener == null) { - return; - } - - synchronized (sListeners) { - sListeners.add(new ListenerDelegate(listener)); - } - } - - /** - * Unregisters a {@link android.storage.StorageEventListener StorageEventListener}. - * - * @param listener A {@link android.storage.StorageEventListener StorageEventListener} object. - * - */ - public void unregisterListener(StorageEventListener listener) { - if (listener == null) { - return; - } - synchronized (sListeners) { - final int size = sListeners.size(); - for (int i=0 ; i<size ; i++) { - ListenerDelegate l = sListeners.get(i); - if (l.getListener() == listener) { - sListeners.remove(i); - break; - } - } - } - } -} diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java index 2b07ae6..7e9bbd1 100644 --- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java +++ b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java @@ -24,7 +24,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; -import android.os.IMountService; +import android.os.storage.IMountService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java index 98fb236..24818a8 100755 --- a/core/java/com/android/internal/app/NetInitiatedActivity.java +++ b/core/java/com/android/internal/app/NetInitiatedActivity.java @@ -24,7 +24,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; -import android.os.IMountService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java index c110f95..2f48499 100644 --- a/core/java/com/android/internal/app/ShutdownThread.java +++ b/core/java/com/android/internal/app/ShutdownThread.java @@ -32,7 +32,7 @@ import android.os.RemoteException; import android.os.Power; import android.os.ServiceManager; import android.os.SystemClock; -import android.os.IMountService; +import android.os.storage.IMountService; import com.android.internal.telephony.ITelephony; import android.util.Log; diff --git a/core/java/com/android/internal/app/StorageNotification.java b/core/java/com/android/internal/app/StorageNotification.java index 27967fc..8876612 100644 --- a/core/java/com/android/internal/app/StorageNotification.java +++ b/core/java/com/android/internal/app/StorageNotification.java @@ -30,12 +30,12 @@ import android.content.res.Resources; import android.os.Bundle; import android.os.Environment; import android.os.Handler; -import android.os.IMountService; +import android.os.storage.IMountService; import android.os.Message; -import android.os.MountServiceResultCode; import android.os.ServiceManager; -import android.storage.StorageEventListener; -import android.storage.StorageManager; +import android.os.storage.StorageEventListener; +import android.os.storage.StorageManager; +import android.os.storage.StorageResultCode; import android.util.Log; import android.view.View; import android.widget.Button; @@ -43,7 +43,7 @@ import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; -public class StorageNotification implements StorageEventListener { +public class StorageNotification extends StorageEventListener { private static final String TAG = "StorageNotification"; /** @@ -69,72 +69,55 @@ public class StorageNotification implements StorageEventListener { * <p> * This is lazily created, so use {@link #setMediaStorageNotification()}. */ - private Notification mMediaStorageNotification; - - private boolean mShowSafeUnmountNotificationWhenUnmounted; - private boolean mUmsAvailable; - private IMountService mMountService; // XXX: This should go away soon + private Notification mMediaStorageNotification; + private boolean mUmsAvailable; + private StorageManager mStorageManager; public StorageNotification(Context context) { mContext = context; - /* - * XXX: This needs to be exposed via StorageManager - */ - mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); - try { - mUmsAvailable = mMountService.getShareMethodAvailable("ums"); - } catch (Exception e) { - Log.e(TAG, "Failed to get ums availability", e); - } - } - - public void onShareAvailabilityChanged(String method, boolean available) { - if (method.equals("ums")) { - mUmsAvailable = available; - /* - * Even though we may have a UMS host connected, we the SD card - * may not be in a state for export. - */ - String st = Environment.getExternalStorageState(); - if (available && (st.equals( - Environment.MEDIA_REMOVED) || st.equals(Environment.MEDIA_CHECKING))) { - /* - * No card or card being checked = don't display - */ - available = false; - } - - updateUsbMassStorageNotification(available); - } - } - - public void onMediaInserted(String label, String path, int major, int minor) { + mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); + mUmsAvailable = mStorageManager.isUsbMassStorageConnected(); + Log.d(TAG, String.format( "Startup with UMS connection %s (media state %s)", mUmsAvailable, + Environment.getExternalStorageState())); } - public void onMediaRemoved(String label, String path, int major, int minor, boolean clean) { + /* + * @override com.android.os.storage.StorageEventListener + */ + @Override + public void onUsbMassStorageConnectionChanged(boolean connected) { + mUmsAvailable = connected; /* - * Media removed - first clear the USB storage notification (if any) + * Even though we may have a UMS host connected, we the SD card + * may not be in a state for export. */ - updateUsbMassStorageNotification(false); + String st = Environment.getExternalStorageState(); - if (clean) { - setMediaStorageNotification( - com.android.internal.R.string.ext_media_nomedia_notification_title, - com.android.internal.R.string.ext_media_nomedia_notification_message, - com.android.internal.R.drawable.stat_notify_sdcard_usb, - true, false, null); - } else { - setMediaStorageNotification( - com.android.internal.R.string.ext_media_badremoval_notification_title, - com.android.internal.R.string.ext_media_badremoval_notification_message, - com.android.internal.R.drawable.stat_sys_warning, - true, true, null); + Log.i(TAG, String.format("UMS connection changed to %s (media state %s)", connected, st)); + + if (connected && (st.equals( + Environment.MEDIA_REMOVED) || st.equals(Environment.MEDIA_CHECKING))) { + /* + * No card or card being checked = don't display + */ + connected = false; } + updateUsbMassStorageNotification(connected); } - public void onVolumeStateChanged(String label, String path, String oldState, String newState) { + /* + * @override com.android.os.storage.StorageEventListener + */ + @Override + public void onStorageStateChanged(String path, String oldState, String newState) { + Log.i(TAG, String.format( + "Media {%s} state changed from {%s} -> {%s}", path, oldState, newState)); if (newState.equals(Environment.MEDIA_SHARED)) { + /* + * Storage is now shared. Modify the UMS notification + * for stopping UMS. + */ Intent intent = new Intent(); intent.setClass(mContext, com.android.internal.app.UsbStorageActivity.class); PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); @@ -143,26 +126,60 @@ public class StorageNotification implements StorageEventListener { com.android.internal.R.string.usb_storage_stop_notification_message, com.android.internal.R.drawable.stat_sys_warning, false, true, pi); } else if (newState.equals(Environment.MEDIA_CHECKING)) { + /* + * Storage is now checking. Update media notification and disable + * UMS notification. + */ setMediaStorageNotification( com.android.internal.R.string.ext_media_checking_notification_title, com.android.internal.R.string.ext_media_checking_notification_message, com.android.internal.R.drawable.stat_notify_sdcard_prepare, true, false, null); updateUsbMassStorageNotification(false); } else if (newState.equals(Environment.MEDIA_MOUNTED)) { + /* + * Storage is now mounted. Dismiss any media notifications, + * and enable UMS notification if connected. + */ setMediaStorageNotification(0, 0, 0, false, false, null); updateUsbMassStorageNotification(mUmsAvailable); } else if (newState.equals(Environment.MEDIA_UNMOUNTED)) { - if (mShowSafeUnmountNotificationWhenUnmounted) { - setMediaStorageNotification( - com.android.internal.R.string.ext_media_safe_unmount_notification_title, - com.android.internal.R.string.ext_media_safe_unmount_notification_message, - com.android.internal.R.drawable.stat_notify_sdcard, true, true, null); - mShowSafeUnmountNotificationWhenUnmounted = false; + /* + * Storage is now unmounted. We may have been unmounted + * because the user is enabling/disabling UMS, in which case we don't + * want to display the 'safe to unmount' notification. + */ + if (!mStorageManager.isUsbMassStorageEnabled()) { + if (oldState.equals(Environment.MEDIA_SHARED)) { + /* + * The unmount was due to UMS being enabled. Dismiss any + * media notifications, and enable UMS notification if connected + */ + setMediaStorageNotification(0, 0, 0, false, false, null); + updateUsbMassStorageNotification(mUmsAvailable); + } else { + /* + * Show safe to unmount media notification, and enable UMS + * notification if connected. + */ + setMediaStorageNotification( + com.android.internal.R.string.ext_media_safe_unmount_notification_title, + com.android.internal.R.string.ext_media_safe_unmount_notification_message, + com.android.internal.R.drawable.stat_notify_sdcard, true, true, null); + updateUsbMassStorageNotification(mUmsAvailable); + } } else { + /* + * The unmount was due to UMS being enabled. Dismiss any + * media notifications, and disable the UMS notification + */ setMediaStorageNotification(0, 0, 0, false, false, null); + updateUsbMassStorageNotification(false); } - updateUsbMassStorageNotification(mUmsAvailable); } else if (newState.equals(Environment.MEDIA_NOFS)) { + /* + * Storage has no filesystem. Show blank media notification, + * and enable UMS notification if connected. + */ Intent intent = new Intent(); intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class); PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); @@ -173,6 +190,10 @@ public class StorageNotification implements StorageEventListener { com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi); updateUsbMassStorageNotification(mUmsAvailable); } else if (newState.equals(Environment.MEDIA_UNMOUNTABLE)) { + /* + * Storage is corrupt. Show corrupt media notification, + * and enable UMS notification if connected. + */ Intent intent = new Intent(); intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class); PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); @@ -182,6 +203,30 @@ public class StorageNotification implements StorageEventListener { com.android.internal.R.string.ext_media_unmountable_notification_message, com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi); updateUsbMassStorageNotification(mUmsAvailable); + } else if (newState.equals(Environment.MEDIA_REMOVED)) { + /* + * Storage has been removed. Show nomedia media notification, + * and disable UMS notification regardless of connection state. + */ + setMediaStorageNotification( + com.android.internal.R.string.ext_media_nomedia_notification_title, + com.android.internal.R.string.ext_media_nomedia_notification_message, + com.android.internal.R.drawable.stat_notify_sdcard_usb, + true, false, null); + updateUsbMassStorageNotification(false); + } else if (newState.equals(Environment.MEDIA_BAD_REMOVAL)) { + /* + * Storage has been removed unsafely. Show bad removal media notification, + * and disable UMS notification regardless of connection state. + */ + setMediaStorageNotification( + com.android.internal.R.string.ext_media_badremoval_notification_title, + com.android.internal.R.string.ext_media_badremoval_notification_message, + com.android.internal.R.drawable.stat_sys_warning, + true, true, null); + updateUsbMassStorageNotification(false); + } else { + Log.w(TAG, String.format("Ignoring unknown state {%s}", newState)); } } diff --git a/core/java/com/android/internal/app/TetherActivity.java b/core/java/com/android/internal/app/TetherActivity.java index 2b93dbc..cb268b3 100644 --- a/core/java/com/android/internal/app/TetherActivity.java +++ b/core/java/com/android/internal/app/TetherActivity.java @@ -25,7 +25,6 @@ import android.content.IntentFilter; import android.net.ConnectivityManager; import android.os.Bundle; import android.os.Handler; -import android.os.IMountService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/core/java/com/android/internal/app/UsbStorageActivity.java b/core/java/com/android/internal/app/UsbStorageActivity.java index 34ae2b4..991f04b 100644 --- a/core/java/com/android/internal/app/UsbStorageActivity.java +++ b/core/java/com/android/internal/app/UsbStorageActivity.java @@ -25,8 +25,9 @@ import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; import android.os.Environment; -import android.os.IMountService; -import android.os.MountServiceResultCode; +import android.os.storage.StorageManager; +import android.os.storage.StorageEventListener; +import android.os.storage.StorageResultCode; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; @@ -35,6 +36,7 @@ import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import android.view.View; +import android.util.Log; /** * This activity is shown to the user for him/her to enable USB mass storage @@ -42,11 +44,13 @@ import android.view.View; * dialog style. It will be launched from a notification. */ public class UsbStorageActivity extends Activity { + private static final String TAG = "UsbStorageActivity"; private Button mMountButton; private Button mUnmountButton; private TextView mBanner; private TextView mMessage; private ImageView mIcon; + private StorageManager mStorageManager = null; /** Used to detect when the USB cable is unplugged, so we can call finish() */ private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() { @@ -57,11 +61,30 @@ public class UsbStorageActivity extends Activity { } } }; + + private StorageEventListener mStorageListener = new StorageEventListener() { + @Override + public void onStorageStateChanged(String path, String oldState, String newState) { + if (newState.equals(Environment.MEDIA_SHARED)) { + switchDisplay(true); + } else { + switchDisplay(false); + } + } + }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (mStorageManager == null) { + mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE); + if (mStorageManager == null) { + Log.w(TAG, "Failed to get StorageManager"); + } + mStorageManager.registerListener(mStorageListener); + } + setTitle(getString(com.android.internal.R.string.usb_storage_activity_title)); setContentView(com.android.internal.R.layout.usb_storage_activity); @@ -74,9 +97,11 @@ public class UsbStorageActivity extends Activity { mMountButton.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { - mountAsUsbStorage(); - // TODO: replace with forthcoming MountService callbacks - switchDisplay(true); + int rc = mStorageManager.enableUsbMassStorage(); + if (rc != StorageResultCode.OperationSucceeded) { + Log.e(TAG, String.format("UMS enable failed (%d)", rc)); + showSharingError(); + } } }); @@ -84,9 +109,11 @@ public class UsbStorageActivity extends Activity { mUnmountButton.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { - stopUsbStorage(); - // TODO: replace with forthcoming MountService callbacks - switchDisplay(false); + int rc = mStorageManager.disableUsbMassStorage(); + if (rc != StorageResultCode.OperationSucceeded) { + Log.e(TAG, String.format("UMS disable failed (%d)", rc)); + showStoppingError(); + } } }); } @@ -112,19 +139,11 @@ public class UsbStorageActivity extends Activity { super.onResume(); registerReceiver(mBatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - - boolean umsOn = false; try { - IMountService mountService = IMountService.Stub.asInterface(ServiceManager - .getService("mount")); - if (mountService != null) { - umsOn = mountService.getVolumeShared( - Environment.getExternalStorageDirectory().getPath(), "ums"); - } - } catch (android.os.RemoteException exc) { - // pass + switchDisplay(mStorageManager.isUsbMassStorageEnabled()); + } catch (Exception ex) { + Log.e(TAG, "Failed to read UMS enable state", ex); } - switchDisplay(umsOn); } @Override @@ -134,42 +153,6 @@ public class UsbStorageActivity extends Activity { unregisterReceiver(mBatteryReceiver); } - private void mountAsUsbStorage() { - IMountService mountService = IMountService.Stub.asInterface(ServiceManager - .getService("mount")); - if (mountService == null) { - showSharingError(); - return; - } - - try { - if (mountService.shareVolume( - Environment.getExternalStorageDirectory().getPath(), "ums") != - MountServiceResultCode.OperationSucceeded) { - showSharingError(); - } - } catch (RemoteException e) { - showSharingError(); - } - } - - private void stopUsbStorage() { - IMountService mountService = IMountService.Stub.asInterface(ServiceManager - .getService("mount")); - if (mountService == null) { - showStoppingError(); - return; - } - - try { - mountService.unshareVolume( - Environment.getExternalStorageDirectory().getPath(), "ums"); - } catch (RemoteException e) { - showStoppingError(); - return; - } - } - private void handleBatteryChanged(Intent intent) { int pluggedType = intent.getIntExtra("plugged", 0); if (pluggedType == 0) { |
