diff --git a/Android.mk b/Android.mk
index 9f92637..62c7679 100644
--- a/Android.mk
+++ b/Android.mk
@@ -118,10 +118,6 @@
 	core/java/android/net/IThrottleManager.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
-	core/java/android/os/storage/IMountService.aidl \
-	core/java/android/os/storage/IMountServiceListener.aidl \
-	core/java/android/os/storage/IMountShutdownObserver.aidl \
-	core/java/android/os/storage/IObbActionListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
 	core/java/android/os/INetStatService.aidl \
 	core/java/android/os/IPermissionController.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1efe77c..5618eaa 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -67,6 +67,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libreverb_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libreverbtest_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/soundfx/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/storage/*)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
deleted file mode 100644
index 5c69214..0000000
--- a/core/java/android/os/storage/IMountService.aidl
+++ /dev/null
@@ -1,184 +0,0 @@
-/* //device/java/android/android/os/IUsb.aidl
-**
-** Copyright 2007, 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.os.storage.IMountServiceListener;
-import android.os.storage.IMountShutdownObserver;
-import android.os.storage.IObbActionListener;
-
-/** 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 - Applications should use android.os.storage.StorageManager to access
- * storage functions.
- */
-interface IMountService
-{
-    /**
-     * Registers an IMountServiceListener for receiving async
-     * notifications.
-     */
-    void registerListener(IMountServiceListener listener);
-
-    /**
-     * Unregisters an IMountServiceListener
-     */
-    void unregisterListener(IMountServiceListener listener);
-
-    /**
-     * Returns true if a USB mass storage host is connected
-     */
-    boolean isUsbMassStorageConnected();
-
-    /**
-     * Enables / disables USB mass storage.
-     * The caller should check actual status of enabling/disabling
-     * USB mass storage via StorageEventListener.
-     */
-    void setUsbMassStorageEnabled(boolean enable);
-
-    /**
-     * Returns true if a USB mass storage host is enabled (media is shared)
-     */
-    boolean isUsbMassStorageEnabled();
-
-    /**
-     * Mount external storage at given mount point.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int mountVolume(String mountPoint);
-
-    /**
-     * Safely unmount external storage at given mount point.
-     * The unmount is an asynchronous operation. Applications
-     * should register StorageEventListener for storage related
-     * status changes.
-     * 
-     */
-    void unmountVolume(String mountPoint, boolean force);
-
-    /**
-     * Format external storage given a mount point.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int formatVolume(String mountPoint);
-
-    /**
-     * Returns an array of pids with open files on
-     * the specified path.
-     */
-    int[] getStorageUsers(String path);
-
-    /**
-     * Gets the state of a volume via its mountpoint.
-     */
-    String getVolumeState(String mountPoint);
-
-    /*
-     * Creates a secure container with the specified parameters.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid);
-
-    /*
-     * Finalize a container which has just been created and populated.
-     * After finalization, the container is immutable.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int finalizeSecureContainer(String id);
-
-    /*
-     * Destroy a secure container, and free up all resources associated with it.
-     * NOTE: Ensure all references are released prior to deleting.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int destroySecureContainer(String id, boolean force);
-
-    /*
-     * Mount a secure container with the specified key and owner UID.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int mountSecureContainer(String id, String key, int ownerUid);
-
-    /*
-     * Unount a secure container.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int unmountSecureContainer(String id, boolean force);
-
-    /*
-     * Returns true if the specified container is mounted
-     */
-    boolean isSecureContainerMounted(String id);
-
-    /*
-     * Rename an unmounted secure container.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    int renameSecureContainer(String oldId, String newId);
-
-    /*
-     * Returns the filesystem path of a mounted secure container.
-     */
-    String getSecureContainerPath(String id);
-
-    /**
-     * Gets an Array of currently known secure container IDs
-     */
-    String[] getSecureContainerList();
-
-    /**
-     * Shuts down the MountService and gracefully unmounts all external media.
-     * Invokes call back once the shutdown is complete.
-     */
-    void shutdown(IMountShutdownObserver observer);
-
-    /**
-     * Call into MountService by PackageManager to notify that its done
-     * processing the media status update request.
-     */
-    void finishMediaUpdate();
-
-    /**
-     * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and only
-     * allows the calling process's UID access to the contents.
-     *
-     * MountService will call back to the supplied IObbActionListener to inform
-     * it of the terminal state of the call.
-     */
-    void mountObb(String filename, String key, IObbActionListener token);
-
-    /**
-     * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified, any
-     * program using it will be forcibly killed to unmount the image.
-     *
-     * MountService will call back to the supplied IObbActionListener to inform
-     * it of the terminal state of the call.
-     */
-    void unmountObb(String filename, boolean force, IObbActionListener token);
-
-    /**
-     * Checks whether the specified Opaque Binary Blob (OBB) is mounted somewhere.
-     */
-    boolean isObbMounted(String filename);
-
-    /**
-     * Gets the path to the mounted Opaque Binary Blob (OBB).
-     */
-    String getMountedObbPath(String filename);
-}
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
new file mode 100644
index 0000000..60ea95c
--- /dev/null
+++ b/core/java/android/os/storage/IMountService.java
@@ -0,0 +1,1046 @@
+/*
+ * 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;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * 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 - Applications should use android.os.storage.StorageManager to access
+ *       storage functions.
+ */
+public interface IMountService extends IInterface {
+    /** Local-side IPC implementation stub class. */
+    public static abstract class Stub extends Binder implements IMountService {
+        private static class Proxy implements IMountService {
+            private IBinder mRemote;
+
+            Proxy(IBinder remote) {
+                mRemote = remote;
+            }
+
+            public IBinder asBinder() {
+                return mRemote;
+            }
+
+            public String getInterfaceDescriptor() {
+                return DESCRIPTOR;
+            }
+
+            /**
+             * Registers an IMountServiceListener for receiving async
+             * notifications.
+             */
+            public void registerListener(IMountServiceListener listener) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeStrongBinder((listener != null ? listener.asBinder() : null));
+                    mRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Unregisters an IMountServiceListener
+             */
+            public void unregisterListener(IMountServiceListener listener) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeStrongBinder((listener != null ? listener.asBinder() : null));
+                    mRemote.transact(Stub.TRANSACTION_unregisterListener, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Returns true if a USB mass storage host is connected
+             */
+            public boolean isUsbMassStorageConnected() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                boolean _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_isUsbMassStorageConnected, _data, _reply, 0);
+                    _reply.readException();
+                    _result = 0 != _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Enables / disables USB mass storage. The caller should check
+             * actual status of enabling/disabling USB mass storage via
+             * StorageEventListener.
+             */
+            public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt((enable ? 1 : 0));
+                    mRemote.transact(Stub.TRANSACTION_setUsbMassStorageEnabled, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Returns true if a USB mass storage host is enabled (media is
+             * shared)
+             */
+            public boolean isUsbMassStorageEnabled() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                boolean _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_isUsbMassStorageEnabled, _data, _reply, 0);
+                    _reply.readException();
+                    _result = 0 != _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Mount external storage at given mount point. Returns an int
+             * consistent with MountServiceResultCode
+             */
+            public int mountVolume(String mountPoint) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(mountPoint);
+                    mRemote.transact(Stub.TRANSACTION_mountVolume, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Safely unmount external storage at given mount point. The unmount
+             * is an asynchronous operation. Applications should register
+             * StorageEventListener for storage related status changes.
+             */
+            public void unmountVolume(String mountPoint, boolean force) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(mountPoint);
+                    _data.writeInt((force ? 1 : 0));
+                    mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Format external storage given a mount point. Returns an int
+             * consistent with MountServiceResultCode
+             */
+            public int formatVolume(String mountPoint) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(mountPoint);
+                    mRemote.transact(Stub.TRANSACTION_formatVolume, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Returns an array of pids with open files on the specified path.
+             */
+            public int[] getStorageUsers(String path) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int[] _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(path);
+                    mRemote.transact(Stub.TRANSACTION_getStorageUsers, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.createIntArray();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Gets the state of a volume via its mountpoint.
+             */
+            public String getVolumeState(String mountPoint) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(mountPoint);
+                    mRemote.transact(Stub.TRANSACTION_getVolumeState, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readString();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Creates a secure container with the specified parameters. Returns
+             * an int consistent with MountServiceResultCode
+             */
+            public int createSecureContainer(String id, int sizeMb, String fstype, String key,
+                    int ownerUid) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    _data.writeInt(sizeMb);
+                    _data.writeString(fstype);
+                    _data.writeString(key);
+                    _data.writeInt(ownerUid);
+                    mRemote.transact(Stub.TRANSACTION_createSecureContainer, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Destroy a secure container, and free up all resources associated
+             * with it. NOTE: Ensure all references are released prior to
+             * deleting. Returns an int consistent with MountServiceResultCode
+             */
+            public int destroySecureContainer(String id, boolean force) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    _data.writeInt((force ? 1 : 0));
+                    mRemote.transact(Stub.TRANSACTION_destroySecureContainer, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Finalize a container which has just been created and populated.
+             * After finalization, the container is immutable. Returns an int
+             * consistent with MountServiceResultCode
+             */
+            public int finalizeSecureContainer(String id) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    mRemote.transact(Stub.TRANSACTION_finalizeSecureContainer, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Mount a secure container with the specified key and owner UID.
+             * Returns an int consistent with MountServiceResultCode
+             */
+            public int mountSecureContainer(String id, String key, int ownerUid)
+                    throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    _data.writeString(key);
+                    _data.writeInt(ownerUid);
+                    mRemote.transact(Stub.TRANSACTION_mountSecureContainer, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Unount a secure container. Returns an int consistent with
+             * MountServiceResultCode
+             */
+            public int unmountSecureContainer(String id, boolean force) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    _data.writeInt((force ? 1 : 0));
+                    mRemote.transact(Stub.TRANSACTION_unmountSecureContainer, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Returns true if the specified container is mounted
+             */
+            public boolean isSecureContainerMounted(String id) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                boolean _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    mRemote.transact(Stub.TRANSACTION_isSecureContainerMounted, _data, _reply, 0);
+                    _reply.readException();
+                    _result = 0 != _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Rename an unmounted secure container. Returns an int consistent
+             * with MountServiceResultCode
+             */
+            public int renameSecureContainer(String oldId, String newId) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(oldId);
+                    _data.writeString(newId);
+                    mRemote.transact(Stub.TRANSACTION_renameSecureContainer, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /*
+             * Returns the filesystem path of a mounted secure container.
+             */
+            public String getSecureContainerPath(String id) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(id);
+                    mRemote.transact(Stub.TRANSACTION_getSecureContainerPath, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readString();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Gets an Array of currently known secure container IDs
+             */
+            public String[] getSecureContainerList() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String[] _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_getSecureContainerList, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.createStringArray();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Shuts down the MountService and gracefully unmounts all external
+             * media. Invokes call back once the shutdown is complete.
+             */
+            public void shutdown(IMountShutdownObserver observer)
+                    throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeStrongBinder((observer != null ? observer.asBinder() : null));
+                    mRemote.transact(Stub.TRANSACTION_shutdown, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Call into MountService by PackageManager to notify that its done
+             * processing the media status update request.
+             */
+            public void finishMediaUpdate() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_finishMediaUpdate, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Mounts an Opaque Binary Blob (OBB) with the specified decryption
+             * key and only allows the calling process's UID access to the
+             * contents. MountService will call back to the supplied
+             * IObbActionListener to inform it of the terminal state of the
+             * call.
+             */
+            public void mountObb(String filename, String key, IObbActionListener token)
+                    throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(filename);
+                    _data.writeString(key);
+                    _data.writeStrongBinder((token != null ? token.asBinder() : null));
+                    mRemote.transact(Stub.TRANSACTION_mountObb, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Unmounts an Opaque Binary Blob (OBB). When the force flag is
+             * specified, any program using it will be forcibly killed to
+             * unmount the image. MountService will call back to the supplied
+             * IObbActionListener to inform it of the terminal state of the
+             * call.
+             */
+            public void unmountObb(String filename, boolean force, IObbActionListener token)
+                    throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(filename);
+                    _data.writeInt((force ? 1 : 0));
+                    _data.writeStrongBinder((token != null ? token.asBinder() : null));
+                    mRemote.transact(Stub.TRANSACTION_unmountObb, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * Checks whether the specified Opaque Binary Blob (OBB) is mounted
+             * somewhere.
+             */
+            public boolean isObbMounted(String filename) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                boolean _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(filename);
+                    mRemote.transact(Stub.TRANSACTION_isObbMounted, _data, _reply, 0);
+                    _reply.readException();
+                    _result = 0 != _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            /**
+             * Gets the path to the mounted Opaque Binary Blob (OBB).
+             */
+            public String getMountedObbPath(String filename) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(filename);
+                    mRemote.transact(Stub.TRANSACTION_getMountedObbPath, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readString();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+        }
+
+        private static final String DESCRIPTOR = "IMountService";
+
+        static final int TRANSACTION_registerListener = IBinder.FIRST_CALL_TRANSACTION + 0;
+
+        static final int TRANSACTION_unregisterListener = IBinder.FIRST_CALL_TRANSACTION + 1;
+
+        static final int TRANSACTION_isUsbMassStorageConnected = IBinder.FIRST_CALL_TRANSACTION + 2;
+
+        static final int TRANSACTION_setUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 3;
+
+        static final int TRANSACTION_isUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 4;
+
+        static final int TRANSACTION_mountVolume = IBinder.FIRST_CALL_TRANSACTION + 5;
+
+        static final int TRANSACTION_unmountVolume = IBinder.FIRST_CALL_TRANSACTION + 6;
+
+        static final int TRANSACTION_formatVolume = IBinder.FIRST_CALL_TRANSACTION + 7;
+
+        static final int TRANSACTION_getStorageUsers = IBinder.FIRST_CALL_TRANSACTION + 8;
+
+        static final int TRANSACTION_getVolumeState = IBinder.FIRST_CALL_TRANSACTION + 9;
+
+        static final int TRANSACTION_createSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 10;
+
+        static final int TRANSACTION_finalizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 11;
+
+        static final int TRANSACTION_destroySecureContainer = IBinder.FIRST_CALL_TRANSACTION + 12;
+
+        static final int TRANSACTION_mountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 13;
+
+        static final int TRANSACTION_unmountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 14;
+
+        static final int TRANSACTION_isSecureContainerMounted = IBinder.FIRST_CALL_TRANSACTION + 15;
+
+        static final int TRANSACTION_renameSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 16;
+
+        static final int TRANSACTION_getSecureContainerPath = IBinder.FIRST_CALL_TRANSACTION + 17;
+
+        static final int TRANSACTION_getSecureContainerList = IBinder.FIRST_CALL_TRANSACTION + 18;
+
+        static final int TRANSACTION_shutdown = IBinder.FIRST_CALL_TRANSACTION + 19;
+
+        static final int TRANSACTION_finishMediaUpdate = IBinder.FIRST_CALL_TRANSACTION + 20;
+
+        static final int TRANSACTION_mountObb = IBinder.FIRST_CALL_TRANSACTION + 21;
+
+        static final int TRANSACTION_unmountObb = IBinder.FIRST_CALL_TRANSACTION + 22;
+
+        static final int TRANSACTION_isObbMounted = IBinder.FIRST_CALL_TRANSACTION + 23;
+
+        static final int TRANSACTION_getMountedObbPath = IBinder.FIRST_CALL_TRANSACTION + 24;
+
+        /**
+         * Cast an IBinder object into an IMountService interface, generating a
+         * proxy if needed.
+         */
+        public static IMountService asInterface(IBinder obj) {
+            if (obj == null) {
+                return null;
+            }
+            IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+            if (iin != null && iin instanceof IMountService) {
+                return (IMountService) iin;
+            }
+            return new IMountService.Stub.Proxy(obj);
+        }
+
+        /** Construct the stub at attach it to the interface. */
+        public Stub() {
+            attachInterface(this, DESCRIPTOR);
+        }
+
+        public IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply,
+                int flags) throws RemoteException {
+            switch (code) {
+                case INTERFACE_TRANSACTION: {
+                    reply.writeString(DESCRIPTOR);
+                    return true;
+                }
+                case TRANSACTION_registerListener: {
+                    data.enforceInterface(DESCRIPTOR);
+                    IMountServiceListener listener;
+                    listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder());
+                    registerListener(listener);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_unregisterListener: {
+                    data.enforceInterface(DESCRIPTOR);
+                    IMountServiceListener listener;
+                    listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder());
+                    unregisterListener(listener);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_isUsbMassStorageConnected: {
+                    data.enforceInterface(DESCRIPTOR);
+                    boolean result = isUsbMassStorageConnected();
+                    reply.writeNoException();
+                    reply.writeInt((result ? 1 : 0));
+                    return true;
+                }
+                case TRANSACTION_setUsbMassStorageEnabled: {
+                    data.enforceInterface(DESCRIPTOR);
+                    boolean enable;
+                    enable = 0 != data.readInt();
+                    setUsbMassStorageEnabled(enable);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_isUsbMassStorageEnabled: {
+                    data.enforceInterface(DESCRIPTOR);
+                    boolean result = isUsbMassStorageEnabled();
+                    reply.writeNoException();
+                    reply.writeInt((result ? 1 : 0));
+                    return true;
+                }
+                case TRANSACTION_mountVolume: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String mountPoint;
+                    mountPoint = data.readString();
+                    int resultCode = mountVolume(mountPoint);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_unmountVolume: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String mountPoint;
+                    mountPoint = data.readString();
+                    boolean force;
+                    force = 0 != data.readInt();
+                    unmountVolume(mountPoint, force);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_formatVolume: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String mountPoint;
+                    mountPoint = data.readString();
+                    int result = formatVolume(mountPoint);
+                    reply.writeNoException();
+                    reply.writeInt(result);
+                    return true;
+                }
+                case TRANSACTION_getStorageUsers: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String path;
+                    path = data.readString();
+                    int[] pids = getStorageUsers(path);
+                    reply.writeNoException();
+                    reply.writeIntArray(pids);
+                    return true;
+                }
+                case TRANSACTION_getVolumeState: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String mountPoint;
+                    mountPoint = data.readString();
+                    String state = getVolumeState(mountPoint);
+                    reply.writeNoException();
+                    reply.writeString(state);
+                    return true;
+                }
+                case TRANSACTION_createSecureContainer: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    int sizeMb;
+                    sizeMb = data.readInt();
+                    String fstype;
+                    fstype = data.readString();
+                    String key;
+                    key = data.readString();
+                    int ownerUid;
+                    ownerUid = data.readInt();
+                    int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_finalizeSecureContainer: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    int resultCode = finalizeSecureContainer(id);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_destroySecureContainer: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    boolean force;
+                    force = 0 != data.readInt();
+                    int resultCode = destroySecureContainer(id, force);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_mountSecureContainer: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    String key;
+                    key = data.readString();
+                    int ownerUid;
+                    ownerUid = data.readInt();
+                    int resultCode = mountSecureContainer(id, key, ownerUid);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_unmountSecureContainer: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    boolean force;
+                    force = 0 != data.readInt();
+                    int resultCode = unmountSecureContainer(id, force);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_isSecureContainerMounted: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    boolean status = isSecureContainerMounted(id);
+                    reply.writeNoException();
+                    reply.writeInt((status ? 1 : 0));
+                    return true;
+                }
+                case TRANSACTION_renameSecureContainer: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String oldId;
+                    oldId = data.readString();
+                    String newId;
+                    newId = data.readString();
+                    int resultCode = renameSecureContainer(oldId, newId);
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
+                case TRANSACTION_getSecureContainerPath: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String id;
+                    id = data.readString();
+                    String path = getSecureContainerPath(id);
+                    reply.writeNoException();
+                    reply.writeString(path);
+                    return true;
+                }
+                case TRANSACTION_getSecureContainerList: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String[] ids = getSecureContainerList();
+                    reply.writeNoException();
+                    reply.writeStringArray(ids);
+                    return true;
+                }
+                case TRANSACTION_shutdown: {
+                    data.enforceInterface(DESCRIPTOR);
+                    IMountShutdownObserver observer;
+                    observer = IMountShutdownObserver.Stub.asInterface(data
+                            .readStrongBinder());
+                    shutdown(observer);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_finishMediaUpdate: {
+                    data.enforceInterface(DESCRIPTOR);
+                    finishMediaUpdate();
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_mountObb: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String filename;
+                    filename = data.readString();
+                    String key;
+                    key = data.readString();
+                    IObbActionListener observer;
+                    observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
+                    mountObb(filename, key, observer);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_unmountObb: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String filename;
+                    filename = data.readString();
+                    boolean force;
+                    force = 0 != data.readInt();
+                    IObbActionListener observer;
+                    observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
+                    unmountObb(filename, force, observer);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_isObbMounted: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String filename;
+                    filename = data.readString();
+                    boolean status = isObbMounted(filename);
+                    reply.writeNoException();
+                    reply.writeInt((status ? 1 : 0));
+                    return true;
+                }
+                case TRANSACTION_getMountedObbPath: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String filename;
+                    filename = data.readString();
+                    String mountedPath = getMountedObbPath(filename);
+                    reply.writeNoException();
+                    reply.writeString(mountedPath);
+                    return true;
+                }
+            }
+            return super.onTransact(code, data, reply, flags);
+        }
+    }
+
+    /*
+     * Creates a secure container with the specified parameters. Returns an int
+     * consistent with MountServiceResultCode
+     */
+    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid)
+            throws RemoteException;
+
+    /*
+     * Destroy a secure container, and free up all resources associated with it.
+     * NOTE: Ensure all references are released prior to deleting. Returns an
+     * int consistent with MountServiceResultCode
+     */
+    public int destroySecureContainer(String id, boolean force) throws RemoteException;
+
+    /*
+     * Finalize a container which has just been created and populated. After
+     * finalization, the container is immutable. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    public int finalizeSecureContainer(String id) throws RemoteException;
+
+    /**
+     * Call into MountService by PackageManager to notify that its done
+     * processing the media status update request.
+     */
+    public void finishMediaUpdate() throws RemoteException;
+
+    /**
+     * Format external storage given a mount point. Returns an int consistent
+     * with MountServiceResultCode
+     */
+    public int formatVolume(String mountPoint) throws RemoteException;
+
+    /**
+     * Gets the path to the mounted Opaque Binary Blob (OBB).
+     */
+    public String getMountedObbPath(String filename) throws RemoteException;
+
+    /**
+     * Gets an Array of currently known secure container IDs
+     */
+    public String[] getSecureContainerList() throws RemoteException;
+
+    /*
+     * Returns the filesystem path of a mounted secure container.
+     */
+    public String getSecureContainerPath(String id) throws RemoteException;
+
+    /**
+     * Returns an array of pids with open files on the specified path.
+     */
+    public int[] getStorageUsers(String path) throws RemoteException;
+
+    /**
+     * Gets the state of a volume via its mountpoint.
+     */
+    public String getVolumeState(String mountPoint) throws RemoteException;
+
+    /**
+     * Checks whether the specified Opaque Binary Blob (OBB) is mounted
+     * somewhere.
+     */
+    public boolean isObbMounted(String filename) throws RemoteException;
+
+    /*
+     * Returns true if the specified container is mounted
+     */
+    public boolean isSecureContainerMounted(String id) throws RemoteException;
+
+    /**
+     * Returns true if a USB mass storage host is connected
+     */
+    public boolean isUsbMassStorageConnected() throws RemoteException;
+
+    /**
+     * Returns true if a USB mass storage host is enabled (media is shared)
+     */
+    public boolean isUsbMassStorageEnabled() throws RemoteException;
+
+    /**
+     * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
+     * only allows the calling process's UID access to the contents.
+     * MountService will call back to the supplied IObbActionListener to inform
+     * it of the terminal state of the call.
+     */
+    public void mountObb(String filename, String key, IObbActionListener token)
+            throws RemoteException;
+
+    /*
+     * Mount a secure container with the specified key and owner UID. Returns an
+     * int consistent with MountServiceResultCode
+     */
+    public int mountSecureContainer(String id, String key, int ownerUid) throws RemoteException;
+
+    /**
+     * Mount external storage at given mount point. Returns an int consistent
+     * with MountServiceResultCode
+     */
+    public int mountVolume(String mountPoint) throws RemoteException;
+
+    /**
+     * Registers an IMountServiceListener for receiving async notifications.
+     */
+    public void registerListener(IMountServiceListener listener) throws RemoteException;
+
+    /*
+     * Rename an unmounted secure container. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    public int renameSecureContainer(String oldId, String newId) throws RemoteException;
+
+    /**
+     * Enables / disables USB mass storage. The caller should check actual
+     * status of enabling/disabling USB mass storage via StorageEventListener.
+     */
+    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException;
+
+    /**
+     * Shuts down the MountService and gracefully unmounts all external media.
+     * Invokes call back once the shutdown is complete.
+     */
+    public void shutdown(IMountShutdownObserver observer) throws RemoteException;
+
+    /**
+     * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
+     * any program using it will be forcibly killed to unmount the image.
+     * MountService will call back to the supplied IObbActionListener to inform
+     * it of the terminal state of the call.
+     */
+    public void unmountObb(String filename, boolean force, IObbActionListener token)
+            throws RemoteException;
+
+    /*
+     * Unount a secure container. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    public int unmountSecureContainer(String id, boolean force) throws RemoteException;
+
+    /**
+     * Safely unmount external storage at given mount point. The unmount is an
+     * asynchronous operation. Applications should register StorageEventListener
+     * for storage related status changes.
+     */
+    public void unmountVolume(String mountPoint, boolean force) throws RemoteException;
+
+    /**
+     * Unregisters an IMountServiceListener
+     */
+    public void unregisterListener(IMountServiceListener listener) throws RemoteException;
+}
diff --git a/core/java/android/os/storage/IMountServiceListener.aidl b/core/java/android/os/storage/IMountServiceListener.aidl
deleted file mode 100644
index 883413a..0000000
--- a/core/java/android/os/storage/IMountServiceListener.aidl
+++ /dev/null
@@ -1,43 +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.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/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
new file mode 100644
index 0000000..d5c5fa5
--- /dev/null
+++ b/core/java/android/os/storage/IMountServiceListener.java
@@ -0,0 +1,176 @@
+/*
+ * 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;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * Callback class for receiving events from MountService.
+ * 
+ * @hide - Applications should use IStorageEventListener for storage event
+ *       callbacks.
+ */
+public interface IMountServiceListener extends IInterface {
+    /** Local-side IPC implementation stub class. */
+    public static abstract class Stub extends Binder implements IMountServiceListener {
+        private static final String DESCRIPTOR = "IMountServiceListener";
+
+        /** Construct the stub at attach it to the interface. */
+        public Stub() {
+            this.attachInterface(this, DESCRIPTOR);
+        }
+
+        /**
+         * Cast an IBinder object into an IMountServiceListener interface,
+         * generating a proxy if needed.
+         */
+        public static IMountServiceListener asInterface(IBinder obj) {
+            if ((obj == null)) {
+                return null;
+            }
+            IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
+            if (((iin != null) && (iin instanceof IMountServiceListener))) {
+                return ((IMountServiceListener) iin);
+            }
+            return new IMountServiceListener.Stub.Proxy(obj);
+        }
+
+        public IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            switch (code) {
+                case INTERFACE_TRANSACTION: {
+                    reply.writeString(DESCRIPTOR);
+                    return true;
+                }
+                case TRANSACTION_onUsbMassStorageConnectionChanged: {
+                    data.enforceInterface(DESCRIPTOR);
+                    boolean connected;
+                    connected = (0 != data.readInt());
+                    this.onUsbMassStorageConnectionChanged(connected);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_onStorageStateChanged: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String path;
+                    path = data.readString();
+                    String oldState;
+                    oldState = data.readString();
+                    String newState;
+                    newState = data.readString();
+                    this.onStorageStateChanged(path, oldState, newState);
+                    reply.writeNoException();
+                    return true;
+                }
+            }
+            return super.onTransact(code, data, reply, flags);
+        }
+
+        private static class Proxy implements IMountServiceListener {
+            private IBinder mRemote;
+
+            Proxy(IBinder remote) {
+                mRemote = remote;
+            }
+
+            public IBinder asBinder() {
+                return mRemote;
+            }
+
+            public String getInterfaceDescriptor() {
+                return DESCRIPTOR;
+            }
+
+            /**
+             * Detection state of USB Mass Storage has changed
+             * 
+             * @param available true if a UMS host is connected.
+             */
+            public void onUsbMassStorageConnectionChanged(boolean connected) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(((connected) ? (1) : (0)));
+                    mRemote.transact(Stub.TRANSACTION_onUsbMassStorageConnectionChanged, _data,
+                            _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            /**
+             * 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()
+             */
+            public void onStorageStateChanged(String path, String oldState, String newState)
+                    throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(path);
+                    _data.writeString(oldState);
+                    _data.writeString(newState);
+                    mRemote.transact(Stub.TRANSACTION_onStorageStateChanged, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+        }
+
+        static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0);
+
+        static final int TRANSACTION_onStorageStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 1);
+    }
+
+    /**
+     * Detection state of USB Mass Storage has changed
+     * 
+     * @param available true if a UMS host is connected.
+     */
+    public void onUsbMassStorageConnectionChanged(boolean connected) throws RemoteException;
+
+    /**
+     * 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()
+     */
+    public void onStorageStateChanged(String path, String oldState, String newState)
+            throws RemoteException;
+}
diff --git a/core/java/android/os/storage/IMountShutdownObserver.aidl b/core/java/android/os/storage/IMountShutdownObserver.aidl
deleted file mode 100644
index 0aa8a45..0000000
--- a/core/java/android/os/storage/IMountShutdownObserver.aidl
+++ /dev/null
@@ -1,33 +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.storage;
-
-/**
- * Callback class for receiving events related
- * to shutdown.
- *
- * @hide - For internal consumption only.
- */
-interface IMountShutdownObserver {
-    /**
-     * This method is called when the shutdown
-     * of MountService completed.
-     * @param statusCode indicates success or failure
-     * of the shutdown.
-     */
-    void onShutDownComplete(int statusCode);
-}
diff --git a/core/java/android/os/storage/IMountShutdownObserver.java b/core/java/android/os/storage/IMountShutdownObserver.java
new file mode 100644
index 0000000..d946e1a
--- /dev/null
+++ b/core/java/android/os/storage/IMountShutdownObserver.java
@@ -0,0 +1,124 @@
+/*
+ * 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;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * Callback class for receiving events related to shutdown.
+ * 
+ * @hide - For internal consumption only.
+ */
+public interface IMountShutdownObserver extends IInterface {
+    /** Local-side IPC implementation stub class. */
+    public static abstract class Stub extends Binder implements IMountShutdownObserver {
+        private static final java.lang.String DESCRIPTOR = "IMountShutdownObserver";
+
+        /** Construct the stub at attach it to the interface. */
+        public Stub() {
+            this.attachInterface(this, DESCRIPTOR);
+        }
+
+        /**
+         * Cast an IBinder object into an IMountShutdownObserver interface,
+         * generating a proxy if needed.
+         */
+        public static IMountShutdownObserver asInterface(IBinder obj) {
+            if ((obj == null)) {
+                return null;
+            }
+            IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
+            if (((iin != null) && (iin instanceof IMountShutdownObserver))) {
+                return ((IMountShutdownObserver) iin);
+            }
+            return new IMountShutdownObserver.Stub.Proxy(obj);
+        }
+
+        public IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            switch (code) {
+                case INTERFACE_TRANSACTION: {
+                    reply.writeString(DESCRIPTOR);
+                    return true;
+                }
+                case TRANSACTION_onShutDownComplete: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int statusCode;
+                    statusCode = data.readInt();
+                    this.onShutDownComplete(statusCode);
+                    reply.writeNoException();
+                    return true;
+                }
+            }
+            return super.onTransact(code, data, reply, flags);
+        }
+
+        private static class Proxy implements IMountShutdownObserver {
+            private IBinder mRemote;
+
+            Proxy(IBinder remote) {
+                mRemote = remote;
+            }
+
+            public IBinder asBinder() {
+                return mRemote;
+            }
+
+            public java.lang.String getInterfaceDescriptor() {
+                return DESCRIPTOR;
+            }
+
+            /**
+             * This method is called when the shutdown of MountService
+             * completed.
+             * 
+             * @param statusCode indicates success or failure of the shutdown.
+             */
+            public void onShutDownComplete(int statusCode) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(statusCode);
+                    mRemote.transact(Stub.TRANSACTION_onShutDownComplete, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+        }
+
+        static final int TRANSACTION_onShutDownComplete = (IBinder.FIRST_CALL_TRANSACTION + 0);
+    }
+
+    /**
+     * This method is called when the shutdown of MountService completed.
+     * 
+     * @param statusCode indicates success or failure of the shutdown.
+     */
+    public void onShutDownComplete(int statusCode) throws RemoteException;
+}
diff --git a/core/java/android/os/storage/IObbActionListener.aidl b/core/java/android/os/storage/IObbActionListener.aidl
deleted file mode 100644
index 78d7a9e..0000000
--- a/core/java/android/os/storage/IObbActionListener.aidl
+++ /dev/null
@@ -1,34 +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.storage;
-
-/**
- * Callback class for receiving events from MountService about
- * Opaque Binary Blobs (OBBs).
- *
- * @hide - Applications should use android.os.storage.StorageManager
- * to interact with OBBs.
- */
-interface IObbActionListener {
-    /**
-     * Return from an OBB action result.
-     *
-     * @param filename the path to the OBB the operation was performed on
-     * @param returnCode status of the operation
-     */
-    void onObbResult(String filename, String status);
-}
diff --git a/core/java/android/os/storage/IObbActionListener.java b/core/java/android/os/storage/IObbActionListener.java
new file mode 100644
index 0000000..2c098ac
--- /dev/null
+++ b/core/java/android/os/storage/IObbActionListener.java
@@ -0,0 +1,130 @@
+/*
+ * 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;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * Callback class for receiving events from MountService about Opaque Binary
+ * Blobs (OBBs).
+ * 
+ * @hide - Applications should use StorageManager to interact with OBBs.
+ */
+public interface IObbActionListener extends IInterface {
+    /** Local-side IPC implementation stub class. */
+    public static abstract class Stub extends Binder implements IObbActionListener {
+        private static final String DESCRIPTOR = "IObbActionListener";
+
+        /** Construct the stub at attach it to the interface. */
+        public Stub() {
+            this.attachInterface(this, DESCRIPTOR);
+        }
+
+        /**
+         * Cast an IBinder object into an IObbActionListener interface,
+         * generating a proxy if needed.
+         */
+        public static IObbActionListener asInterface(IBinder obj) {
+            if ((obj == null)) {
+                return null;
+            }
+            IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
+            if (((iin != null) && (iin instanceof IObbActionListener))) {
+                return ((IObbActionListener) iin);
+            }
+            return new IObbActionListener.Stub.Proxy(obj);
+        }
+
+        public IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            switch (code) {
+                case INTERFACE_TRANSACTION: {
+                    reply.writeString(DESCRIPTOR);
+                    return true;
+                }
+                case TRANSACTION_onObbResult: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String filename;
+                    filename = data.readString();
+                    String status;
+                    status = data.readString();
+                    this.onObbResult(filename, status);
+                    reply.writeNoException();
+                    return true;
+                }
+            }
+            return super.onTransact(code, data, reply, flags);
+        }
+
+        private static class Proxy implements IObbActionListener {
+            private IBinder mRemote;
+
+            Proxy(IBinder remote) {
+                mRemote = remote;
+            }
+
+            public IBinder asBinder() {
+                return mRemote;
+            }
+
+            public String getInterfaceDescriptor() {
+                return DESCRIPTOR;
+            }
+
+            /**
+             * Return from an OBB action result.
+             * 
+             * @param filename the path to the OBB the operation was performed
+             *            on
+             * @param returnCode status of the operation
+             */
+            public void onObbResult(String filename, String status) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(filename);
+                    _data.writeString(status);
+                    mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+        }
+
+        static final int TRANSACTION_onObbResult = (IBinder.FIRST_CALL_TRANSACTION + 0);
+    }
+
+    /**
+     * Return from an OBB action result.
+     * 
+     * @param filename the path to the OBB the operation was performed on
+     * @param returnCode status of the operation
+     */
+    public void onObbResult(String filename, String status) throws RemoteException;
+}
diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h
new file mode 100644
index 0000000..a2735a4
--- /dev/null
+++ b/include/storage/IMountService.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_IMOUNTSERVICE_H
+#define ANDROID_IMOUNTSERVICE_H
+
+#include <storage/IMountServiceListener.h>
+#include <storage/IMountShutdownObserver.h>
+#include <storage/IObbActionListener.h>
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMountService: public IInterface {
+public:
+    DECLARE_META_INTERFACE(MountService);
+
+    virtual void registerListener(const sp<IMountServiceListener>& listener) = 0;
+    virtual void
+            unregisterListener(const sp<IMountServiceListener>& listener) = 0;
+    virtual bool isUsbMassStorageConnected() = 0;
+    virtual void setUsbMassStorageEnabled(const bool enable) = 0;
+    virtual bool isUsbMassStorageEnabled() = 0;
+    virtual int32_t mountVolume(const String16& mountPoint) = 0;
+    virtual int32_t
+            unmountVolume(const String16& mountPoint, const bool force) = 0;
+    virtual int32_t formatVolume(const String16& mountPoint) = 0;
+    virtual int32_t
+            getStorageUsers(const String16& mountPoint, int32_t** users) = 0;
+    virtual int32_t getVolumeState(const String16& mountPoint) = 0;
+    virtual int32_t createSecureContainer(const String16& id,
+            const int32_t sizeMb, const String16& fstype, const String16& key,
+            const int32_t ownerUid) = 0;
+    virtual int32_t finalizeSecureContainer(const String16& id) = 0;
+    virtual int32_t destroySecureContainer(const String16& id) = 0;
+    virtual int32_t mountSecureContainer(const String16& id,
+            const String16& key, const int32_t ownerUid) = 0;
+    virtual int32_t
+            unmountSecureContainer(const String16& id, const bool force) = 0;
+    virtual bool isSecureContainerMounted(const String16& id) = 0;
+    virtual int32_t renameSecureContainer(const String16& oldId,
+            const String16& newId) = 0;
+    virtual bool getSecureContainerPath(const String16& id, String16& path) = 0;
+    virtual int32_t getSecureContainerList(const String16& id,
+            String16*& containers) = 0;
+    virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;
+    virtual void finishMediaUpdate() = 0;
+    virtual void mountObb(const String16& filename, const String16& key,
+            const sp<IObbActionListener>& token) = 0;
+    virtual void unmountObb(const String16& filename, const bool force) = 0;
+    virtual bool isObbMounted(const String16& filename) = 0;
+    virtual bool getMountedObbPath(const String16& filename, String16& path) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMountService: public BnInterface<IMountService> {
+public:
+    virtual status_t onTransact(uint32_t code, const Parcel& data,
+            Parcel* reply, uint32_t flags = 0);
+};
+
+}
+; // namespace android
+
+#endif // ANDROID_IMOUNTSERVICE_H
diff --git a/include/storage/IMountServiceListener.h b/include/storage/IMountServiceListener.h
new file mode 100644
index 0000000..5b1f21c
--- /dev/null
+++ b/include/storage/IMountServiceListener.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_IMOUNTSERVICELISTENER_H
+#define ANDROID_IMOUNTSERVICELISTENER_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMountServiceListener: public IInterface {
+public:
+    DECLARE_META_INTERFACE(MountServiceListener);
+
+    virtual void onUsbMassStorageConnectionChanged(const bool connected) = 0;
+    virtual void onStorageStateChanged(const String16& path,
+            const String16& oldState, const String16& newState) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMountServiceListener: public BnInterface<IMountServiceListener> {
+public:
+    virtual status_t onTransact(uint32_t code, const Parcel& data,
+            Parcel* reply, uint32_t flags = 0);
+};
+
+}
+; // namespace android
+
+#endif // ANDROID_IMOUNTSERVICELISTENER_H
diff --git a/include/storage/IMountShutdownObserver.h b/include/storage/IMountShutdownObserver.h
new file mode 100644
index 0000000..d019e01
--- /dev/null
+++ b/include/storage/IMountShutdownObserver.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_IMOUNTSHUTDOWNOBSERVER_H
+#define ANDROID_IMOUNTSHUTDOWNOBSERVER_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMountShutdownObserver: public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(MountShutdownObserver);
+
+    virtual void onShutDownComplete(const int32_t statusCode) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMountShutdownObserver: public BnInterface<IMountShutdownObserver>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMOUNTSHUTDOWNOBSERVER_H
diff --git a/include/storage/IObbActionListener.h b/include/storage/IObbActionListener.h
new file mode 100644
index 0000000..1bedcc6
--- /dev/null
+++ b/include/storage/IObbActionListener.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_IOBBACTIONLISTENER_H
+#define ANDROID_IOBBACTIONLISTENER_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+#include <utils/String16.h>
+
+namespace android {
+
+class IObbActionListener: public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(ObbActionListener);
+
+    virtual void onObbResult(const String16& filename, const String16& status) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnObbActionListener: public BnInterface<IObbActionListener>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IOBBACTIONLISTENER_H
diff --git a/libs/storage/Android.mk b/libs/storage/Android.mk
new file mode 100644
index 0000000..1e52fa4
--- /dev/null
+++ b/libs/storage/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	IMountServiceListener.cpp \
+	IMountShutdownObserver.cpp \
+	IObbActionListener.cpp \
+	IMountService.cpp
+
+LOCAL_STATIC_LIBRARIES := \
+	libutils \
+	libbinder
+
+LOCAL_MODULE:= libstorage
+
+ifeq ($(TARGET_SIMULATOR),true)
+    LOCAL_LDLIBS += -lpthread
+endif
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
new file mode 100644
index 0000000..902bb27
--- /dev/null
+++ b/libs/storage/IMountService.cpp
@@ -0,0 +1,508 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "IMountService"
+
+#include <storage/IMountService.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+enum {
+    TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION,
+    TRANSACTION_unregisterListener,
+    TRANSACTION_isUsbMassStorageConnected,
+    TRANSACTION_setUsbMassStorageEnabled,
+    TRANSACTION_isUsbMassStorageEnabled,
+    TRANSACTION_mountVolume,
+    TRANSACTION_unmountVolume,
+    TRANSACTION_formatVolume,
+    TRANSACTION_getStorageUsers,
+    TRANSACTION_getVolumeState,
+    TRANSACTION_createSecureContainer,
+    TRANSACTION_finalizeSecureContainer,
+    TRANSACTION_destroySecureContainer,
+    TRANSACTION_mountSecureContainer,
+    TRANSACTION_unmountSecureContainer,
+    TRANSACTION_isSecureContainerMounted,
+    TRANSACTION_renameSecureContainer,
+    TRANSACTION_getSecureContainerPath,
+    TRANSACTION_getSecureContainerList,
+    TRANSACTION_shutdown,
+    TRANSACTION_finishMediaUpdate,
+    TRANSACTION_mountObb,
+    TRANSACTION_unmountObb,
+    TRANSACTION_isObbMounted,
+    TRANSACTION_getMountedObbPath,
+};
+
+class BpMountService: public BpInterface<IMountService>
+{
+public:
+    BpMountService(const sp<IBinder>& impl)
+        : BpInterface<IMountService>(impl)
+    {
+    }
+
+    virtual void registerListener(const sp<IMountServiceListener>& listener)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeStrongBinder(listener->asBinder());
+        if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) {
+            LOGD("registerListener could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("registerListener caught exception %d\n", err);
+            return;
+        }
+    }
+
+    virtual void unregisterListener(const sp<IMountServiceListener>& listener)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeStrongBinder(listener->asBinder());
+        if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) {
+            LOGD("unregisterListener could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("unregisterListener caught exception %d\n", err);
+            return;
+        }
+    }
+
+    virtual bool isUsbMassStorageConnected()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) {
+            LOGD("isUsbMassStorageConnected could not contact remote\n");
+            return false;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("isUsbMassStorageConnected caught exception %d\n", err);
+            return false;
+        }
+        return reply.readInt32() != 0;
+    }
+
+    virtual void setUsbMassStorageEnabled(const bool enable)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeInt32(enable != 0);
+        if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
+            LOGD("setUsbMassStorageEnabled could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("setUsbMassStorageEnabled caught exception %d\n", err);
+            return;
+        }
+    }
+
+    virtual bool isUsbMassStorageEnabled()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
+            LOGD("isUsbMassStorageEnabled could not contact remote\n");
+            return false;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("isUsbMassStorageEnabled caught exception %d\n", err);
+            return false;
+        }
+        return reply.readInt32() != 0;
+    }
+
+    int32_t mountVolume(const String16& mountPoint)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(mountPoint);
+        if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) {
+            LOGD("mountVolume could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("mountVolume caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t unmountVolume(const String16& mountPoint, const bool force)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(mountPoint);
+        data.writeInt32(force ? 1 : 0);
+        if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
+            LOGD("unmountVolume could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("unmountVolume caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t formatVolume(const String16& mountPoint)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(mountPoint);
+        if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) {
+            LOGD("formatVolume could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("formatVolume caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t getStorageUsers(const String16& mountPoint, int32_t** users)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(mountPoint);
+        if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) {
+            LOGD("getStorageUsers could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("getStorageUsers caught exception %d\n", err);
+            return err;
+        }
+        const int32_t numUsers = reply.readInt32();
+        *users = (int32_t*)malloc(sizeof(int32_t)*numUsers);
+        for (int i = 0; i < numUsers; i++) {
+            **users++ = reply.readInt32();
+        }
+        return numUsers;
+    }
+
+    int32_t getVolumeState(const String16& mountPoint)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(mountPoint);
+        if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) {
+            LOGD("getVolumeState could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("getVolumeState caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype,
+            const String16& key, const int32_t ownerUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        data.writeInt32(sizeMb);
+        data.writeString16(fstype);
+        data.writeString16(key);
+        data.writeInt32(ownerUid);
+        if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) {
+            LOGD("createSecureContainer could not contact remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("createSecureContainer caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t finalizeSecureContainer(const String16& id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) {
+            LOGD("finalizeSecureContainer couldn't call remote\n");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("finalizeSecureContainer caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t destroySecureContainer(const String16& id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) {
+            LOGD("destroySecureContainer couldn't call remote");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("destroySecureContainer caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        data.writeString16(key);
+        data.writeInt32(ownerUid);
+        if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) {
+            LOGD("mountSecureContainer couldn't call remote");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode(); // What to do...
+        if (err < 0) {
+            LOGD("mountSecureContainer caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    int32_t unmountSecureContainer(const String16& id, const bool force)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        data.writeInt32(force ? 1 : 0);
+        if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
+            LOGD("unmountSecureContainer couldn't call remote");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode(); // What to do...
+        if (err < 0) {
+            LOGD("unmountSecureContainer caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    bool isSecureContainerMounted(const String16& id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) {
+            LOGD("isSecureContainerMounted couldn't call remote");
+            return false;
+        }
+        int32_t err = reply.readExceptionCode(); // What to do...
+        if (err < 0) {
+            LOGD("isSecureContainerMounted caught exception %d\n", err);
+            return false;
+        }
+        return reply.readInt32() != 0;
+    }
+
+    int32_t renameSecureContainer(const String16& oldId, const String16& newId)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(oldId);
+        data.writeString16(newId);
+        if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) {
+            LOGD("renameSecureContainer couldn't call remote");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode(); // What to do...
+        if (err < 0) {
+            LOGD("renameSecureContainer caught exception %d\n", err);
+            return err;
+        }
+        return reply.readInt32();
+    }
+
+    bool getSecureContainerPath(const String16& id, String16& path)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
+            LOGD("getSecureContainerPath couldn't call remote");
+            return false;
+        }
+        int32_t err = reply.readExceptionCode(); // What to do...
+        if (err < 0) {
+            LOGD("getSecureContainerPath caught exception %d\n", err);
+            return false;
+        }
+        path = reply.readString16();
+        return true;
+    }
+
+    int32_t getSecureContainerList(const String16& id, String16*& containers)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(id);
+        if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) {
+            LOGD("getSecureContainerList couldn't call remote");
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("getSecureContainerList caught exception %d\n", err);
+            return err;
+        }
+        const int32_t numStrings = reply.readInt32();
+        containers = new String16[numStrings];
+        for (int i = 0; i < numStrings; i++) {
+            containers[i] = reply.readString16();
+        }
+        return numStrings;
+    }
+
+    void shutdown(const sp<IMountShutdownObserver>& observer)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeStrongBinder(observer->asBinder());
+        if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) {
+            LOGD("shutdown could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("shutdown caught exception %d\n", err);
+            return;
+        }
+        reply.readExceptionCode();
+    }
+
+    void finishMediaUpdate()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) {
+            LOGD("finishMediaUpdate could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("finishMediaUpdate caught exception %d\n", err);
+            return;
+        }
+        reply.readExceptionCode();
+    }
+
+    void mountObb(const String16& filename, const String16& key, const sp<
+            IObbActionListener>& token)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(filename);
+        data.writeString16(key);
+        data.writeStrongBinder(token->asBinder());
+        if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
+            LOGD("mountObb could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("mountObb caught exception %d\n", err);
+            return;
+        }
+    }
+
+    void unmountObb(const String16& filename, const bool force)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(filename);
+        data.writeInt32(force ? 1 : 0);
+        if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
+            LOGD("unmountObb could not contact remote\n");
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("unmountObb caught exception %d\n", err);
+            return;
+        }
+    }
+
+    bool isObbMounted(const String16& filename)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(filename);
+        if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
+            LOGD("isObbMounted could not contact remote\n");
+            return false;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("isObbMounted caught exception %d\n", err);
+            return false;
+        }
+        return reply.readInt32() != 0;
+    }
+
+    bool getMountedObbPath(const String16& filename, String16& path)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
+        data.writeString16(filename);
+        if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
+            LOGD("getMountedObbPath could not contact remote\n");
+            return false;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            LOGD("getMountedObbPath caught exception %d\n", err);
+            return false;
+        }
+        path = reply.readString16();
+        return true;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(MountService, "IMountService");
+
+// ----------------------------------------------------------------------
+
+};
diff --git a/libs/storage/IMountServiceListener.cpp b/libs/storage/IMountServiceListener.cpp
new file mode 100644
index 0000000..c98a424
--- /dev/null
+++ b/libs/storage/IMountServiceListener.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#include <storage/IMountServiceListener.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+enum {
+    TRANSACTION_onUsbMassStorageConnectionChanged = IBinder::FIRST_CALL_TRANSACTION,
+    TRANSACTION_onStorageStateChanged,
+};
+
+status_t BnMountServiceListener::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case TRANSACTION_onUsbMassStorageConnectionChanged: {
+            CHECK_INTERFACE(IMountServiceListener, data, reply);
+            bool connected = (data.readInt32() != 0);
+            onUsbMassStorageConnectionChanged(connected);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case TRANSACTION_onStorageStateChanged: {
+            CHECK_INTERFACE(IMountServiceListener, data, reply);
+            String16 path = data.readString16();
+            String16 oldState = data.readString16();
+            String16 newState = data.readString16();
+            onStorageStateChanged(path, oldState, newState);
+            reply->writeNoException();
+            return NO_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+// ----------------------------------------------------------------------
+
+};
diff --git a/libs/storage/IMountShutdownObserver.cpp b/libs/storage/IMountShutdownObserver.cpp
new file mode 100644
index 0000000..1a6fdee
--- /dev/null
+++ b/libs/storage/IMountShutdownObserver.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#include <storage/IMountShutdownObserver.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+enum {
+    TRANSACTION_onShutDownComplete = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+status_t BnMountShutdownObserver::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case TRANSACTION_onShutDownComplete: {
+            CHECK_INTERFACE(IMountShutdownObserver, data, reply);
+            int32_t statusCode = data.readInt32();
+            onShutDownComplete(statusCode);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+// ----------------------------------------------------------------------
+
+};
diff --git a/libs/storage/IObbActionListener.cpp b/libs/storage/IObbActionListener.cpp
new file mode 100644
index 0000000..5bfece7
--- /dev/null
+++ b/libs/storage/IObbActionListener.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#include <storage/IObbActionListener.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+enum {
+    TRANSACTION_onObbResult = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+// This is a stub that real consumers should override.
+class BpObbActionListener: public BpInterface<IObbActionListener> {
+public:
+    BpObbActionListener(const sp<IBinder>& impl)
+        : BpInterface<IObbActionListener>(impl)
+    { }
+
+    virtual void onObbResult(const String16& filename, const String16& status) { }
+};
+
+IMPLEMENT_META_INTERFACE(ObbActionListener, "IObbActionListener");
+
+// ----------------------------------------------------------------------
+
+status_t BnObbActionListener::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case TRANSACTION_onObbResult: {
+            CHECK_INTERFACE(IObbActionListener, data, reply);
+            String16 filename = data.readString16();
+            String16 state = data.readString16();
+            onObbResult(filename, state);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------
+
+};
diff --git a/libs/storage/MODULE_LICENSE_APACHE2 b/libs/storage/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/storage/MODULE_LICENSE_APACHE2
diff --git a/libs/storage/NOTICE b/libs/storage/NOTICE
new file mode 100644
index 0000000..5d14293
--- /dev/null
+++ b/libs/storage/NOTICE
@@ -0,0 +1,190 @@
+
+   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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
