summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2014-08-25 17:52:06 -0400
committerJohn Spurlock <jspurlock@google.com>2014-08-25 17:55:08 -0400
commit78b8c8fbde12b214314cc2ab2644350b5d5189a5 (patch)
tree0b232017fed212e835e2906dc32201e99cc8cdb2 /packages
parent6adf1588fd2bccb8cf95a9c3456230bba805fab9 (diff)
downloadframeworks_base-78b8c8fbde12b214314cc2ab2644350b5d5189a5.zip
frameworks_base-78b8c8fbde12b214314cc2ab2644350b5d5189a5.tar.gz
frameworks_base-78b8c8fbde12b214314cc2ab2644350b5d5189a5.tar.bz2
QS: Wire up screen casting to tile/panel.
Use MediaProjectionManager to determine whether or not screencasting is active, when it changes, and to stop casting. Also: - Implement hashCode/equals on MediaProjectionInfo - Fix unintentional recursion in the service. Bug:16488053 Change-Id: Icd1a88f23bbdf1d4c1915b30cb2508f8fe9d6d7e
Diffstat (limited to 'packages')
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java95
3 files changed, 95 insertions, 5 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 6cd0f39..f503657 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -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);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
index eb5804a..7713e57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
@@ -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();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 22179e0..eb0be05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -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;
@@ -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()");
}
@@ -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
@@ -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();
@@ -122,9 +152,55 @@ public class CastControllerImpl implements CastController {
}
@Override
- public void stopCasting() {
- if (DEBUG) Log.d(TAG, "stopCasting");
- mMediaRouter.getDefaultRoute().select();
+ 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() {
@@ -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);
+ }
+ };
}