Loading api/current.xml +10 −2 Original line number Diff line number Diff line Loading @@ -52732,6 +52732,16 @@ visibility="public" > </field> <field name="filename" type="java.lang.String" transient="false" volatile="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </field> <field name="flags" type="int" transient="false" Loading Loading @@ -130946,8 +130956,6 @@ </parameter> <parameter name="listener" type="android.os.storage.OnObbStateChangeListener"> </parameter> <exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> </exception> </method> </class> </package> core/java/android/content/res/ObbInfo.java +7 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ public class ObbInfo implements Parcelable { /** Flag noting that this OBB is an overlay patch for a base OBB. */ public static final int OBB_OVERLAY = 1 << 0; /** * The canonical filename of the OBB. */ public String filename; /** * The name of the package to which the OBB file belongs. */ Loading Loading @@ -66,6 +71,7 @@ public class ObbInfo implements Parcelable { } public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeString(filename); dest.writeString(packageName); dest.writeInt(version); dest.writeInt(flags); Loading @@ -83,6 +89,7 @@ public class ObbInfo implements Parcelable { }; private ObbInfo(Parcel source) { filename = source.readString(); packageName = source.readString(); version = source.readInt(); flags = source.readInt(); Loading core/java/android/content/res/ObbScanner.java +5 −0 Original line number Diff line number Diff line Loading @@ -45,9 +45,14 @@ public class ObbScanner { throw new IllegalArgumentException("OBB file does not exist: " + filePath); } /* * XXX This will fail to find the real canonical path if bind mounts are * used, but we don't use any bind mounts right now. */ final String canonicalFilePath = obbFile.getCanonicalPath(); ObbInfo obbInfo = new ObbInfo(); obbInfo.filename = canonicalFilePath; getObbInfo_native(canonicalFilePath, obbInfo); return obbInfo; Loading core/java/android/os/storage/StorageManager.java +1 −4 Original line number Diff line number Diff line Loading @@ -434,7 +434,6 @@ public class StorageManager * @param key secret used to encrypt the OBB; may be <code>null</code> if no * encryption was used on the OBB. * @return whether the mount call was successfully queued or not * @throws IllegalArgumentException when the OBB is already mounted */ public boolean mountObb(String filename, String key, OnObbStateChangeListener listener) { try { Loading Loading @@ -468,10 +467,8 @@ public class StorageManager * @param force whether to kill any programs using this in order to unmount * it * @return whether the unmount call was successfully queued or not * @throws IllegalArgumentException when OBB is not already mounted */ public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) throws IllegalArgumentException { public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) { try { mObbActionListener.addListener(listener); mMountService.unmountObb(filename, force, mObbActionListener); Loading services/java/com/android/server/MountService.java +230 −60 Original line number Diff line number Diff line Loading @@ -46,13 +46,18 @@ import android.os.storage.IObbActionListener; import android.os.storage.StorageResultCode; import android.util.Slog; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * MountService implements back-end services for platform storage Loading Loading @@ -181,6 +186,22 @@ class MountService extends IMountService.Stub token.asBinder().unlinkToDeath(this, 0); } @Override public String toString() { StringBuilder sb = new StringBuilder("ObbState{"); sb.append("filename="); sb.append(filename); sb.append(",token="); sb.append(token.toString()); sb.append(",callerUid="); sb.append(callerUid); sb.append(",mounted="); sb.append(mounted); sb.append('}'); return sb.toString(); } } // OBB Action Handler Loading Loading @@ -475,6 +496,34 @@ class MountService extends IMountService.Stub } else if (Environment.MEDIA_MOUNTED.equals(state)) { mPms.updateExternalMediaStatus(true, false); } // Remove all OBB mappings and listeners from this path synchronized (mObbMounts) { final List<ObbState> obbStatesToRemove = new LinkedList<ObbState>(); final Iterator<Entry<String, ObbState>> i = mObbPathToStateMap.entrySet().iterator(); while (i.hasNext()) { final Entry<String, ObbState> obbEntry = i.next(); // If this entry's source file is in the volume path that got // unmounted, remove it because it's no longer valid. if (obbEntry.getKey().startsWith(path)) { obbStatesToRemove.add(obbEntry.getValue()); } } for (final ObbState obbState : obbStatesToRemove) { removeObbState(obbState); try { obbState.token.onObbResult(obbState.filename, Environment.MEDIA_UNMOUNTED); } catch (RemoteException e) { Slog.i(TAG, "Couldn't send unmount notification for OBB: " + obbState.filename); } } } String oldState = mLegacyState; mLegacyState = state; Loading Loading @@ -1494,9 +1543,15 @@ class MountService extends IMountService.Stub public boolean isObbMounted(String filename) { synchronized (mObbMounts) { return mObbPathToStateMap.containsKey(filename); final ObbState obbState = mObbPathToStateMap.get(filename); if (obbState != null) { synchronized (obbState) { return obbState.mounted; } } } return false; } public void mountObb(String filename, String key, IObbActionListener token) { waitForReady(); Loading @@ -1512,7 +1567,12 @@ class MountService extends IMountService.Stub synchronized (mObbMounts) { if (isObbMounted(filename)) { throw new IllegalArgumentException("OBB file is already mounted"); try { token.onObbResult(filename, Environment.MEDIA_MOUNTED); } catch (RemoteException e) { Slog.d(TAG, "Could not send unmount notification for: " + filename); } return; } final int callerUid = Binder.getCallingUid(); Loading @@ -1526,7 +1586,7 @@ class MountService extends IMountService.Stub Slog.e(TAG, "Failed to link to listener death"); } MountObbAction action = new MountObbAction(obbState, key); ObbAction action = new MountObbAction(obbState, key); mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action)); if (DEBUG_OBB) Loading @@ -1544,8 +1604,14 @@ class MountService extends IMountService.Stub synchronized (mObbMounts) { if (!isObbMounted(filename)) { throw new IllegalArgumentException("OBB is not mounted"); try { token.onObbResult(filename, Environment.MEDIA_UNMOUNTED); } catch (RemoteException e) { Slog.d(TAG, "Could not send unmount notification for: " + filename); } return; } obbState = mObbPathToStateMap.get(filename); if (Binder.getCallingUid() != obbState.callerUid) { Loading @@ -1555,7 +1621,7 @@ class MountService extends IMountService.Stub } } UnmountObbAction action = new UnmountObbAction(obbState, force); ObbAction action = new UnmountObbAction(obbState, force); mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action)); if (DEBUG_OBB) Loading Loading @@ -1587,6 +1653,13 @@ class MountService extends IMountService.Stub } } private void replaceObbState(ObbState oldObbState, ObbState newObbState) { synchronized (mObbMounts) { removeObbState(oldObbState); addObbState(newObbState); } } private class ObbActionHandler extends Handler { private boolean mBound = false; private List<ObbAction> mActions = new LinkedList<ObbAction>(); Loading Loading @@ -1760,6 +1833,29 @@ class MountService extends IMountService.Stub abstract void handleExecute() throws RemoteException, IOException; abstract void handleError(); protected ObbInfo getObbInfo() throws IOException { ObbInfo obbInfo; try { obbInfo = mContainerService.getObbInfo(mObbState.filename); } catch (RemoteException e) { Slog.d(TAG, "Couldn't call DefaultContainerService to fetch OBB info for " + mObbState.filename); obbInfo = null; } if (obbInfo == null) { throw new IOException("Couldn't read OBB file: " + mObbState.filename); } return obbInfo; } protected void sendNewStatusOrIgnore(String filename, String status) { try { mObbState.token.onObbResult(filename, status); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); } } } class MountObbAction extends ObbAction { Loading @@ -1770,10 +1866,42 @@ class MountService extends IMountService.Stub mKey = key; } public void handleExecute() throws RemoteException, IOException { final ObbInfo obbInfo = mContainerService.getObbInfo(mObbState.filename); if (obbInfo == null) { throw new IOException("Couldn't read OBB file: " + mObbState.filename); public void handleExecute() throws IOException { final ObbInfo obbInfo = getObbInfo(); /* * If someone tried to trick us with some weird characters, rectify * it here. */ if (!mObbState.filename.equals(obbInfo.filename)) { if (DEBUG_OBB) Slog.i(TAG, "OBB filename " + mObbState.filename + " is actually " + obbInfo.filename); synchronized (mObbMounts) { /* * If the real filename is already mounted, discard this * state and notify the caller that the OBB is already * mounted. */ if (isObbMounted(obbInfo.filename)) { if (DEBUG_OBB) Slog.i(TAG, "OBB already mounted as " + obbInfo.filename); removeObbState(mObbState); sendNewStatusOrIgnore(obbInfo.filename, Environment.MEDIA_MOUNTED); return; } /* * It's not already mounted, so we have to replace the state * with the state containing the actual filename. */ ObbState newObbState = new ObbState(obbInfo.filename, mObbState.token, mObbState.callerUid); replaceObbState(mObbState, newObbState); mObbState = newObbState; } } if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mObbState.callerUid)) { Loading @@ -1784,7 +1912,15 @@ class MountService extends IMountService.Stub mKey = "none"; } int rc = StorageResultCode.OperationSucceeded; boolean mounted = false; int rc; synchronized (mObbState) { if (mObbState.mounted) { sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED); return; } rc = StorageResultCode.OperationSucceeded; String cmd = String.format("obb mount %s %s %d", mObbState.filename, mKey, mObbState.callerUid); try { Loading @@ -1797,29 +1933,26 @@ class MountService extends IMountService.Stub } if (rc == StorageResultCode.OperationSucceeded) { try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_MOUNTED); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); mObbState.mounted = mounted = true; } } if (mounted) { sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED); } else { Slog.e(TAG, "Couldn't mount OBB file: " + rc); // We didn't succeed, so remove this from the mount-set. removeObbState(mObbState); mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED); } } public void handleError() { removeObbState(mObbState); try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } catch (RemoteException e) { Slog.e(TAG, "Couldn't send back OBB mount error for " + mObbState.filename); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } @Override Loading @@ -1845,10 +1978,31 @@ class MountService extends IMountService.Stub mForceUnmount = force; } public void handleExecute() throws RemoteException, IOException { final ObbInfo obbInfo = mContainerService.getObbInfo(mObbState.filename); if (obbInfo == null) { throw new IOException("Couldn't read OBB file: " + mObbState.filename); public void handleExecute() throws IOException { final ObbInfo obbInfo = getObbInfo(); /* * If someone tried to trick us with some weird characters, rectify * it here. */ synchronized (mObbMounts) { if (!isObbMounted(obbInfo.filename)) { removeObbState(mObbState); sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED); return; } if (!mObbState.filename.equals(obbInfo.filename)) { removeObbState(mObbState); mObbState = mObbPathToStateMap.get(obbInfo.filename); } } boolean unmounted = false; synchronized (mObbState) { if (!mObbState.mounted) { sendNewStatusOrIgnore(obbInfo.filename, Environment.MEDIA_UNMOUNTED); return; } int rc = StorageResultCode.OperationSucceeded; Loading @@ -1866,30 +2020,24 @@ class MountService extends IMountService.Stub } if (rc == StorageResultCode.OperationSucceeded) { mObbState.mounted = false; unmounted = true; } } if (unmounted) { removeObbState(mObbState); try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_UNMOUNTED); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED); } else { try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED); } } public void handleError() { removeObbState(mObbState); try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } catch (RemoteException e) { Slog.e(TAG, "Couldn't send back OBB unmount error for " + mObbState.filename); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } @Override Loading @@ -1908,5 +2056,27 @@ class MountService extends IMountService.Stub return sb.toString(); } } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { pw.println("Permission Denial: can't dump ActivityManager from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " without permission " + android.Manifest.permission.DUMP); return; } pw.println(" mObbMounts:"); synchronized (mObbMounts) { final Collection<List<ObbState>> obbStateLists = mObbMounts.values(); for (final List<ObbState> obbStates : obbStateLists) { for (final ObbState obbState : obbStates) { pw.print(" "); pw.println(obbState.toString()); } } } } } Loading
api/current.xml +10 −2 Original line number Diff line number Diff line Loading @@ -52732,6 +52732,16 @@ visibility="public" > </field> <field name="filename" type="java.lang.String" transient="false" volatile="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </field> <field name="flags" type="int" transient="false" Loading Loading @@ -130946,8 +130956,6 @@ </parameter> <parameter name="listener" type="android.os.storage.OnObbStateChangeListener"> </parameter> <exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> </exception> </method> </class> </package>
core/java/android/content/res/ObbInfo.java +7 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ public class ObbInfo implements Parcelable { /** Flag noting that this OBB is an overlay patch for a base OBB. */ public static final int OBB_OVERLAY = 1 << 0; /** * The canonical filename of the OBB. */ public String filename; /** * The name of the package to which the OBB file belongs. */ Loading Loading @@ -66,6 +71,7 @@ public class ObbInfo implements Parcelable { } public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeString(filename); dest.writeString(packageName); dest.writeInt(version); dest.writeInt(flags); Loading @@ -83,6 +89,7 @@ public class ObbInfo implements Parcelable { }; private ObbInfo(Parcel source) { filename = source.readString(); packageName = source.readString(); version = source.readInt(); flags = source.readInt(); Loading
core/java/android/content/res/ObbScanner.java +5 −0 Original line number Diff line number Diff line Loading @@ -45,9 +45,14 @@ public class ObbScanner { throw new IllegalArgumentException("OBB file does not exist: " + filePath); } /* * XXX This will fail to find the real canonical path if bind mounts are * used, but we don't use any bind mounts right now. */ final String canonicalFilePath = obbFile.getCanonicalPath(); ObbInfo obbInfo = new ObbInfo(); obbInfo.filename = canonicalFilePath; getObbInfo_native(canonicalFilePath, obbInfo); return obbInfo; Loading
core/java/android/os/storage/StorageManager.java +1 −4 Original line number Diff line number Diff line Loading @@ -434,7 +434,6 @@ public class StorageManager * @param key secret used to encrypt the OBB; may be <code>null</code> if no * encryption was used on the OBB. * @return whether the mount call was successfully queued or not * @throws IllegalArgumentException when the OBB is already mounted */ public boolean mountObb(String filename, String key, OnObbStateChangeListener listener) { try { Loading Loading @@ -468,10 +467,8 @@ public class StorageManager * @param force whether to kill any programs using this in order to unmount * it * @return whether the unmount call was successfully queued or not * @throws IllegalArgumentException when OBB is not already mounted */ public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) throws IllegalArgumentException { public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) { try { mObbActionListener.addListener(listener); mMountService.unmountObb(filename, force, mObbActionListener); Loading
services/java/com/android/server/MountService.java +230 −60 Original line number Diff line number Diff line Loading @@ -46,13 +46,18 @@ import android.os.storage.IObbActionListener; import android.os.storage.StorageResultCode; import android.util.Slog; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * MountService implements back-end services for platform storage Loading Loading @@ -181,6 +186,22 @@ class MountService extends IMountService.Stub token.asBinder().unlinkToDeath(this, 0); } @Override public String toString() { StringBuilder sb = new StringBuilder("ObbState{"); sb.append("filename="); sb.append(filename); sb.append(",token="); sb.append(token.toString()); sb.append(",callerUid="); sb.append(callerUid); sb.append(",mounted="); sb.append(mounted); sb.append('}'); return sb.toString(); } } // OBB Action Handler Loading Loading @@ -475,6 +496,34 @@ class MountService extends IMountService.Stub } else if (Environment.MEDIA_MOUNTED.equals(state)) { mPms.updateExternalMediaStatus(true, false); } // Remove all OBB mappings and listeners from this path synchronized (mObbMounts) { final List<ObbState> obbStatesToRemove = new LinkedList<ObbState>(); final Iterator<Entry<String, ObbState>> i = mObbPathToStateMap.entrySet().iterator(); while (i.hasNext()) { final Entry<String, ObbState> obbEntry = i.next(); // If this entry's source file is in the volume path that got // unmounted, remove it because it's no longer valid. if (obbEntry.getKey().startsWith(path)) { obbStatesToRemove.add(obbEntry.getValue()); } } for (final ObbState obbState : obbStatesToRemove) { removeObbState(obbState); try { obbState.token.onObbResult(obbState.filename, Environment.MEDIA_UNMOUNTED); } catch (RemoteException e) { Slog.i(TAG, "Couldn't send unmount notification for OBB: " + obbState.filename); } } } String oldState = mLegacyState; mLegacyState = state; Loading Loading @@ -1494,9 +1543,15 @@ class MountService extends IMountService.Stub public boolean isObbMounted(String filename) { synchronized (mObbMounts) { return mObbPathToStateMap.containsKey(filename); final ObbState obbState = mObbPathToStateMap.get(filename); if (obbState != null) { synchronized (obbState) { return obbState.mounted; } } } return false; } public void mountObb(String filename, String key, IObbActionListener token) { waitForReady(); Loading @@ -1512,7 +1567,12 @@ class MountService extends IMountService.Stub synchronized (mObbMounts) { if (isObbMounted(filename)) { throw new IllegalArgumentException("OBB file is already mounted"); try { token.onObbResult(filename, Environment.MEDIA_MOUNTED); } catch (RemoteException e) { Slog.d(TAG, "Could not send unmount notification for: " + filename); } return; } final int callerUid = Binder.getCallingUid(); Loading @@ -1526,7 +1586,7 @@ class MountService extends IMountService.Stub Slog.e(TAG, "Failed to link to listener death"); } MountObbAction action = new MountObbAction(obbState, key); ObbAction action = new MountObbAction(obbState, key); mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action)); if (DEBUG_OBB) Loading @@ -1544,8 +1604,14 @@ class MountService extends IMountService.Stub synchronized (mObbMounts) { if (!isObbMounted(filename)) { throw new IllegalArgumentException("OBB is not mounted"); try { token.onObbResult(filename, Environment.MEDIA_UNMOUNTED); } catch (RemoteException e) { Slog.d(TAG, "Could not send unmount notification for: " + filename); } return; } obbState = mObbPathToStateMap.get(filename); if (Binder.getCallingUid() != obbState.callerUid) { Loading @@ -1555,7 +1621,7 @@ class MountService extends IMountService.Stub } } UnmountObbAction action = new UnmountObbAction(obbState, force); ObbAction action = new UnmountObbAction(obbState, force); mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action)); if (DEBUG_OBB) Loading Loading @@ -1587,6 +1653,13 @@ class MountService extends IMountService.Stub } } private void replaceObbState(ObbState oldObbState, ObbState newObbState) { synchronized (mObbMounts) { removeObbState(oldObbState); addObbState(newObbState); } } private class ObbActionHandler extends Handler { private boolean mBound = false; private List<ObbAction> mActions = new LinkedList<ObbAction>(); Loading Loading @@ -1760,6 +1833,29 @@ class MountService extends IMountService.Stub abstract void handleExecute() throws RemoteException, IOException; abstract void handleError(); protected ObbInfo getObbInfo() throws IOException { ObbInfo obbInfo; try { obbInfo = mContainerService.getObbInfo(mObbState.filename); } catch (RemoteException e) { Slog.d(TAG, "Couldn't call DefaultContainerService to fetch OBB info for " + mObbState.filename); obbInfo = null; } if (obbInfo == null) { throw new IOException("Couldn't read OBB file: " + mObbState.filename); } return obbInfo; } protected void sendNewStatusOrIgnore(String filename, String status) { try { mObbState.token.onObbResult(filename, status); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); } } } class MountObbAction extends ObbAction { Loading @@ -1770,10 +1866,42 @@ class MountService extends IMountService.Stub mKey = key; } public void handleExecute() throws RemoteException, IOException { final ObbInfo obbInfo = mContainerService.getObbInfo(mObbState.filename); if (obbInfo == null) { throw new IOException("Couldn't read OBB file: " + mObbState.filename); public void handleExecute() throws IOException { final ObbInfo obbInfo = getObbInfo(); /* * If someone tried to trick us with some weird characters, rectify * it here. */ if (!mObbState.filename.equals(obbInfo.filename)) { if (DEBUG_OBB) Slog.i(TAG, "OBB filename " + mObbState.filename + " is actually " + obbInfo.filename); synchronized (mObbMounts) { /* * If the real filename is already mounted, discard this * state and notify the caller that the OBB is already * mounted. */ if (isObbMounted(obbInfo.filename)) { if (DEBUG_OBB) Slog.i(TAG, "OBB already mounted as " + obbInfo.filename); removeObbState(mObbState); sendNewStatusOrIgnore(obbInfo.filename, Environment.MEDIA_MOUNTED); return; } /* * It's not already mounted, so we have to replace the state * with the state containing the actual filename. */ ObbState newObbState = new ObbState(obbInfo.filename, mObbState.token, mObbState.callerUid); replaceObbState(mObbState, newObbState); mObbState = newObbState; } } if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mObbState.callerUid)) { Loading @@ -1784,7 +1912,15 @@ class MountService extends IMountService.Stub mKey = "none"; } int rc = StorageResultCode.OperationSucceeded; boolean mounted = false; int rc; synchronized (mObbState) { if (mObbState.mounted) { sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED); return; } rc = StorageResultCode.OperationSucceeded; String cmd = String.format("obb mount %s %s %d", mObbState.filename, mKey, mObbState.callerUid); try { Loading @@ -1797,29 +1933,26 @@ class MountService extends IMountService.Stub } if (rc == StorageResultCode.OperationSucceeded) { try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_MOUNTED); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); mObbState.mounted = mounted = true; } } if (mounted) { sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED); } else { Slog.e(TAG, "Couldn't mount OBB file: " + rc); // We didn't succeed, so remove this from the mount-set. removeObbState(mObbState); mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED); } } public void handleError() { removeObbState(mObbState); try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } catch (RemoteException e) { Slog.e(TAG, "Couldn't send back OBB mount error for " + mObbState.filename); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } @Override Loading @@ -1845,10 +1978,31 @@ class MountService extends IMountService.Stub mForceUnmount = force; } public void handleExecute() throws RemoteException, IOException { final ObbInfo obbInfo = mContainerService.getObbInfo(mObbState.filename); if (obbInfo == null) { throw new IOException("Couldn't read OBB file: " + mObbState.filename); public void handleExecute() throws IOException { final ObbInfo obbInfo = getObbInfo(); /* * If someone tried to trick us with some weird characters, rectify * it here. */ synchronized (mObbMounts) { if (!isObbMounted(obbInfo.filename)) { removeObbState(mObbState); sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED); return; } if (!mObbState.filename.equals(obbInfo.filename)) { removeObbState(mObbState); mObbState = mObbPathToStateMap.get(obbInfo.filename); } } boolean unmounted = false; synchronized (mObbState) { if (!mObbState.mounted) { sendNewStatusOrIgnore(obbInfo.filename, Environment.MEDIA_UNMOUNTED); return; } int rc = StorageResultCode.OperationSucceeded; Loading @@ -1866,30 +2020,24 @@ class MountService extends IMountService.Stub } if (rc == StorageResultCode.OperationSucceeded) { mObbState.mounted = false; unmounted = true; } } if (unmounted) { removeObbState(mObbState); try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_UNMOUNTED); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED); } else { try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } catch (RemoteException e) { Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged"); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED); } } public void handleError() { removeObbState(mObbState); try { mObbState.token.onObbResult(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } catch (RemoteException e) { Slog.e(TAG, "Couldn't send back OBB unmount error for " + mObbState.filename); } sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_BAD_REMOVAL); } @Override Loading @@ -1908,5 +2056,27 @@ class MountService extends IMountService.Stub return sb.toString(); } } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { pw.println("Permission Denial: can't dump ActivityManager from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " without permission " + android.Manifest.permission.DUMP); return; } pw.println(" mObbMounts:"); synchronized (mObbMounts) { final Collection<List<ObbState>> obbStateLists = mObbMounts.values(); for (final List<ObbState> obbStates : obbStateLists) { for (final ObbState obbState : obbStates) { pw.print(" "); pw.println(obbState.toString()); } } } } }