Add Media Playing API

These methods permit an activity to play or continue playing media
behind a translucent activity above it. Particularly the home
activity in Android TV. Methods exist to notify the upper activity
when playing starts or stops and for notifying the playing activity
when to stop playing and release its resources.

Methods are called when either activity's state changes or new
activities are launched.

Fixes bug 14469711.

Change-Id: I7ba10c5a4683504931cffa228488f5281e5bbf86
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index ce36fd8..4a70e15 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2176,6 +2176,33 @@
             reply.writeNoException();
             return true;
         }
+
+        case SET_MEDIA_PLAYING_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean enable = data.readInt() > 0;
+            boolean success = setMediaPlaying(token, enable);
+            reply.writeNoException();
+            reply.writeInt(success ? 1 : 0);
+            return true;
+        }
+
+        case IS_BG_MEDIA_PLAYING_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            final boolean enabled = isBackgroundMediaPlaying(token);
+            reply.writeNoException();
+            reply.writeInt(enabled ? 1 : 0);
+            return true;
+        }
+
+        case MEDIA_RESOURCES_RELEASED: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            mediaResourcesReleased(token);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -5007,5 +5034,46 @@
         reply.recycle();
     }
 
+    @Override
+    public boolean setMediaPlaying(IBinder token, boolean playing) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        data.writeInt(playing ? 1 : 0);
+        mRemote.transact(SET_MEDIA_PLAYING_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean success = reply.readInt() > 0;
+        data.recycle();
+        reply.recycle();
+        return success;
+    }
+
+    @Override
+    public boolean isBackgroundMediaPlaying(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(IS_BG_MEDIA_PLAYING_TRANSACTION, data, reply, 0);
+        reply.readException();
+        final boolean playing = reply.readInt() > 0;
+        data.recycle();
+        reply.recycle();
+        return playing;
+    }
+
+    @Override
+    public void mediaResourcesReleased(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(MEDIA_RESOURCES_RELEASED, data, reply, IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }