Loading core/java/android/content/res/ObbInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ public class ObbInfo implements Parcelable { } 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); Loading core/java/android/os/storage/IStorageManager.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -57,7 +58,7 @@ interface IStorageManager { * 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. Loading core/java/android/os/storage/StorageManager.java +13 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import android.content.Intent; 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; Loading Loading @@ -580,7 +582,8 @@ public class StorageManager { 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); Loading @@ -589,6 +592,15 @@ public class StorageManager { } } 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 Loading core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java +4 −91 Original line number Diff line number Diff line Loading @@ -65,95 +65,6 @@ public class StorageManagerBaseTest extends InstrumentationTestCase { + "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"; Loading Loading @@ -362,7 +273,8 @@ public class StorageManagerBaseTest extends InstrumentationTestCase { 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()); Loading @@ -373,7 +285,8 @@ public class StorageManagerBaseTest extends InstrumentationTestCase { 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(); } Loading core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java +6 −46 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.os.ParcelFileDescriptor; import android.os.ProxyFileDescriptorCallback; import android.system.ErrnoException; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import com.android.frameworks.coretests.R; Loading Loading @@ -134,50 +133,6 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest { } } /** * 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. */ Loading @@ -185,7 +140,12 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest { public void testMountUnsignedObb() throws Exception { final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign); String filePath = file.getAbsolutePath(); try { mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL); fail("mountObb should've failed with an exception"); } catch (IllegalArgumentException e) { // Expected } } /** Loading Loading
core/java/android/content/res/ObbInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ public class ObbInfo implements Parcelable { } 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); Loading
core/java/android/os/storage/IStorageManager.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -57,7 +58,7 @@ interface IStorageManager { * 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. Loading
core/java/android/os/storage/StorageManager.java +13 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import android.content.Intent; 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; Loading Loading @@ -580,7 +582,8 @@ public class StorageManager { 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); Loading @@ -589,6 +592,15 @@ public class StorageManager { } } 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 Loading
core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java +4 −91 Original line number Diff line number Diff line Loading @@ -65,95 +65,6 @@ public class StorageManagerBaseTest extends InstrumentationTestCase { + "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"; Loading Loading @@ -362,7 +273,8 @@ public class StorageManagerBaseTest extends InstrumentationTestCase { 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()); Loading @@ -373,7 +285,8 @@ public class StorageManagerBaseTest extends InstrumentationTestCase { 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(); } Loading
core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java +6 −46 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.os.ParcelFileDescriptor; import android.os.ProxyFileDescriptorCallback; import android.system.ErrnoException; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import com.android.frameworks.coretests.R; Loading Loading @@ -134,50 +133,6 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest { } } /** * 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. */ Loading @@ -185,7 +140,12 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest { public void testMountUnsignedObb() throws Exception { final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign); String filePath = file.getAbsolutePath(); try { mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL); fail("mountObb should've failed with an exception"); } catch (IllegalArgumentException e) { // Expected } } /** Loading