Loading media/java/android/media/projection/MediaProjectionInfo.java +17 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; import java.util.Objects; /** @hide */ public final class MediaProjectionInfo implements Parcelable { private final String mPackageName; Loading @@ -43,6 +45,21 @@ public final class MediaProjectionInfo implements Parcelable { return mUserHandle; } @Override public boolean equals(Object o) { if (o instanceof MediaProjectionInfo) { final MediaProjectionInfo other = (MediaProjectionInfo) o; return Objects.equals(other.mPackageName, mPackageName) && Objects.equals(other.mUserHandle, mUserHandle); } return false; } @Override public int hashCode() { return Objects.hash(mPackageName, mUserHandle); } @Override public String toString() { return "MediaProjectionInfo{mPackageName=" Loading packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +2 −1 Original line number Diff line number Diff line Loading @@ -239,7 +239,8 @@ public class CastTile extends QSTile<QSTile.BooleanState> { @Override public void onDetailItemDisconnect(Item item) { if (item == null || item.tag == null) return; mController.stopCasting(); final CastDevice device = (CastDevice) item.tag; mController.stopCasting(device); } } } packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java +1 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public interface CastController { void setCurrentUserId(int currentUserId); Set<CastDevice> getCastDevices(); void startCasting(CastDevice device); void stopCasting(); void stopCasting(CastDevice device); public interface Callback { void onCastDevicesChanged(); Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java +92 −3 Original line number Diff line number Diff line Loading @@ -19,15 +19,25 @@ package com.android.systemui.statusbar.policy; import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.media.MediaRouter; import android.media.MediaRouter.RouteInfo; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; import android.os.Handler; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import com.android.systemui.R; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Objects; import java.util.Set; import java.util.UUID; Loading @@ -41,12 +51,19 @@ public class CastControllerImpl implements CastController { private final MediaRouter mMediaRouter; private final ArrayMap<String, RouteInfo> mRoutes = new ArrayMap<>(); private final Object mDiscoveringLock = new Object(); private final MediaProjectionManager mProjectionManager; private final Object mProjectionLock = new Object(); private boolean mDiscovering; private MediaProjectionInfo mProjection; public CastControllerImpl(Context context) { mContext = context; mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); mProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); mProjection = mProjectionManager.getActiveProjectionInfo(); mProjectionManager.addCallback(mProjectionCallback, new Handler()); if (DEBUG) Log.d(TAG, "new CastController()"); } Loading @@ -59,6 +76,7 @@ public class CastControllerImpl implements CastController { final RouteInfo route = mRoutes.valueAt(i); pw.print(" "); pw.println(routeToString(route)); } pw.print(" mProjection="); pw.println(mProjection); } @Override Loading Loading @@ -95,6 +113,18 @@ public class CastControllerImpl implements CastController { @Override public Set<CastDevice> getCastDevices() { final ArraySet<CastDevice> devices = new ArraySet<CastDevice>(); synchronized (mProjectionLock) { if (mProjection != null) { final CastDevice device = new CastDevice(); device.id = mProjection.getPackageName(); device.name = getAppName(mProjection.getPackageName()); device.description = mContext.getString(R.string.quick_settings_casting); device.state = CastDevice.STATE_CONNECTED; device.tag = mProjection; devices.add(device); return devices; } } synchronized(mRoutes) { for (RouteInfo route : mRoutes.values()) { final CastDevice device = new CastDevice(); Loading Loading @@ -122,10 +152,56 @@ public class CastControllerImpl implements CastController { } @Override public void stopCasting() { if (DEBUG) Log.d(TAG, "stopCasting"); public void stopCasting(CastDevice device) { final boolean isProjection = device.tag instanceof MediaProjectionInfo; if (DEBUG) Log.d(TAG, "stopCasting isProjection=" + isProjection); if (isProjection) { final MediaProjectionInfo projection = (MediaProjectionInfo) device.tag; if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) { mProjectionManager.stopActiveProjection(); } else { Log.w(TAG, "Projection is no longer active: " + projection); } } else { mMediaRouter.getDefaultRoute().select(); } } private void setProjection(MediaProjectionInfo projection, boolean started) { boolean changed = false; final MediaProjectionInfo oldProjection = mProjection; synchronized (mProjectionLock) { final boolean isCurrent = Objects.equals(projection, mProjection); if (started && !isCurrent) { mProjection = projection; changed = true; } else if (!started && isCurrent) { mProjection = null; changed = true; } } if (changed) { if (DEBUG) Log.d(TAG, "setProjection: " + oldProjection + " -> " + mProjection); fireOnCastDevicesChanged(); } } private String getAppName(String packageName) { final PackageManager pm = mContext.getPackageManager(); try { final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); if (appInfo != null) { final CharSequence label = appInfo.loadLabel(pm); if (!TextUtils.isEmpty(label)) { return label.toString(); } } Log.w(TAG, "No label found for package: " + packageName); } catch (NameNotFoundException e) { Log.w(TAG, "Error getting appName for package: " + packageName, e); } return packageName; } private void updateRemoteDisplays() { synchronized(mRoutes) { Loading Loading @@ -202,4 +278,17 @@ public class CastControllerImpl implements CastController { updateRemoteDisplays(); } }; private final MediaProjectionManager.Callback mProjectionCallback = new MediaProjectionManager.Callback() { @Override public void onStart(MediaProjectionInfo info) { setProjection(info, true); } @Override public void onStop(MediaProjectionInfo info) { setProjection(info, false); } }; } services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -111,7 +111,6 @@ public final class MediaProjectionManagerService extends SystemService @Override public void binderDied() { synchronized (mLock) { unlinkDeathRecipientLocked(callback); removeCallback(callback); } } Loading @@ -125,7 +124,7 @@ public final class MediaProjectionManagerService extends SystemService private void removeCallback(IMediaProjectionWatcherCallback callback) { synchronized (mLock) { unlinkDeathRecipientLocked(callback); removeCallback(callback); mCallbackDelegate.remove(callback); } } Loading Loading
media/java/android/media/projection/MediaProjectionInfo.java +17 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; import java.util.Objects; /** @hide */ public final class MediaProjectionInfo implements Parcelable { private final String mPackageName; Loading @@ -43,6 +45,21 @@ public final class MediaProjectionInfo implements Parcelable { return mUserHandle; } @Override public boolean equals(Object o) { if (o instanceof MediaProjectionInfo) { final MediaProjectionInfo other = (MediaProjectionInfo) o; return Objects.equals(other.mPackageName, mPackageName) && Objects.equals(other.mUserHandle, mUserHandle); } return false; } @Override public int hashCode() { return Objects.hash(mPackageName, mUserHandle); } @Override public String toString() { return "MediaProjectionInfo{mPackageName=" Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +2 −1 Original line number Diff line number Diff line Loading @@ -239,7 +239,8 @@ public class CastTile extends QSTile<QSTile.BooleanState> { @Override public void onDetailItemDisconnect(Item item) { if (item == null || item.tag == null) return; mController.stopCasting(); final CastDevice device = (CastDevice) item.tag; mController.stopCasting(device); } } }
packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java +1 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public interface CastController { void setCurrentUserId(int currentUserId); Set<CastDevice> getCastDevices(); void startCasting(CastDevice device); void stopCasting(); void stopCasting(CastDevice device); public interface Callback { void onCastDevicesChanged(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java +92 −3 Original line number Diff line number Diff line Loading @@ -19,15 +19,25 @@ package com.android.systemui.statusbar.policy; import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.media.MediaRouter; import android.media.MediaRouter.RouteInfo; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; import android.os.Handler; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import com.android.systemui.R; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Objects; import java.util.Set; import java.util.UUID; Loading @@ -41,12 +51,19 @@ public class CastControllerImpl implements CastController { private final MediaRouter mMediaRouter; private final ArrayMap<String, RouteInfo> mRoutes = new ArrayMap<>(); private final Object mDiscoveringLock = new Object(); private final MediaProjectionManager mProjectionManager; private final Object mProjectionLock = new Object(); private boolean mDiscovering; private MediaProjectionInfo mProjection; public CastControllerImpl(Context context) { mContext = context; mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); mProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); mProjection = mProjectionManager.getActiveProjectionInfo(); mProjectionManager.addCallback(mProjectionCallback, new Handler()); if (DEBUG) Log.d(TAG, "new CastController()"); } Loading @@ -59,6 +76,7 @@ public class CastControllerImpl implements CastController { final RouteInfo route = mRoutes.valueAt(i); pw.print(" "); pw.println(routeToString(route)); } pw.print(" mProjection="); pw.println(mProjection); } @Override Loading Loading @@ -95,6 +113,18 @@ public class CastControllerImpl implements CastController { @Override public Set<CastDevice> getCastDevices() { final ArraySet<CastDevice> devices = new ArraySet<CastDevice>(); synchronized (mProjectionLock) { if (mProjection != null) { final CastDevice device = new CastDevice(); device.id = mProjection.getPackageName(); device.name = getAppName(mProjection.getPackageName()); device.description = mContext.getString(R.string.quick_settings_casting); device.state = CastDevice.STATE_CONNECTED; device.tag = mProjection; devices.add(device); return devices; } } synchronized(mRoutes) { for (RouteInfo route : mRoutes.values()) { final CastDevice device = new CastDevice(); Loading Loading @@ -122,10 +152,56 @@ public class CastControllerImpl implements CastController { } @Override public void stopCasting() { if (DEBUG) Log.d(TAG, "stopCasting"); public void stopCasting(CastDevice device) { final boolean isProjection = device.tag instanceof MediaProjectionInfo; if (DEBUG) Log.d(TAG, "stopCasting isProjection=" + isProjection); if (isProjection) { final MediaProjectionInfo projection = (MediaProjectionInfo) device.tag; if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) { mProjectionManager.stopActiveProjection(); } else { Log.w(TAG, "Projection is no longer active: " + projection); } } else { mMediaRouter.getDefaultRoute().select(); } } private void setProjection(MediaProjectionInfo projection, boolean started) { boolean changed = false; final MediaProjectionInfo oldProjection = mProjection; synchronized (mProjectionLock) { final boolean isCurrent = Objects.equals(projection, mProjection); if (started && !isCurrent) { mProjection = projection; changed = true; } else if (!started && isCurrent) { mProjection = null; changed = true; } } if (changed) { if (DEBUG) Log.d(TAG, "setProjection: " + oldProjection + " -> " + mProjection); fireOnCastDevicesChanged(); } } private String getAppName(String packageName) { final PackageManager pm = mContext.getPackageManager(); try { final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); if (appInfo != null) { final CharSequence label = appInfo.loadLabel(pm); if (!TextUtils.isEmpty(label)) { return label.toString(); } } Log.w(TAG, "No label found for package: " + packageName); } catch (NameNotFoundException e) { Log.w(TAG, "Error getting appName for package: " + packageName, e); } return packageName; } private void updateRemoteDisplays() { synchronized(mRoutes) { Loading Loading @@ -202,4 +278,17 @@ public class CastControllerImpl implements CastController { updateRemoteDisplays(); } }; private final MediaProjectionManager.Callback mProjectionCallback = new MediaProjectionManager.Callback() { @Override public void onStart(MediaProjectionInfo info) { setProjection(info, true); } @Override public void onStop(MediaProjectionInfo info) { setProjection(info, false); } }; }
services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -111,7 +111,6 @@ public final class MediaProjectionManagerService extends SystemService @Override public void binderDied() { synchronized (mLock) { unlinkDeathRecipientLocked(callback); removeCallback(callback); } } Loading @@ -125,7 +124,7 @@ public final class MediaProjectionManagerService extends SystemService private void removeCallback(IMediaProjectionWatcherCallback callback) { synchronized (mLock) { unlinkDeathRecipientLocked(callback); removeCallback(callback); mCallbackDelegate.remove(callback); } } Loading