Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bb7a1df authored by Kenny Root's avatar Kenny Root Committed by Android Git Automerger
Browse files

am b4de3dca: Merge "OBB: rearrange to be entirely asynchronous" into gingerbread

Merge commit 'b4de3dca' into gingerbread-plus-aosp

* commit 'b4de3dca':
  OBB: rearrange to be entirely asynchronous
parents 0ad4a77c b4de3dca
Loading
Loading
Loading
Loading
+89 −3
Original line number Diff line number Diff line
@@ -133777,9 +133777,97 @@
>
<parameter name="path" type="java.lang.String">
</parameter>
<parameter name="state" type="java.lang.String">
<parameter name="state" type="int">
</parameter>
</method>
<field name="ERROR_ALREADY_MOUNTED"
 type="int"
 transient="false"
 volatile="false"
 value="24"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ERROR_COULD_NOT_MOUNT"
 type="int"
 transient="false"
 volatile="false"
 value="21"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ERROR_COULD_NOT_UNMOUNT"
 type="int"
 transient="false"
 volatile="false"
 value="22"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ERROR_INTERNAL"
 type="int"
 transient="false"
 volatile="false"
 value="20"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ERROR_NOT_MOUNTED"
 type="int"
 transient="false"
 volatile="false"
 value="23"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ERROR_PERMISSION_DENIED"
 type="int"
 transient="false"
 volatile="false"
 value="25"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="MOUNTED"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="UNMOUNTED"
 type="int"
 transient="false"
 volatile="false"
 value="2"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
</class>
<class name="StorageManager"
 extends="java.lang.Object"
@@ -133814,8 +133902,6 @@
>
<parameter name="filename" type="java.lang.String">
</parameter>
<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
</exception>
</method>
<method name="mountObb"
 return="boolean"
+13 −7
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ public interface IMountService extends IInterface {
             * IObbActionListener to inform it of the terminal state of the
             * call.
             */
            public void mountObb(String filename, String key, IObbActionListener token)
            public void mountObb(String filename, String key, IObbActionListener token, int nonce)
                    throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
@@ -493,6 +493,7 @@ public interface IMountService extends IInterface {
                    _data.writeString(filename);
                    _data.writeString(key);
                    _data.writeStrongBinder((token != null ? token.asBinder() : null));
                    _data.writeInt(nonce);
                    mRemote.transact(Stub.TRANSACTION_mountObb, _data, _reply, 0);
                    _reply.readException();
                } finally {
@@ -508,8 +509,8 @@ public interface IMountService extends IInterface {
             * IObbActionListener to inform it of the terminal state of the
             * call.
             */
            public void unmountObb(String filename, boolean force, IObbActionListener token)
                    throws RemoteException {
            public void unmountObb(String filename, boolean force, IObbActionListener token,
                    int nonce) throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
                try {
@@ -517,6 +518,7 @@ public interface IMountService extends IInterface {
                    _data.writeString(filename);
                    _data.writeInt((force ? 1 : 0));
                    _data.writeStrongBinder((token != null ? token.asBinder() : null));
                    _data.writeInt(nonce);
                    mRemote.transact(Stub.TRANSACTION_unmountObb, _data, _reply, 0);
                    _reply.readException();
                } finally {
@@ -855,7 +857,9 @@ public interface IMountService extends IInterface {
                    key = data.readString();
                    IObbActionListener observer;
                    observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
                    mountObb(filename, key, observer);
                    int nonce;
                    nonce = data.readInt();
                    mountObb(filename, key, observer, nonce);
                    reply.writeNoException();
                    return true;
                }
@@ -867,7 +871,9 @@ public interface IMountService extends IInterface {
                    force = 0 != data.readInt();
                    IObbActionListener observer;
                    observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
                    unmountObb(filename, force, observer);
                    int nonce;
                    nonce = data.readInt();
                    unmountObb(filename, force, observer, nonce);
                    reply.writeNoException();
                    return true;
                }
@@ -979,7 +985,7 @@ public interface IMountService extends IInterface {
     * 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)
    public void mountObb(String filename, String key, IObbActionListener token, int nonce)
            throws RemoteException;

    /*
@@ -1023,7 +1029,7 @@ public interface IMountService extends IInterface {
     * 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)
    public void unmountObb(String filename, boolean force, IObbActionListener token, int nonce)
            throws RemoteException;

    /*
+12 −7
Original line number Diff line number Diff line
@@ -69,9 +69,11 @@ public interface IObbActionListener extends IInterface {
                    data.enforceInterface(DESCRIPTOR);
                    String filename;
                    filename = data.readString();
                    String status;
                    status = data.readString();
                    this.onObbResult(filename, status);
                    int nonce;
                    nonce = data.readInt();
                    int status;
                    status = data.readInt();
                    this.onObbResult(filename, nonce, status);
                    reply.writeNoException();
                    return true;
                }
@@ -101,13 +103,15 @@ public interface IObbActionListener extends IInterface {
             *            on
             * @param returnCode status of the operation
             */
            public void onObbResult(String filename, String status) throws RemoteException {
            public void onObbResult(String filename, int nonce, int status)
                    throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(filename);
                    _data.writeString(status);
                    _data.writeInt(nonce);
                    _data.writeInt(status);
                    mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply, 0);
                    _reply.readException();
                } finally {
@@ -124,7 +128,8 @@ public interface IObbActionListener extends IInterface {
     * Return from an OBB action result.
     * 
     * @param filename the path to the OBB the operation was performed on
     * @param returnCode status of the operation
     * @param nonce identifier that is meaningful to the receiver
     * @param status status code as defined in {@link OnObbStateChangeListener}
     */
    public void onObbResult(String filename, String status) throws RemoteException;
    public void onObbResult(String filename, int nonce, int status) throws RemoteException;
}
+56 −2
Original line number Diff line number Diff line
@@ -17,15 +17,69 @@
package android.os.storage;

/**
 * Used for receiving notifications from {@link StorageManager}.
 * Used for receiving notifications from {@link StorageManager} about OBB file
 * states.
 */
public abstract class OnObbStateChangeListener {

    /**
     * The OBB container is now mounted and ready for use. Returned in status
     * messages from calls made via {@link StorageManager}
     */
    public static final int MOUNTED = 1;

    /**
     * The OBB container is now unmounted and not usable. Returned in status
     * messages from calls made via {@link StorageManager}
     */
    public static final int UNMOUNTED = 2;

    /**
     * There was an internal system error encountered while trying to mount the
     * OBB. Returned in status messages from calls made via
     * {@link StorageManager}
     */
    public static final int ERROR_INTERNAL = 20;

    /**
     * The OBB could not be mounted by the system. Returned in status messages
     * from calls made via {@link StorageManager}
     */
    public static final int ERROR_COULD_NOT_MOUNT = 21;

    /**
     * The OBB could not be unmounted. This most likely indicates that a file is
     * in use on the OBB. Returned in status messages from calls made via
     * {@link StorageManager}
     */
    public static final int ERROR_COULD_NOT_UNMOUNT = 22;

    /**
     * A call was made to unmount the OBB when it was not mounted. Returned in
     * status messages from calls made via {@link StorageManager}
     */
    public static final int ERROR_NOT_MOUNTED = 23;

    /**
     * The OBB has already been mounted. Returned in status messages from calls
     * made via {@link StorageManager}
     */
    public static final int ERROR_ALREADY_MOUNTED = 24;

    /**
     * The current application does not have permission to use this OBB because
     * the OBB indicates it's owned by a different package or the key used to
     * open it is incorrect. Returned in status messages from calls made via
     * {@link StorageManager}
     */
    public static final int ERROR_PERMISSION_DENIED = 25;

    /**
     * Called when an OBB has changed states.
     * 
     * @param path path to the OBB file the state change has happened on
     * @param state the current state of the OBB
     */
    public void onObbStateChange(String path, String state) {
    public void onObbStateChange(String path, int state) {
    }
}
+70 −59
Original line number Diff line number Diff line
@@ -22,12 +22,13 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * StorageManager is the interface to the systems storage service. The storage
@@ -69,7 +70,12 @@ public class StorageManager
    /*
     * List of our listeners
     */
    private ArrayList<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>();
    private List<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>();

    /*
     * Next available nonce
     */
    final private AtomicInteger mNextNonce = new AtomicInteger(0);

    private class MountServiceBinderListener extends IMountServiceListener.Stub {
        public void onUsbMassStorageConnectionChanged(boolean available) {
@@ -93,55 +99,36 @@ public class StorageManager
    private final ObbActionListener mObbActionListener = new ObbActionListener();

    private class ObbActionListener extends IObbActionListener.Stub {
        private List<WeakReference<ObbListenerDelegate>> mListeners = new LinkedList<WeakReference<ObbListenerDelegate>>();
        private SparseArray<ObbListenerDelegate> mListeners = new SparseArray<ObbListenerDelegate>();

        @Override
        public void onObbResult(String filename, String status) throws RemoteException {
        public void onObbResult(String filename, int nonce, int status) throws RemoteException {
            final ObbListenerDelegate delegate;
            synchronized (mListeners) {
                final Iterator<WeakReference<ObbListenerDelegate>> iter = mListeners.iterator();
                while (iter.hasNext()) {
                    final WeakReference<ObbListenerDelegate> ref = iter.next();

                    final ObbListenerDelegate delegate = (ref == null) ? null : ref.get();
                    if (delegate == null) {
                        iter.remove();
                        continue;
                delegate = mListeners.get(nonce);
                if (delegate != null) {
                    mListeners.remove(nonce);
                }
            }

            if (delegate != null) {
                delegate.sendObbStateChanged(filename, status);
            }
        }
        }

        public void addListener(OnObbStateChangeListener listener) {
            if (listener == null) {
                return;
            }
        public int addListener(OnObbStateChangeListener listener) {
            final ObbListenerDelegate delegate = new ObbListenerDelegate(listener);

            synchronized (mListeners) {
                final Iterator<WeakReference<ObbListenerDelegate>> iter = mListeners.iterator();
                while (iter.hasNext()) {
                    final WeakReference<ObbListenerDelegate> ref = iter.next();

                    final ObbListenerDelegate delegate = (ref == null) ? null : ref.get();
                    if (delegate == null) {
                        iter.remove();
                        continue;
                mListeners.put(delegate.nonce, delegate);
            }

                    /*
                     * If we're already in the listeners, we don't need to be in
                     * there again.
                     */
                    if (listener.equals(delegate.getListener())) {
                        return;
            return delegate.nonce;
        }
    }

                final ObbListenerDelegate delegate = new ObbListenerDelegate(listener);
                mListeners.add(new WeakReference<ObbListenerDelegate>(delegate));
            }
        }
    private int getNextNonce() {
        return mNextNonce.getAndIncrement();
    }

    /**
@@ -151,7 +138,10 @@ public class StorageManager
        private final WeakReference<OnObbStateChangeListener> mObbEventListenerRef;
        private final Handler mHandler;

        private final int nonce;

        ObbListenerDelegate(OnObbStateChangeListener listener) {
            nonce = getNextNonce();
            mObbEventListenerRef = new WeakReference<OnObbStateChangeListener>(listener);
            mHandler = new Handler(mTgtLooper) {
                @Override
@@ -180,7 +170,7 @@ public class StorageManager
            return mObbEventListenerRef.get();
        }

        void sendObbStateChanged(String path, String state) {
        void sendObbStateChanged(String path, int state) {
            ObbStateChangedStorageEvent e = new ObbStateChangedStorageEvent(path, state);
            mHandler.sendMessage(e.getMessage());
        }
@@ -191,9 +181,10 @@ public class StorageManager
     */
    private class ObbStateChangedStorageEvent extends StorageEvent {
        public final String path;
        public final String state;

        public ObbStateChangedStorageEvent(String path, String state) {
        public final int state;

        public ObbStateChangedStorageEvent(String path, int state) {
            super(EVENT_OBB_STATE_CHANGED);
            this.path = path;
            this.state = state;
@@ -420,10 +411,8 @@ public class StorageManager
     * <p>
     * The OBB will remain mounted for as long as the StorageManager reference
     * is held by the application. As soon as this reference is lost, the OBBs
     * in use will be unmounted. The {@link OnObbStateChangeListener} registered with
     * this call will receive all further OBB-related events until it goes out
     * of scope. If the caller is not interested in whether the call succeeds,
     * the <code>listener</code> may be specified as <code>null</code>.
     * in use will be unmounted. The {@link OnObbStateChangeListener} registered
     * with this call will receive the success or failure of this operation.
     * <p>
     * <em>Note:</em> you can only mount OBB files for which the OBB tag on the
     * file matches a package ID that is owned by the calling program's UID.
@@ -433,12 +422,21 @@ public class StorageManager
     * @param filename the path to the OBB file
     * @param key secret used to encrypt the OBB; may be <code>null</code> if no
     *            encryption was used on the OBB.
     * @param listener will receive the success or failure of the operation
     * @return whether the mount call was successfully queued or not
     */
    public boolean mountObb(String filename, String key, OnObbStateChangeListener listener) {
        if (filename == null) {
            throw new IllegalArgumentException("filename cannot be null");
        }

        if (listener == null) {
            throw new IllegalArgumentException("listener cannot be null");
        }

        try {
            mObbActionListener.addListener(listener);
            mMountService.mountObb(filename, key, mObbActionListener);
            final int nonce = mObbActionListener.addListener(listener);
            mMountService.mountObb(filename, key, mObbActionListener, nonce);
            return true;
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to mount OBB", e);
@@ -452,10 +450,8 @@ public class StorageManager
     * <code>force</code> flag is true, it will kill any application needed to
     * unmount the given OBB (even the calling application).
     * <p>
     * The {@link OnObbStateChangeListener} registered with this call will receive all
     * further OBB-related events until it goes out of scope. If the caller is
     * not interested in whether the call succeeded, the listener may be
     * specified as <code>null</code>.
     * The {@link OnObbStateChangeListener} registered with this call will
     * receive the success or failure of this operation.
     * <p>
     * <em>Note:</em> you can only mount OBB files for which the OBB tag on the
     * file matches a package ID that is owned by the calling program's UID.
@@ -466,12 +462,21 @@ public class StorageManager
     * @param filename path to the OBB file
     * @param force whether to kill any programs using this in order to unmount
     *            it
     * @param listener will receive the success or failure of the operation
     * @return whether the unmount call was successfully queued or not
     */
    public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) {
        if (filename == null) {
            throw new IllegalArgumentException("filename cannot be null");
        }

        if (listener == null) {
            throw new IllegalArgumentException("listener cannot be null");
        }

        try {
            mObbActionListener.addListener(listener);
            mMountService.unmountObb(filename, force, mObbActionListener);
            final int nonce = mObbActionListener.addListener(listener);
            mMountService.unmountObb(filename, force, mObbActionListener, nonce);
            return true;
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to mount OBB", e);
@@ -486,7 +491,11 @@ public class StorageManager
     * @param filename path to OBB image
     * @return true if OBB is mounted; false if not mounted or on error
     */
    public boolean isObbMounted(String filename) throws IllegalArgumentException {
    public boolean isObbMounted(String filename) {
        if (filename == null) {
            throw new IllegalArgumentException("filename cannot be null");
        }

        try {
            return mMountService.isObbMounted(filename);
        } catch (RemoteException e) {
@@ -506,12 +515,14 @@ public class StorageManager
     *         not mounted or exception encountered trying to read status
     */
    public String getMountedObbPath(String filename) {
        if (filename == null) {
            throw new IllegalArgumentException("filename cannot be null");
        }

        try {
            return mMountService.getMountedObbPath(filename);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to find mounted path for OBB", e);
        } catch (IllegalArgumentException e) {
            Log.d(TAG, "Couldn't read OBB file", e);
        }

        return null;
Loading