Remove DefaultContainerService usage in StorageManagerService.

StorageManagerService uses DefaultContainerService to obtain ObbInfo
for files passed through mountObb() transaction. This change moves this
logic to client side and so ObbInfo will be passed as part of mountObb()
transaction.

Bug: 111838160
Test: atest src/android/os/storage/cts/StorageManagerTest.java
Test: atest core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
Test: atest services/tests/servicestests/src/com/android/server/MountServiceTests.java
Change-Id: I29aee3aa54a45057df96aae289888161a3e3af71
diff --git a/core/java/android/content/res/ObbInfo.java b/core/java/android/content/res/ObbInfo.java
index 452fdce..1d10b4f 100644
--- a/core/java/android/content/res/ObbInfo.java
+++ b/core/java/android/content/res/ObbInfo.java
@@ -80,6 +80,7 @@
     }
 
     public void writeToParcel(Parcel dest, int parcelableFlags) {
+        // Keep this in sync with writeToParcel() in ObbInfo.cpp
         dest.writeString(filename);
         dest.writeString(packageName);
         dest.writeInt(version);
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 5c2d41e..33b2676 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -17,6 +17,7 @@
 package android.os.storage;
 
 import android.content.pm.IPackageMoveObserver;
+import android.content.res.ObbInfo;
 import android.os.IVoldTaskListener;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.DiskInfo;
@@ -57,7 +58,7 @@
      * it of the terminal state of the call.
      */
     void mountObb(in String rawPath, in String canonicalPath, in String key,
-            IObbActionListener token, int nonce) = 21;
+            IObbActionListener token, int nonce, in ObbInfo obbInfo) = 21;
     /**
      * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
      * any program using it will be forcibly killed to unmount the image.
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 5a1ea68..e69acae 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -34,6 +34,8 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.PackageManager;
+import android.content.res.ObbInfo;
+import android.content.res.ObbScanner;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -580,7 +582,8 @@
         try {
             final String canonicalPath = new File(rawPath).getCanonicalPath();
             final int nonce = mObbActionListener.addListener(listener);
-            mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce);
+            mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce,
+                    getObbInfo(canonicalPath));
             return true;
         } catch (IOException e) {
             throw new IllegalArgumentException("Failed to resolve path: " + rawPath, e);
@@ -589,6 +592,15 @@
         }
     }
 
+    private ObbInfo getObbInfo(String canonicalPath) {
+        try {
+            final ObbInfo obbInfo = ObbScanner.getObbInfo(canonicalPath);
+            return obbInfo;
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Couldn't get OBB info for " + canonicalPath, e);
+        }
+    }
+
     /**
      * Unmount an Opaque Binary Blob (OBB) file asynchronously. If the
      * <code>force</code> flag is true, it will kill any application needed to
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
index 56629d4..16dcff5 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
@@ -65,95 +65,6 @@
         + "to ourselves and our posterity, do ordain and establish this Constitution\n"
         + "for the United States of America.\n\n";
 
-    class MountingObbThread extends Thread {
-        boolean mStop = false;
-        volatile boolean mFileOpenOnObb = false;
-        private String mObbFilePath = null;
-        private String mPathToContentsFile = null;
-        private String mOfficialObbFilePath = null;
-
-        /**
-         * Constructor
-         *
-         * @param obbFilePath path to the OBB image file
-         * @param pathToContentsFile path to a file on the mounted OBB volume to open after the OBB
-         *      has been mounted
-         */
-        public MountingObbThread (String obbFilePath, String pathToContentsFile) {
-            assertTrue("obbFilePath cannot be null!", obbFilePath != null);
-            mObbFilePath = obbFilePath;
-            assertTrue("path to contents file cannot be null!", pathToContentsFile != null);
-            mPathToContentsFile = pathToContentsFile;
-        }
-
-        /**
-         * Runs the thread
-         *
-         * Mounts OBB_FILE_1, and tries to open a file on the mounted OBB (specified in the
-         * constructor). Once it's open, it waits until someone calls its doStop(), after which it
-         * closes the opened file.
-         */
-        public void run() {
-            // the official OBB file path and the mount-request file path should be the same, but
-            // let's distinguish the two as they may make for some interesting tests later
-            mOfficialObbFilePath = mountObb(mObbFilePath);
-            assertEquals("Expected and actual OBB file paths differ!", mObbFilePath,
-                    mOfficialObbFilePath);
-
-            // open a file on OBB 1...
-            DataInputStream inputFile = openFileOnMountedObb(mOfficialObbFilePath,
-                    mPathToContentsFile);
-            assertTrue("Failed to open file!", inputFile != null);
-
-            synchronized (this) {
-                mFileOpenOnObb = true;
-                notifyAll();
-            }
-
-            while (!mStop) {
-                try {
-                    Thread.sleep(WAIT_TIME_INCR);
-                } catch (InterruptedException e) {
-                    // nothing special to be done for interruptions
-                }
-            }
-            try {
-                inputFile.close();
-            } catch (IOException e) {
-                fail("Failed to close file on OBB due to error: " + e.toString());
-            }
-        }
-
-        /**
-         * Tells whether a file has yet been successfully opened on the OBB or not
-         *
-         * @return true if the specified file on the OBB was opened; false otherwise
-         */
-        public boolean isFileOpenOnObb() {
-            return mFileOpenOnObb;
-        }
-
-        /**
-         * Returns the official path of the OBB file that was mounted
-         *
-         * This is not the mount path, but the normalized path to the actual OBB file
-         *
-         * @return a {@link String} representation of the path to the OBB file that was mounted
-         */
-        public String officialObbFilePath() {
-            return mOfficialObbFilePath;
-        }
-
-        /**
-         * Requests the thread to stop running
-         *
-         * Closes the opened file and returns
-         */
-        public void doStop() {
-            mStop = true;
-        }
-    }
-
     public class ObbListener extends OnObbStateChangeListener {
         private String LOG_TAG = "StorageManagerBaseTest.ObbListener";
 
@@ -362,7 +273,8 @@
         assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, key, obbListener));
         assertTrue("Failed to get OBB mount status change for file: " + obbFilePath,
                 doWaitForObbStateChange(obbListener));
-        assertEquals("OBB mount state not what was expected!", expectedState, obbListener.state());
+        assertEquals("OBB mount state not what was expected!", expectedState,
+                obbListener.state());
 
         if (OnObbStateChangeListener.MOUNTED == expectedState) {
             assertEquals(obbFilePath, obbListener.officialPath());
@@ -373,7 +285,8 @@
                     mSm.isObbMounted(obbListener.officialPath()));
         }
 
-        assertEquals("Mount state is not what was expected!", expectedState, obbListener.state());
+        assertEquals("Mount state is not what was expected!", expectedState,
+                obbListener.state());
         return obbListener.officialPath();
     }
 
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
index 5f8bd03..3ec297c 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
@@ -20,7 +20,6 @@
 import android.os.ProxyFileDescriptorCallback;
 import android.system.ErrnoException;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
 
 import com.android.frameworks.coretests.R;
 
@@ -135,57 +134,18 @@
     }
 
     /**
-     * Tests that we can not force unmount when a file is currently open on the OBB.
-     */
-    @LargeTest
-    public void testUnmount_DontForce() throws Exception {
-        final File file = createObbFile(OBB_FILE_1, R.raw.obb_file1);
-        String obbFilePath = file.getAbsolutePath();
-
-        MountingObbThread mountingThread = new MountingObbThread(obbFilePath,
-                OBB_FILE_1_CONTENTS_1);
-
-        try {
-            mountingThread.start();
-
-            long waitTime = 0;
-            while (!mountingThread.isFileOpenOnObb()) {
-                synchronized (mountingThread) {
-                    Log.i(LOG_TAG, "Waiting for file to be opened on OBB...");
-                    mountingThread.wait(WAIT_TIME_INCR);
-                    waitTime += WAIT_TIME_INCR;
-                    if (waitTime > MAX_WAIT_TIME) {
-                        fail("Timed out waiting for file file to be opened on OBB!");
-                    }
-                }
-            }
-
-            unmountObb(obbFilePath, DONT_FORCE);
-
-            // verify still mounted
-            assertTrue("mounted path should not be null!", obbFilePath != null);
-            assertTrue("mounted path should still be mounted!", mSm.isObbMounted(obbFilePath));
-
-            // close the opened file
-            mountingThread.doStop();
-
-            // try unmounting again (should succeed this time)
-            unmountObb(obbFilePath, DONT_FORCE);
-            assertFalse("mounted path should no longer be mounted!",
-                    mSm.isObbMounted(obbFilePath));
-        } catch (InterruptedException e) {
-            fail("Timed out waiting for file on OBB to be opened...");
-        }
-    }
-
-    /**
      * Tests mounting a single OBB that isn't signed.
      */
     @LargeTest
     public void testMountUnsignedObb() throws Exception {
         final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
         String filePath = file.getAbsolutePath();
-        mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
+        try {
+            mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
+            fail("mountObb should've failed with an exception");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
     }
 
     /**
diff --git a/libs/storage/Android.bp b/libs/storage/Android.bp
index 911bd1d..c19933e 100644
--- a/libs/storage/Android.bp
+++ b/libs/storage/Android.bp
@@ -6,6 +6,7 @@
         "IMountShutdownObserver.cpp",
         "IObbActionListener.cpp",
         "IMountService.cpp",
+        "ObbInfo.cpp",
     ],
 
     export_include_dirs: ["include"],
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fa3d8bd..fd6e6e9 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -443,7 +443,7 @@
     }
 
     void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
-            const sp<IObbActionListener>& token, int32_t nonce)
+            const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
@@ -452,6 +452,7 @@
         data.writeString16(key);
         data.writeStrongBinder(IInterface::asBinder(token));
         data.writeInt32(nonce);
+        obbInfo->writeToParcel(&data);
         if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
             ALOGD("mountObb could not contact remote\n");
             return;
diff --git a/libs/storage/ObbInfo.cpp b/libs/storage/ObbInfo.cpp
new file mode 100644
index 0000000..1bb6b3a
--- /dev/null
+++ b/libs/storage/ObbInfo.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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/ObbInfo.h>
+
+#include <binder/Parcel.h>
+#include <utils/String16.h>
+#include <sys/types.h>
+
+namespace android {
+
+ObbInfo::ObbInfo(const String16 fileName, const String16 packageName, int32_t version,
+        int32_t flags, size_t saltSize, const uint8_t* salt) : mFileName(fileName),
+        mPackageName(packageName), mVersion(version), mFlags(flags), mSaltSize(saltSize),
+        mSalt(salt) {}
+
+ObbInfo::~ObbInfo() {}
+
+status_t ObbInfo::readFromParcel(const Parcel*) {
+    return INVALID_OPERATION;
+}
+
+status_t ObbInfo::writeToParcel(Parcel* p) const {
+    // Parcel write code must be kept in sync with
+    // frameworks/base/core/java/android/content/res/ObbInfo.java
+    p->writeString16(mFileName);
+    p->writeString16(mPackageName);
+    p->writeInt32(mVersion);
+    p->writeInt32(mFlags);
+    p->writeByteArray(mSaltSize, mSalt);
+    return OK;
+}
+
+}; // namespace android
\ No newline at end of file
diff --git a/libs/storage/include/storage/IMountService.h b/libs/storage/include/storage/IMountService.h
index c3d34d8..2463e02 100644
--- a/libs/storage/include/storage/IMountService.h
+++ b/libs/storage/include/storage/IMountService.h
@@ -20,6 +20,7 @@
 #include <storage/IMountServiceListener.h>
 #include <storage/IMountShutdownObserver.h>
 #include <storage/IObbActionListener.h>
+#include <storage/ObbInfo.h>
 
 #include <utils/String8.h>
 
@@ -64,7 +65,7 @@
     virtual void finishMediaUpdate() = 0;
     virtual void mountObb(const String16& rawPath, const String16& canonicalPath,
             const String16& key, const sp<IObbActionListener>& token,
-            const int32_t nonce) = 0;
+            const int32_t nonce, const sp<ObbInfo>& obbInfo) = 0;
     virtual void unmountObb(const String16& filename, const bool force,
             const sp<IObbActionListener>& token, const int32_t nonce) = 0;
     virtual bool isObbMounted(const String16& filename) = 0;
diff --git a/libs/storage/include/storage/ObbInfo.h b/libs/storage/include/storage/ObbInfo.h
new file mode 100644
index 0000000..e4cc353
--- /dev/null
+++ b/libs/storage/include/storage/ObbInfo.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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_OBBINFO_H
+#define ANDROID_OBBINFO_H
+
+#include <binder/Parcelable.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <sys/types.h>
+
+namespace android {
+
+class ObbInfo : public Parcelable, public virtual RefBase {
+
+public:
+    ObbInfo(const String16 fileName, const String16 packageName, int32_t version,
+            int32_t flags, size_t saltSize, const uint8_t* salt);
+    ~ObbInfo();
+
+    status_t writeToParcel(Parcel* parcel) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+    const String16 mFileName;
+    const String16 mPackageName;
+    int32_t mVersion;
+    int32_t mFlags;
+    size_t mSaltSize;
+    const uint8_t* mSalt;
+};
+
+}; // namespace android
+
+#endif // ANDROID_OBBINFO_H
\ No newline at end of file
diff --git a/native/android/storage_manager.cpp b/native/android/storage_manager.cpp
index bf15b8d..2272525 100644
--- a/native/android/storage_manager.cpp
+++ b/native/android/storage_manager.cpp
@@ -18,7 +18,9 @@
 
 #include <android/storage_manager.h>
 #include <storage/IMountService.h>
+#include <storage/ObbInfo.h>
 
+#include <androidfw/ObbFile.h>
 #include <binder/Binder.h>
 #include <binder/IServiceManager.h>
 #include <cutils/atomic.h>
@@ -29,7 +31,6 @@
 #include <utils/Vector.h>
 #include <utils/threads.h>
 
-
 using namespace android;
 
 struct ObbActionListener : public BnObbActionListener {
@@ -79,6 +80,20 @@
         return cb;
     }
 
+    ObbInfo* getObbInfo(char* canonicalPath) {
+        sp<ObbFile> obbFile = new ObbFile();
+        if (!obbFile->readFrom(canonicalPath)) {
+            return nullptr;
+        }
+
+        String16 fileName(obbFile->getFileName());
+        String16 packageName(obbFile->getPackageName());
+        size_t length;
+        const unsigned char* salt = obbFile->getSalt(&length);
+        return new ObbInfo(fileName, packageName,
+                obbFile->getVersion(), obbFile->getFlags(), length, salt);
+    }
+
 public:
     AStorageManager()
     {
@@ -134,11 +149,18 @@
             return;
         }
 
+        sp<ObbInfo> obbInfo = getObbInfo(canonicalPath);
+        if (obbInfo == nullptr) {
+            ALOGE("Couldn't get obb info for %s: %s", canonicalPath, strerror(errno));
+            return;
+        }
+
         ObbCallback* cb = registerObbCallback(func, data);
         String16 rawPath16(rawPath);
         String16 canonicalPath16(canonicalPath);
         String16 key16(key);
-        mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener, cb->nonce);
+        mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener,
+                cb->nonce, obbInfo);
     }
 
     void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1746b85..d505a77 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -44,11 +44,9 @@
 import android.app.admin.SecurityLog;
 import android.app.usage.StorageStatsManager;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.PackageManager;
@@ -115,7 +113,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IMediaContainerService;
 import com.android.internal.os.AppFuseMount;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.FuseUnavailableMountException;
@@ -544,37 +541,7 @@
 
     // OBB action handler messages
     private static final int OBB_RUN_ACTION = 1;
-    private static final int OBB_MCS_BOUND = 2;
-    private static final int OBB_MCS_UNBIND = 3;
-    private static final int OBB_MCS_RECONNECT = 4;
-    private static final int OBB_FLUSH_MOUNT_STATE = 5;
-
-    /*
-     * Default Container Service information
-     */
-    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
-            "com.android.defcontainer", "com.android.defcontainer.DefaultContainerService");
-
-    final private DefaultContainerConnection mDefContainerConn = new DefaultContainerConnection();
-
-    class DefaultContainerConnection implements ServiceConnection {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (DEBUG_OBB)
-                Slog.i(TAG, "onServiceConnected");
-            IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(service);
-            mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_MCS_BOUND, imcs));
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            if (DEBUG_OBB)
-                Slog.i(TAG, "onServiceDisconnected");
-        }
-    }
-
-    // Used in the ObbActionHandler
-    private IMediaContainerService mContainerService = null;
+    private static final int OBB_FLUSH_MOUNT_STATE = 2;
 
     // Last fstrim operation tracking
     private static final String LAST_FSTRIM_FILE = "last-fstrim";
@@ -2305,16 +2272,17 @@
     }
 
     @Override
-    public void mountObb(
-            String rawPath, String canonicalPath, String key, IObbActionListener token, int nonce) {
+    public void mountObb(String rawPath, String canonicalPath, String key,
+            IObbActionListener token, int nonce, ObbInfo obbInfo) {
         Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
         Preconditions.checkNotNull(canonicalPath, "canonicalPath cannot be null");
         Preconditions.checkNotNull(token, "token cannot be null");
+        Preconditions.checkNotNull(obbInfo, "obbIfno cannot be null");
 
         final int callingUid = Binder.getCallingUid();
         final ObbState obbState = new ObbState(rawPath, canonicalPath,
                 callingUid, token, nonce, null);
-        final ObbAction action = new MountObbAction(obbState, key, callingUid);
+        final ObbAction action = new MountObbAction(obbState, key, callingUid, obbInfo);
         mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
 
         if (DEBUG_OBB)
@@ -3217,8 +3185,6 @@
     }
 
     private class ObbActionHandler extends Handler {
-        private boolean mBound = false;
-        private final List<ObbAction> mActions = new LinkedList<ObbAction>();
 
         ObbActionHandler(Looper l) {
             super(l);
@@ -3233,83 +3199,7 @@
                     if (DEBUG_OBB)
                         Slog.i(TAG, "OBB_RUN_ACTION: " + action.toString());
 
-                    // If a bind was already initiated we don't really
-                    // need to do anything. The pending install
-                    // will be processed later on.
-                    if (!mBound) {
-                        // If this is the only one pending we might
-                        // have to bind to the service again.
-                        if (!connectToService()) {
-                            action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                                    "Failed to bind to media container service"));
-                            return;
-                        }
-                    }
-
-                    mActions.add(action);
-                    break;
-                }
-                case OBB_MCS_BOUND: {
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "OBB_MCS_BOUND");
-                    if (msg.obj != null) {
-                        mContainerService = (IMediaContainerService) msg.obj;
-                    }
-                    if (mContainerService == null) {
-                        // Something seriously wrong. Bail out
-                        for (ObbAction action : mActions) {
-                            // Indicate service bind error
-                            action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                                    "Failed to bind to media container service"));
-                        }
-                        mActions.clear();
-                    } else if (mActions.size() > 0) {
-                        final ObbAction action = mActions.get(0);
-                        if (action != null) {
-                            action.execute(this);
-                        }
-                    } else {
-                        // Should never happen ideally.
-                        Slog.w(TAG, "Empty queue");
-                    }
-                    break;
-                }
-                case OBB_MCS_RECONNECT: {
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "OBB_MCS_RECONNECT");
-                    if (mActions.size() > 0) {
-                        if (mBound) {
-                            disconnectService();
-                        }
-                        if (!connectToService()) {
-                            for (ObbAction action : mActions) {
-                                // Indicate service bind error
-                                action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                                        "Failed to bind to media container service"));
-                            }
-                            mActions.clear();
-                        }
-                    }
-                    break;
-                }
-                case OBB_MCS_UNBIND: {
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "OBB_MCS_UNBIND");
-
-                    // Delete pending install
-                    if (mActions.size() > 0) {
-                        mActions.remove(0);
-                    }
-                    if (mActions.size() == 0) {
-                        if (mBound) {
-                            disconnectService();
-                        }
-                    } else {
-                        // There are more pending requests in queue.
-                        // Just post MCS_BOUND message to trigger processing
-                        // of next pending install.
-                        mObbActionHandler.sendEmptyMessage(OBB_MCS_BOUND);
-                    }
+                    action.execute(this);
                     break;
                 }
                 case OBB_FLUSH_MOUNT_STATE: {
@@ -3354,25 +3244,6 @@
                 }
             }
         }
-
-        private boolean connectToService() {
-            if (DEBUG_OBB)
-                Slog.i(TAG, "Trying to bind to DefaultContainerService");
-
-            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
-            if (mContext.bindServiceAsUser(service, mDefContainerConn, Context.BIND_AUTO_CREATE,
-                    UserHandle.SYSTEM)) {
-                mBound = true;
-                return true;
-            }
-            return false;
-        }
-
-        private void disconnectService() {
-            mContainerService = null;
-            mBound = false;
-            mContext.unbindService(mDefContainerConn);
-        }
     }
 
     private static class ObbException extends Exception {
@@ -3390,8 +3261,6 @@
     }
 
     abstract class ObbAction {
-        private static final int MAX_RETRIES = 3;
-        private int mRetries;
 
         ObbState mObbState;
 
@@ -3403,40 +3272,14 @@
             try {
                 if (DEBUG_OBB)
                     Slog.i(TAG, "Starting to execute action: " + toString());
-                mRetries++;
-                if (mRetries > MAX_RETRIES) {
-                    mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
-                    notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                            "Failed to bind to media container service"));
-                } else {
-                    handleExecute();
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "Posting install MCS_UNBIND");
-                    mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
-                }
+                handleExecute();
             } catch (ObbException e) {
                 notifyObbStateChange(e);
-                mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
             }
         }
 
         abstract void handleExecute() throws ObbException;
 
-        protected ObbInfo getObbInfo() throws ObbException {
-            final ObbInfo obbInfo;
-            try {
-                obbInfo = mContainerService.getObbInfo(mObbState.canonicalPath);
-            } catch (Exception e) {
-                throw new ObbException(ERROR_PERMISSION_DENIED, e);
-            }
-            if (obbInfo != null) {
-                return obbInfo;
-            } else {
-                throw new ObbException(ERROR_INTERNAL,
-                        "Missing OBB info for: " + mObbState.canonicalPath);
-            }
-        }
-
         protected void notifyObbStateChange(ObbException e) {
             Slog.w(TAG, e);
             notifyObbStateChange(e.status);
@@ -3458,22 +3301,22 @@
     class MountObbAction extends ObbAction {
         private final String mKey;
         private final int mCallingUid;
+        private ObbInfo mObbInfo;
 
-        MountObbAction(ObbState obbState, String key, int callingUid) {
+        MountObbAction(ObbState obbState, String key, int callingUid, ObbInfo obbInfo) {
             super(obbState);
             mKey = key;
             mCallingUid = callingUid;
+            mObbInfo = obbInfo;
         }
 
         @Override
         public void handleExecute() throws ObbException {
             warnOnNotMounted();
 
-            final ObbInfo obbInfo = getObbInfo();
-
-            if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mCallingUid)) {
+            if (!isUidOwnerOfPackageOrSystem(mObbInfo.packageName, mCallingUid)) {
                 throw new ObbException(ERROR_PERMISSION_DENIED, "Denied attempt to mount OBB "
-                        + obbInfo.filename + " which is owned by " + obbInfo.packageName);
+                        + mObbInfo.filename + " which is owned by " + mObbInfo.packageName);
             }
 
             final boolean isMounted;
@@ -3482,7 +3325,7 @@
             }
             if (isMounted) {
                 throw new ObbException(ERROR_ALREADY_MOUNTED,
-                        "Attempt to mount OBB which is already mounted: " + obbInfo.filename);
+                        "Attempt to mount OBB which is already mounted: " + mObbInfo.filename);
             }
 
             final String hashedKey;
@@ -3494,7 +3337,7 @@
                 try {
                     SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
 
-                    KeySpec ks = new PBEKeySpec(mKey.toCharArray(), obbInfo.salt,
+                    KeySpec ks = new PBEKeySpec(mKey.toCharArray(), mObbInfo.salt,
                             PBKDF2_HASH_ROUNDS, CRYPTO_ALGORITHM_KEY_SIZE);
                     SecretKey key = factory.generateSecret(ks);
                     BigInteger bi = new BigInteger(key.getEncoded());
diff --git a/services/tests/servicestests/src/com/android/server/MountServiceTests.java b/services/tests/servicestests/src/com/android/server/MountServiceTests.java
index ecfe0db..b1b3174 100644
--- a/services/tests/servicestests/src/com/android/server/MountServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/MountServiceTests.java
@@ -220,7 +220,12 @@
 
         final File outFile = getFilePath("test1_nosig.obb");
 
-        mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
+        try {
+            mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
+            fail("mountObb should've failed with an exception");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
 
         assertFalse("OBB should not be mounted",
                 sm.isObbMounted(outFile.getPath()));