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

Commit 30cb5c3f authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 2ea480ca: am 5d0b18cd: am 3de885be: Merge "Disallow applications from...

am 2ea480ca: am 5d0b18cd: am 3de885be: Merge "Disallow applications from initiating cast screen." into klp-dev

* commit '2ea480ca':
  Disallow applications from initiating cast screen.
parents 0b342cf8 2ea480ca
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -299,6 +299,10 @@ public final class DisplayManager {
    /**
     * Initiates a fresh scan of availble Wifi displays.
     * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
     * <p>
     * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
     * </p>
     *
     * @hide
     */
    public void scanWifiDisplays() {
@@ -312,8 +316,7 @@ public final class DisplayManager {
     * Automatically remembers the display after a successful connection, if not
     * already remembered.
     * </p><p>
     * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY} to connect
     * to unknown displays.  No permissions are required to connect to already known displays.
     * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
     * </p>
     *
     * @param deviceAddress The MAC address of the device to which we should connect.
+65 −8
Original line number Diff line number Diff line
@@ -18,11 +18,13 @@ package android.media;

import com.android.internal.util.Objects;

import android.Manifest;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
@@ -30,6 +32,7 @@ import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -82,6 +85,7 @@ public class MediaRouter {

        RouteInfo mSelectedRoute;

        final boolean mCanConfigureWifiDisplays;
        boolean mActivelyScanningWifiDisplays;

        int mDiscoveryRequestRouteTypes;
@@ -129,6 +133,13 @@ public class MediaRouter {
                    com.android.internal.R.string.default_audio_route_category_name,
                    ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO, false);
            mSystemCategory.mIsSystem = true;

            // Only the system can configure wifi displays.  The display manager
            // enforces this with a permission check.  Set a flag here so that we
            // know whether this process is actually allowed to scan and connect.
            mCanConfigureWifiDisplays = appContext.checkPermission(
                    Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                    Process.myPid(), Process.myUid()) == PackageManager.PERMISSION_GRANTED;
        }

        // Called after sStatic is initialized
@@ -255,7 +266,7 @@ public class MediaRouter {
                }
                if ((cbi.flags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0) {
                    activeScan = true;
                    if ((cbi.type & (ROUTE_TYPE_LIVE_VIDEO | ROUTE_TYPE_REMOTE_DISPLAY)) != 0) {
                    if ((cbi.type & ROUTE_TYPE_REMOTE_DISPLAY) != 0) {
                        activeScanWifiDisplay = true;
                    }
                }
@@ -268,7 +279,7 @@ public class MediaRouter {
            }

            // Update wifi display scanning.
            if (activeScanWifiDisplay) {
            if (activeScanWifiDisplay && mCanConfigureWifiDisplays) {
                if (!mActivelyScanningWifiDisplays) {
                    mActivelyScanningWifiDisplays = true;
                    mHandler.post(mScanWifiDisplays);
@@ -493,7 +504,8 @@ public class MediaRouter {
                route.mDescription = globalRoute.description;
                changed = true;
            }
            if (route.mSupportedTypes != globalRoute.supportedTypes) {
            final int oldSupportedTypes = route.mSupportedTypes;
            if (oldSupportedTypes != globalRoute.supportedTypes) {
                route.mSupportedTypes = globalRoute.supportedTypes;
                changed = true;
            }
@@ -536,7 +548,7 @@ public class MediaRouter {
            }

            if (changed) {
                dispatchRouteChanged(route);
                dispatchRouteChanged(route, oldSupportedTypes);
            }
            if (volumeChanged) {
                dispatchRouteVolumeChanged(route);
@@ -908,7 +920,12 @@ public class MediaRouter {
        final boolean newRouteHasAddress = route != null && route.mDeviceAddress != null;
        if (activeDisplay != null || oldRouteHasAddress || newRouteHasAddress) {
            if (newRouteHasAddress && !matchesDeviceAddress(activeDisplay, route)) {
                if (sStatic.mCanConfigureWifiDisplays) {
                    sStatic.mDisplayService.connectWifiDisplay(route.mDeviceAddress);
                } else {
                    Log.e(TAG, "Cannot connect to wifi displays because this process "
                            + "is not allowed to do so.");
                }
            } else if (activeDisplay != null && !newRouteHasAddress) {
                sStatic.mDisplayService.disconnectWifiDisplay();
            }
@@ -1175,10 +1192,34 @@ public class MediaRouter {
    }

    static void dispatchRouteChanged(RouteInfo info) {
        dispatchRouteChanged(info, info.mSupportedTypes);
    }

    static void dispatchRouteChanged(RouteInfo info, int oldSupportedTypes) {
        final int newSupportedTypes = info.mSupportedTypes;
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
            // Reconstruct some of the history for callbacks that may not have observed
            // all of the events needed to correctly interpret the current state.
            // FIXME: This is a strong signal that we should deprecate route type filtering
            // completely in the future because it can lead to inconsistencies in
            // applications.
            final boolean oldVisibility = cbi.filterRouteEvent(oldSupportedTypes);
            final boolean newVisibility = cbi.filterRouteEvent(newSupportedTypes);
            if (!oldVisibility && newVisibility) {
                cbi.cb.onRouteAdded(cbi.router, info);
                if (info.isSelected()) {
                    cbi.cb.onRouteSelected(cbi.router, newSupportedTypes, info);
                }
            }
            if (oldVisibility || newVisibility) {
                cbi.cb.onRouteChanged(cbi.router, info);
            }
            if (oldVisibility && !newVisibility) {
                if (info.isSelected()) {
                    cbi.cb.onRouteUnselected(cbi.router, oldSupportedTypes, info);
                }
                cbi.cb.onRouteRemoved(cbi.router, info);
            }
        }
    }

@@ -1257,6 +1298,18 @@ public class MediaRouter {
        if (status.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) {
            displays = status.getDisplays();
            activeDisplay = status.getActiveDisplay();

            // Only the system is able to connect to wifi display routes.
            // The display manager will enforce this with a permission check but it
            // still publishes information about all available displays.
            // Filter the list down to just the active display.
            if (!sStatic.mCanConfigureWifiDisplays) {
                if (activeDisplay != null) {
                    displays = new WifiDisplay[] { activeDisplay };
                } else {
                    displays = WifiDisplay.EMPTY_ARRAY;
                }
            }
        } else {
            displays = WifiDisplay.EMPTY_ARRAY;
            activeDisplay = null;
@@ -1293,7 +1346,7 @@ public class MediaRouter {

        // Don't scan if we're already connected to a wifi display,
        // the scanning process can cause a hiccup with some configurations.
        if (wantScan && activeDisplay != null) {
        if (wantScan && activeDisplay != null && sStatic.mCanConfigureWifiDisplays) {
            sStatic.mDisplayService.scanWifiDisplays();
        }
    }
@@ -2547,8 +2600,12 @@ public class MediaRouter {
        }

        public boolean filterRouteEvent(RouteInfo route) {
            return filterRouteEvent(route.mSupportedTypes);
        }

        public boolean filterRouteEvent(int supportedTypes) {
            return (flags & CALLBACK_FLAG_UNFILTERED_EVENTS) != 0
                    || (type & route.mSupportedTypes) != 0;
                    || (type & supportedTypes) != 0;
        }
    }

+17 −0
Original line number Diff line number Diff line
@@ -50,6 +50,17 @@ public final class MediaRouterClientState implements Parcelable {
        globallySelectedRouteId = src.readString();
    }

    public RouteInfo getRoute(String id) {
        final int count = routes.size();
        for (int i = 0; i < count; i++) {
            final RouteInfo route = routes.get(i);
            if (route.id.equals(id)) {
                return route;
            }
        }
        return null;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -61,6 +72,12 @@ public final class MediaRouterClientState implements Parcelable {
        dest.writeString(globallySelectedRouteId);
    }

    @Override
    public String toString() {
        return "MediaRouterClientState{ globallySelectedRouteId="
                + globallySelectedRouteId + ", routes=" + routes.toString() + " }";
    }

    public static final Parcelable.Creator<MediaRouterClientState> CREATOR =
            new Parcelable.Creator<MediaRouterClientState>() {
        @Override
+3 −0
Original line number Diff line number Diff line
@@ -71,6 +71,9 @@
    <!-- Keyguard -->
    <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />

    <!-- Wifi Display -->
    <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />

    <application
        android:persistent="true"
        android:allowClearUserData="false"
+22 −27
Original line number Diff line number Diff line
@@ -466,6 +466,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub {

    @Override // Binder call
    public void scanWifiDisplays() {
        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                "Permission required to scan wifi displays");

        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mSyncRoot) {
@@ -483,13 +486,14 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
        if (address == null) {
            throw new IllegalArgumentException("address must not be null");
        }
        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                "Permission required to connect to a wifi display");

        final boolean trusted = canCallerConfigureWifiDisplay();
        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mSyncRoot) {
                if (mWifiDisplayAdapter != null) {
                    mWifiDisplayAdapter.requestConnectLocked(address, trusted);
                    mWifiDisplayAdapter.requestConnectLocked(address);
                }
            }
        } finally {
@@ -499,12 +503,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub {

    @Override
    public void pauseWifiDisplay() {
        if (mContext.checkCallingPermission(
                android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
                        != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY"
                    + "permission to pause a wifi display session.");
        }
        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                "Permission required to pause a wifi display session");

        final long token = Binder.clearCallingIdentity();
        try {
@@ -520,12 +520,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub {

    @Override
    public void resumeWifiDisplay() {
        if (mContext.checkCallingPermission(
                android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
                        != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY"
                    + "permission to resume a wifi display session.");
        }
        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                "Permission required to resume a wifi display session");

        final long token = Binder.clearCallingIdentity();
        try {
@@ -541,6 +537,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub {

    @Override // Binder call
    public void disconnectWifiDisplay() {
        // This request does not require special permissions.
        // Any app can request disconnection from the currently active wifi display.
        // This exception should no longer be needed once wifi display control moves
        // to the media router service.

        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mSyncRoot) {
@@ -558,10 +559,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
        if (address == null) {
            throw new IllegalArgumentException("address must not be null");
        }
        if (!canCallerConfigureWifiDisplay()) {
            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
                    + "rename a wifi display.");
        }
        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                "Permission required to rename to a wifi display");

        final long token = Binder.clearCallingIdentity();
        try {
@@ -580,10 +579,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
        if (address == null) {
            throw new IllegalArgumentException("address must not be null");
        }
        if (!canCallerConfigureWifiDisplay()) {
            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
                    + "forget a wifi display.");
        }
        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                "Permission required to forget to a wifi display");

        final long token = Binder.clearCallingIdentity();
        try {
@@ -599,6 +596,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub {

    @Override // Binder call
    public WifiDisplayStatus getWifiDisplayStatus() {
        // This request does not require special permissions.
        // Any app can get information about available wifi displays.

        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mSyncRoot) {
@@ -612,11 +612,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
        }
    }

    private boolean canCallerConfigureWifiDisplay() {
        return mContext.checkCallingPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
                == PackageManager.PERMISSION_GRANTED;
    }

    @Override // Binder call
    public int createVirtualDisplay(IBinder appToken, String packageName,
            String name, int width, int height, int densityDpi, Surface surface, int flags) {
Loading