diff options
28 files changed, 955 insertions, 925 deletions
@@ -111,8 +111,8 @@ LOCAL_SRC_FILES += \ core/java/android/net/INetworkManagementEventObserver.aidl \ core/java/android/os/ICheckinService.aidl \ core/java/android/os/IMessenger.aidl \ - core/java/android/os/IMountService.aidl \ - core/java/android/os/IMountServiceListener.aidl \ + core/java/android/os/storage/IMountService.aidl \ + core/java/android/os/storage/IMountServiceListener.aidl \ core/java/android/os/INetworkManagementService.aidl \ core/java/android/os/INetStatService.aidl \ core/java/android/os/IParentalControlCallback.aidl \ diff --git a/api/current.xml b/api/current.xml index e673f0f..b155c45 100644 --- a/api/current.xml +++ b/api/current.xml @@ -117646,6 +117646,218 @@ </method> </class> </package> +<package name="android.os.storage" +> +<class name="StorageEventListener" + extends="java.lang.Object" + abstract="true" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="StorageEventListener" + type="android.os.storage.StorageEventListener" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="onStorageStateChanged" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="path" type="java.lang.String"> +</parameter> +<parameter name="oldState" type="java.lang.String"> +</parameter> +<parameter name="newState" type="java.lang.String"> +</parameter> +</method> +<method name="onUsbMassStorageConnectionChanged" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="connected" type="boolean"> +</parameter> +</method> +</class> +<class name="StorageManager" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="disableUsbMassStorage" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="enableUsbMassStorage" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="isUsbMassStorageConnected" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="isUsbMassStorageEnabled" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="registerListener" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="listener" type="android.os.storage.StorageEventListener"> +</parameter> +</method> +<method name="unregisterListener" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="listener" type="android.os.storage.StorageEventListener"> +</parameter> +</method> +</class> +<class name="StorageResultCode" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="StorageResultCode" + type="android.os.storage.StorageResultCode" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<field name="OperationFailedInternalError" + type="int" + transient="false" + volatile="false" + value="-1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OperationFailedMediaBlank" + type="int" + transient="false" + volatile="false" + value="-3" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OperationFailedMediaCorrupt" + type="int" + transient="false" + volatile="false" + value="-4" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OperationFailedNoMedia" + type="int" + transient="false" + volatile="false" + value="-2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OperationFailedVolumeNotMounted" + type="int" + transient="false" + volatile="false" + value="-5" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OperationSucceeded" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +</class> +</package> <package name="android.preference" > <class name="CheckBoxPreference" @@ -136301,126 +136513,6 @@ </method> </interface> </package> -<package name="android.storage" -> -<interface name="StorageEventListener" - abstract="true" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<method name="onMediaInserted" - return="void" - abstract="true" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="label" type="java.lang.String"> -</parameter> -<parameter name="path" type="java.lang.String"> -</parameter> -<parameter name="major" type="int"> -</parameter> -<parameter name="minor" type="int"> -</parameter> -</method> -<method name="onMediaRemoved" - return="void" - abstract="true" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="label" type="java.lang.String"> -</parameter> -<parameter name="path" type="java.lang.String"> -</parameter> -<parameter name="major" type="int"> -</parameter> -<parameter name="minor" type="int"> -</parameter> -<parameter name="clean" type="boolean"> -</parameter> -</method> -<method name="onShareAvailabilityChanged" - return="void" - abstract="true" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="method" type="java.lang.String"> -</parameter> -<parameter name="available" type="boolean"> -</parameter> -</method> -<method name="onVolumeStateChanged" - return="void" - abstract="true" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="label" type="java.lang.String"> -</parameter> -<parameter name="path" type="java.lang.String"> -</parameter> -<parameter name="oldState" type="java.lang.String"> -</parameter> -<parameter name="newState" type="java.lang.String"> -</parameter> -</method> -</interface> -<class name="StorageManager" - extends="java.lang.Object" - abstract="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<method name="registerListener" - return="void" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="listener" type="android.storage.StorageEventListener"> -</parameter> -</method> -<method name="unregisterListener" - return="void" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="listener" type="android.storage.StorageEventListener"> -</parameter> -</method> -</class> -</package> <package name="android.telephony" > <class name="CellLocation" 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) { diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index d23b7d0..fecd366 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -6,8 +6,8 @@ import android.content.Intent; import android.net.Uri; import android.os.Debug; import android.os.IBinder; -import android.os.IMountService; -import android.os.MountServiceResultCode; +import android.os.storage.IMountService; +import android.os.storage.StorageResultCode; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; @@ -158,12 +158,12 @@ public class DefaultContainerService extends Service { int rc = mountService.createSecureContainer( containerId, mbLen, "vfat", sdEncKey, ownerUid); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Container creation failed (%d)", rc)); // XXX: This destroy should not be necessary rc = mountService.destroySecureContainer(containerId); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Container creation-cleanup failed (%d)", rc)); return null; } @@ -171,7 +171,7 @@ public class DefaultContainerService extends Service { // XXX: Does this ever actually succeed? rc = mountService.createSecureContainer( containerId, mbLen, "vfat", sdEncKey, ownerUid); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Container creation retry failed (%d)", rc)); } } @@ -226,7 +226,7 @@ public class DefaultContainerService extends Service { private String mountSdDir(String containerId, String key) { try { int rc = getMountService().mountSecureContainer(containerId, key, Process.myUid()); - if (rc == MountServiceResultCode.OperationSucceeded) { + if (rc == StorageResultCode.OperationSucceeded) { return getMountService().getSecureContainerPath(containerId); } else { Log.e(TAG, String.format("Failed to mount id %s with rc %d ", containerId, rc)); diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 0e44858..6de2eff 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -23,9 +23,9 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; -import android.os.IMountService; -import android.os.IMountServiceListener; -import android.os.MountServiceResultCode; +import android.os.storage.IMountService; +import android.os.storage.IMountServiceListener; +import android.os.storage.StorageResultCode; import android.os.RemoteException; import android.os.IBinder; import android.os.Environment; @@ -42,11 +42,14 @@ import java.io.File; import java.io.FileReader; /** - * MountService implements an to the mount service daemon - * @hide + * MountService implements back-end services for platform storage + * management. + * @hide - Applications should use android.os.storage.StorageManager + * to access the MountService. */ class MountService extends IMountService.Stub implements INativeDaemonConnectorCallbacks { + private static final boolean LOCAL_LOGD = false; private static final String TAG = "MountService"; @@ -135,7 +138,7 @@ class MountService extends IMountService.Stub String path = Environment.getExternalStorageDirectory().getPath(); if (getVolumeState(path).equals(Environment.MEDIA_UNMOUNTED)) { int rc = doMountVolume(path); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Boot-time mount failed (%d)", rc)); } } @@ -152,7 +155,7 @@ class MountService extends IMountService.Stub } public void binderDied() { - Log.d(TAG, "An IMountServiceListener has died!"); + if (LOCAL_LOGD) Log.d(TAG, "An IMountServiceListener has died!"); synchronized(mListeners) { mListeners.remove(this); mListener.asBinder().unlinkToDeath(this, 0); @@ -173,9 +176,9 @@ class MountService extends IMountService.Stub */ String vs = getVolumeState(path); if (enable && vs.equals(Environment.MEDIA_MOUNTED)) { - mUmsEnabling = enable; // Supress unmounted events + mUmsEnabling = enable; // Override for isUsbMassStorageEnabled() doUnmountVolume(path); - mUmsEnabling = false; // Unsupress unmounted events + mUmsEnabling = false; // Clear override } try { @@ -183,14 +186,14 @@ class MountService extends IMountService.Stub "volume %sshare %s %s", (enable ? "" : "un"), path, method)); } catch (NativeDaemonConnectorException e) { Log.e(TAG, "Failed to share/unshare", e); - return MountServiceResultCode.OperationFailedInternalError; + return StorageResultCode.OperationFailedInternalError; } /* * If we disabled UMS then mount the volume */ if (!enable) { - if (doMountVolume(path) != MountServiceResultCode.OperationSucceeded) { + if (doMountVolume(path) != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format( "Failed to remount %s after disabling share method %s", path, method)); /* @@ -201,7 +204,7 @@ class MountService extends IMountService.Stub } } - return MountServiceResultCode.OperationSucceeded; + return StorageResultCode.OperationSucceeded; } private void updatePublicVolumeState(String path, String state) { @@ -209,7 +212,11 @@ class MountService extends IMountService.Stub Log.w(TAG, "Multiple volumes not currently supported"); return; } - Log.i(TAG, "State for {" + path + "} = {" + state + "}"); + + if (mLegacyState.equals(state)) { + Log.w(TAG, String.format("Duplicate state transition (%s -> %s)", mLegacyState, state)); + return; + } String oldState = mLegacyState; mLegacyState = state; @@ -218,7 +225,7 @@ class MountService extends IMountService.Stub for (int i = mListeners.size() -1; i >= 0; i--) { MountServiceBinderListener bl = mListeners.get(i); try { - bl.mListener.onVolumeStateChanged("", path, oldState, state); + bl.mListener.onStorageStateChanged(path, oldState, state); } catch (RemoteException rex) { Log.e(TAG, "Listener dead"); mListeners.remove(i); @@ -296,13 +303,11 @@ class MountService extends IMountService.Stub } /** - * * Callback from NativeDaemonConnector */ public boolean onEvent(int code, String raw, String[] cooked) { Intent in = null; - // Log.d(TAG, "event {" + raw + "}"); if (code == VoldResponseCode.VolumeStateChange) { /* * One of the volumes we're managing has changed state. @@ -339,34 +344,12 @@ class MountService extends IMountService.Stub Log.e(TAG, "Failed to parse major/minor", ex); } - synchronized (mListeners) { - for (int i = mListeners.size() -1; i >= 0; i--) { - MountServiceBinderListener bl = mListeners.get(i); - try { - if (code == VoldResponseCode.VolumeDiskInserted) { - bl.mListener.onMediaInserted(label, path, major, minor); - } else if (code == VoldResponseCode.VolumeDiskRemoved) { - bl.mListener.onMediaRemoved(label, path, major, minor, true); - } else if (code == VoldResponseCode.VolumeBadRemoval) { - bl.mListener.onMediaRemoved(label, path, major, minor, false); - } else { - Log.e(TAG, String.format("Unknown code {%d}", code)); - } - } catch (RemoteException rex) { - Log.e(TAG, "Listener dead"); - mListeners.remove(i); - } catch (Exception ex) { - Log.e(TAG, "Listener failed", ex); - } - } - } - if (code == VoldResponseCode.VolumeDiskInserted) { new Thread() { public void run() { try { int rc; - if ((rc = doMountVolume(path)) != MountServiceResultCode.OperationSucceeded) { + if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) { Log.w(TAG, String.format("Insertion mount failed (%d)", rc)); } } catch (Exception ex) { @@ -489,7 +472,7 @@ class MountService extends IMountService.Stub } private int doMountVolume(String path) { - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; try { mConnector.doCommand(String.format("volume mount %s", path)); @@ -503,23 +486,23 @@ class MountService extends IMountService.Stub /* * Attempt to mount but no media inserted */ - rc = MountServiceResultCode.OperationFailedNoMedia; + rc = StorageResultCode.OperationFailedNoMedia; } else if (code == VoldResponseCode.OpFailedMediaBlank) { /* * Media is blank or does not contain a supported filesystem */ updatePublicVolumeState(path, Environment.MEDIA_NOFS); in = new Intent(Intent.ACTION_MEDIA_NOFS, Uri.parse("file://" + path)); - rc = MountServiceResultCode.OperationFailedMediaBlank; + rc = StorageResultCode.OperationFailedMediaBlank; } else if (code == VoldResponseCode.OpFailedMediaCorrupt) { /* * Volume consistency check failed */ updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTABLE); in = new Intent(Intent.ACTION_MEDIA_UNMOUNTABLE, Uri.parse("file://" + path)); - rc = MountServiceResultCode.OperationFailedMediaCorrupt; + rc = StorageResultCode.OperationFailedMediaCorrupt; } else { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } /* @@ -544,15 +527,15 @@ class MountService extends IMountService.Stub mPms.updateExternalMediaStatus(false); try { mConnector.doCommand(String.format("volume unmount %s", path)); - return MountServiceResultCode.OperationSucceeded; + return StorageResultCode.OperationSucceeded; } catch (NativeDaemonConnectorException e) { // Don't worry about mismatch in PackageManager since the // call back will handle the status changes any way. int code = e.getCode(); if (code == VoldResponseCode.OpFailedVolNotMounted) { - return MountServiceResultCode.OperationFailedVolumeNotMounted; + return StorageResultCode.OperationFailedVolumeNotMounted; } else { - return MountServiceResultCode.OperationFailedInternalError; + return StorageResultCode.OperationFailedInternalError; } } } @@ -561,19 +544,45 @@ class MountService extends IMountService.Stub try { String cmd = String.format("volume format %s", path); mConnector.doCommand(cmd); - return MountServiceResultCode.OperationSucceeded; + return StorageResultCode.OperationSucceeded; } catch (NativeDaemonConnectorException e) { int code = e.getCode(); if (code == VoldResponseCode.OpFailedNoMedia) { - return MountServiceResultCode.OperationFailedNoMedia; + return StorageResultCode.OperationFailedNoMedia; } else if (code == VoldResponseCode.OpFailedMediaCorrupt) { - return MountServiceResultCode.OperationFailedMediaCorrupt; + return StorageResultCode.OperationFailedMediaCorrupt; } else { - return MountServiceResultCode.OperationFailedInternalError; + return StorageResultCode.OperationFailedInternalError; } } } + private boolean doGetVolumeShared(String path, String method) { + String cmd = String.format("volume shared %s %s", path, method); + ArrayList<String> rsp = mConnector.doCommand(cmd); + + for (String line : rsp) { + String []tok = line.split(" "); + int code; + try { + code = Integer.parseInt(tok[0]); + } catch (NumberFormatException nfe) { + Log.e(TAG, String.format("Error parsing code %s", tok[0])); + return false; + } + if (code == VoldResponseCode.ShareEnabledResult) { + if (tok[2].equals("enabled")) + return true; + return false; + } else { + Log.e(TAG, String.format("Unexpected response code %d", code)); + return false; + } + } + Log.e(TAG, "Got an empty response"); + return false; + } + private void notifyShareAvailabilityChange(String method, final boolean avail) { if (!method.equals("ums")) { Log.w(TAG, "Ignoring unsupported share method {" + method + "}"); @@ -584,7 +593,7 @@ class MountService extends IMountService.Stub for (int i = mListeners.size() -1; i >= 0; i--) { MountServiceBinderListener bl = mListeners.get(i); try { - bl.mListener.onShareAvailabilityChanged(method, avail); + bl.mListener.onUsbMassStorageConnectionChanged(avail); } catch (RemoteException rex) { Log.e(TAG, "Listener dead"); mListeners.remove(i); @@ -685,7 +694,7 @@ class MountService extends IMountService.Stub * the UMS host could have dirty FAT cache entries * yet to flush. */ - if (unshareVolume(path, "ums") != MountServiceResultCode.OperationSucceeded) { + if (setUsbMassStorageEnabled(false) != StorageResultCode.OperationSucceeded) { Log.e(TAG, "UMS disable on shutdown failed"); } } else if (state.equals(Environment.MEDIA_CHECKING)) { @@ -713,58 +722,30 @@ class MountService extends IMountService.Stub /* * If the media is mounted, then gracefully unmount it. */ - if (doUnmountVolume(path) != MountServiceResultCode.OperationSucceeded) { + if (doUnmountVolume(path) != StorageResultCode.OperationSucceeded) { Log.e(TAG, "Failed to unmount media for shutdown"); } } } - public String[] getShareMethodList() { - String[] rdata = new String[1]; - rdata[0] = "ums"; - return rdata; - } - - public boolean getShareMethodAvailable(String method) { + public boolean isUsbMassStorageConnected() { waitForReady(); - return doGetShareMethodAvailable(method); - } - public int shareVolume(String path, String method) { - waitForReady(); - return doShareUnshareVolume(path, method, true); + if (mUmsEnabling) { + return true; + } + return doGetShareMethodAvailable("ums"); } - public int unshareVolume(String path, String method) { + public int setUsbMassStorageEnabled(boolean enable) { waitForReady(); - return doShareUnshareVolume(path, method, false); + + return doShareUnshareVolume(Environment.getExternalStorageDirectory().getPath(), "ums", enable); } - public boolean getVolumeShared(String path, String method) { + public boolean isUsbMassStorageEnabled() { waitForReady(); - String cmd = String.format("volume shared %s %s", path, method); - ArrayList<String> rsp = mConnector.doCommand(cmd); - - for (String line : rsp) { - String []tok = line.split(" "); - int code; - try { - code = Integer.parseInt(tok[0]); - } catch (NumberFormatException nfe) { - Log.e(TAG, String.format("Error parsing code %s", tok[0])); - return false; - } - if (code == VoldResponseCode.ShareEnabledResult) { - if (tok[2].equals("enabled")) - return true; - return false; - } else { - Log.e(TAG, String.format("Unexpected response code %d", code)); - return false; - } - } - Log.e(TAG, "Got an empty response"); - return false; + return doGetVolumeShared(Environment.getExternalStorageDirectory().getPath(), "ums"); } /** @@ -804,12 +785,16 @@ class MountService extends IMountService.Stub return doFormatVolume(path); } + private void warnOnNotMounted() { + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + Log.w(TAG, "getSecureContainerList() called when storage not mounted"); + } + } + public String[] getSecureContainerList() { validatePermission(android.Manifest.permission.ASEC_ACCESS); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "getSecureContainerList() called when storage not mounted"); - } + warnOnNotMounted(); try { return mConnector.doListCommand("asec list", VoldResponseCode.AsecListResult); @@ -822,31 +807,27 @@ class MountService extends IMountService.Stub String key, int ownerUid) { validatePermission(android.Manifest.permission.ASEC_CREATE); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "createSecureContainer() called when storage not mounted"); - } + warnOnNotMounted(); - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; String cmd = String.format("asec create %s %d %s %s %d", id, sizeMb, fstype, key, ownerUid); try { mConnector.doCommand(cmd); } catch (NativeDaemonConnectorException e) { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } return rc; } public int finalizeSecureContainer(String id) { validatePermission(android.Manifest.permission.ASEC_CREATE); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "finalizeSecureContainer() called when storage not mounted"); - } + warnOnNotMounted(); - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; try { mConnector.doCommand(String.format("asec finalize %s", id)); } catch (NativeDaemonConnectorException e) { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } return rc; } @@ -854,15 +835,13 @@ class MountService extends IMountService.Stub public int destroySecureContainer(String id) { validatePermission(android.Manifest.permission.ASEC_DESTROY); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "destroySecureContainer() called when storage not mounted"); - } + warnOnNotMounted(); - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; try { mConnector.doCommand(String.format("asec destroy %s", id)); } catch (NativeDaemonConnectorException e) { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } return rc; } @@ -870,16 +849,14 @@ class MountService extends IMountService.Stub public int mountSecureContainer(String id, String key, int ownerUid) { validatePermission(android.Manifest.permission.ASEC_MOUNT_UNMOUNT); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "mountSecureContainer() called when storage not mounted"); - } + warnOnNotMounted(); - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; String cmd = String.format("asec mount %s %s %d", id, key, ownerUid); try { mConnector.doCommand(cmd); } catch (NativeDaemonConnectorException e) { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } return rc; } @@ -887,16 +864,14 @@ class MountService extends IMountService.Stub public int unmountSecureContainer(String id) { validatePermission(android.Manifest.permission.ASEC_MOUNT_UNMOUNT); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "unmountSecureContainer() called when storage not mounted"); - } + warnOnNotMounted(); - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; String cmd = String.format("asec unmount %s", id); try { mConnector.doCommand(cmd); } catch (NativeDaemonConnectorException e) { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } return rc; } @@ -904,16 +879,14 @@ class MountService extends IMountService.Stub public int renameSecureContainer(String oldId, String newId) { validatePermission(android.Manifest.permission.ASEC_RENAME); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "renameSecureContainer() called when storage not mounted"); - } + warnOnNotMounted(); - int rc = MountServiceResultCode.OperationSucceeded; + int rc = StorageResultCode.OperationSucceeded; String cmd = String.format("asec rename %s %s", oldId, newId); try { mConnector.doCommand(cmd); } catch (NativeDaemonConnectorException e) { - rc = MountServiceResultCode.OperationFailedInternalError; + rc = StorageResultCode.OperationFailedInternalError; } return rc; } @@ -921,9 +894,7 @@ class MountService extends IMountService.Stub public String getSecureContainerPath(String id) { validatePermission(android.Manifest.permission.ASEC_ACCESS); waitForReady(); - if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) { - Log.w(TAG, "getSecureContainerPath() called when storage not mounted"); - } + warnOnNotMounted(); ArrayList<String> rsp = mConnector.doCommand("asec path " + id); diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 80fd51f..ad8ab84 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -50,7 +50,7 @@ import android.os.Message; import android.os.Power; import android.os.Process; import android.os.RemoteException; -import android.storage.StorageManager; +import android.os.storage.StorageManager; import android.os.SystemProperties; import android.os.Vibrator; import android.provider.Settings; diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index f27ef8e..c99480f 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -74,7 +74,7 @@ import android.os.Environment; import android.os.FileObserver; import android.os.FileUtils; import android.os.Handler; -import android.os.MountServiceResultCode; +import android.os.storage.StorageResultCode; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.ServiceManager; @@ -8295,17 +8295,17 @@ class PackageManagerService extends IPackageManager.Stub { int rc = mountService.createSecureContainer( pkgName, mbLen, "vfat", sdEncKey, Process.SYSTEM_UID); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Failed to create container (%d)", rc)); rc = mountService.destroySecureContainer(pkgName); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Failed to cleanup container (%d)", rc)); return null; } rc = mountService.createSecureContainer( pkgName, mbLen, "vfat", sdEncKey, Process.SYSTEM_UID); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, String.format("Failed to create container (2nd try) (%d)", rc)); return null; } @@ -8325,7 +8325,7 @@ class PackageManagerService extends IPackageManager.Stub { int rc = getMountService().mountSecureContainer(pkgName, sdEncKey, ownerUid); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.i(TAG, "Failed to mount container for pkg : " + pkgName + " rc : " + rc); return null; } @@ -8336,7 +8336,7 @@ class PackageManagerService extends IPackageManager.Stub { private boolean unMountSdDir(String pkgName) { // STOPSHIP unmount directory int rc = getMountService().unmountSecureContainer(pkgName); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, "Failed to unmount : " + pkgName + " with rc " + rc); return false; } @@ -8360,7 +8360,7 @@ class PackageManagerService extends IPackageManager.Stub { private boolean finalizeSdDir(String pkgName) { int rc = getMountService().finalizeSecureContainer(pkgName); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.i(TAG, "Failed to finalize container for pkg : " + pkgName); return false; } @@ -8369,7 +8369,7 @@ class PackageManagerService extends IPackageManager.Stub { private boolean destroySdDir(String pkgName) { int rc = getMountService().destroySecureContainer(pkgName); - if (rc != MountServiceResultCode.OperationSucceeded) { + if (rc != StorageResultCode.OperationSucceeded) { Log.i(TAG, "Failed to destroy container for pkg : " + pkgName); return false; } diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 1e7dd99..1ccae86 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -41,7 +41,7 @@ import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; -import android.os.IMountService; +import android.os.storage.IMountService; import android.os.IPowerManager; import android.os.LocalPowerManager; import android.os.Power; diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java index a1370ea..3a4d38c 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java @@ -16,7 +16,7 @@ package com.android.unit_tests; -import android.os.IMountService.Stub; +import android.os.storage.IMountService.Stub; import android.net.Uri; import android.os.FileUtils; @@ -54,8 +54,8 @@ import android.util.Log; import android.os.Environment; import android.os.Handler; import android.os.IBinder; -import android.os.IMountService; -import android.os.MountServiceResultCode; +import android.os.storage.IMountService; +import android.os.storage.StorageResultCode; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; @@ -662,7 +662,7 @@ public class PackageManagerTests extends AndroidTestCase { try { String mPath = Environment.getExternalStorageDirectory().toString(); int ret = getMs().mountVolume(mPath); - return ret == MountServiceResultCode.OperationSucceeded; + return ret == StorageResultCode.OperationSucceeded; } catch (RemoteException e) { return false; } @@ -675,7 +675,7 @@ public class PackageManagerTests extends AndroidTestCase { try { String mPath = Environment.getExternalStorageDirectory().toString(); int ret = getMs().unmountVolume(mPath); - return ret == MountServiceResultCode.OperationSucceeded; + return ret == StorageResultCode.OperationSucceeded; } catch (RemoteException e) { return true; } |
