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

Commit db80d1c1 authored by Sherry Huang's avatar Sherry Huang Committed by Android (Google) Code Review
Browse files

Merge "TIS: Singleton TIS for Broadcast Feature Support" into main

parents ccffd26d 8bf9dd63
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -592,6 +592,10 @@ applications that come with the platform
        <permission name="android.permission.INTERACT_ACROSS_USERS" />
    </privapp-permissions>

    <privapp-permissions package="com.android.providers.tv">
        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
    </privapp-permissions>

    <privapp-permissions package="com.android.tv">
        <permission name="android.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE"/>
        <permission name="android.permission.DVB_DEVICE"/>
+1 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ interface ITvInputManager {
    void releaseSession(in IBinder sessionToken, int userId);
    int getClientPid(in String sessionId);
    int getClientPriority(int useCase, in String sessionId);
    int getClientUserId(in String sessionId);

    void setMainSession(in IBinder sessionToken, int userId);
    void setSurface(in IBinder sessionToken, in Surface surface, int userId);
+35 −0
Original line number Diff line number Diff line
@@ -760,6 +760,14 @@ public final class TvInputManager {
     * @hide
     */
    public static final int UNKNOWN_CLIENT_PID = -1;
    /**
     * An unknown state of the client userId gets from the TvInputManager. Client gets this value
     * when query through {@link #getClientUserId(String sessionId)} fails.
     *
     * @hide
     */
    @FlaggedApi(Flags.FLAG_KIDS_MODE_TVDB_SHARING)
    public static final int UNKNOWN_CLIENT_USER_ID = -1;

    /**
     * Broadcast intent action when the user blocked content ratings change. For use with the
@@ -2509,6 +2517,21 @@ public final class TvInputManager {
        return getClientPidInternal(sessionId);
    };

    /**
     * Get a the client user id when creating the session with the session id provided.
     *
     * @param sessionId a String of session id that is used to query the client user id.
     * @return the client pid when created the session. Returns {@link #UNKNOWN_CLIENT_USER_ID}
     *         if the call fails.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.TUNER_RESOURCE_ACCESS)
    @FlaggedApi(Flags.FLAG_KIDS_MODE_TVDB_SHARING)
    public int getClientUserId(@NonNull String sessionId) {
        return getClientUserIdInternal(sessionId);
    }

    /**
     * Returns a priority for the given use case type and the client's foreground or background
     * status.
@@ -2599,6 +2622,18 @@ public final class TvInputManager {
        return clientPid;
    }

    @FlaggedApi(Flags.FLAG_KIDS_MODE_TVDB_SHARING)
    private int getClientUserIdInternal(String sessionId) {
        Preconditions.checkNotNull(sessionId);
        int clientUserId = UNKNOWN_CLIENT_USER_ID;
        try {
            clientUserId = mService.getClientUserId(sessionId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return clientUserId;
    }

    private int getClientPriorityInternal(int useCase, String sessionId) {
        try {
            return mService.getClientPriority(useCase, sessionId);
+8 −0
Original line number Diff line number Diff line
@@ -32,3 +32,11 @@ flag {
    description: "Introduce ALWAYS_BOUND_TV_INPUT for TIS."
    bug: "332201346"
}

flag {
    name: "kids_mode_tvdb_sharing"
    is_exported: true
    namespace: "media_tv"
    description: "Performance and Storage Optimization in Google TV Kids Mode."
    bug: "288383796"
}
 No newline at end of file
+55 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.tv;
import static android.media.AudioManager.DEVICE_NONE;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
import static android.media.tv.flags.Flags.kidsModeTvdbSharing;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -805,6 +806,19 @@ public final class TvInputManagerService extends SystemService {
        }
    }

    private boolean isServiceSingleUser(ComponentName component) {
        try {
            ServiceInfo serviceInfo = getContext().getPackageManager()
                    .getServiceInfo(component, 0);
            // Check if the single-user flag is present
            return (serviceInfo.flags & ServiceInfo.FLAG_SINGLE_USER) != 0;
        } catch (PackageManager.NameNotFoundException e) {
            // Handle the case where the service is not found
            Slog.e(TAG, "Service not found: " + component, e);
            return false;
        }
    }

    @GuardedBy("mLock")
    private void abortPendingCreateSessionRequestsLocked(ServiceState serviceState,
            String inputId, int userId) {
@@ -2839,6 +2853,26 @@ public final class TvInputManagerService extends SystemService {
            return clientPid;
        }

        @Override
        public int getClientUserId(String sessionId) {
            ensureTunerResourceAccessPermission();
            int clientUserId = TvInputManager.UNKNOWN_CLIENT_USER_ID;

            final long identity = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
                    try {
                        clientUserId = getClientUserIdLocked(sessionId);
                    } catch (ClientUserIdNotFoundException e) {
                        Slog.e(TAG, "error in getClientUserId", e);
                    }
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
            return clientUserId;
        }

        @Override
        public int getClientPriority(int useCase, String sessionId) {
            ensureTunerResourceAccessPermission();
@@ -2924,6 +2958,16 @@ public final class TvInputManagerService extends SystemService {
            return mSessionIdToSessionStateMap.get(sessionId).callingPid;
        }

        @GuardedBy("mLock")
        private int getClientUserIdLocked(String sessionId) throws ClientUserIdNotFoundException {
            SessionState sessionState = mSessionIdToSessionStateMap.get(sessionId);
            if (sessionState == null) {
                throw new ClientUserIdNotFoundException(
                        "Client UserId not found with sessionId " + sessionId);
            }
            return sessionState.userId;
        }

        private void ensureTunerResourceAccessPermission() {
            if (mContext.checkCallingPermission(
                    android.Manifest.permission.TUNER_RESOURCE_ACCESS)
@@ -3495,11 +3539,15 @@ public final class TvInputManagerService extends SystemService {
                    "bindServiceAsUser(service=" + serviceState.component + ", userId=" + userId
                            + ")");
        }
        int bindUserId = userId;
        if (kidsModeTvdbSharing() && isServiceSingleUser(serviceState.component)) {
            bindUserId = UserHandle.USER_SYSTEM;
        }
        Intent i =
                new Intent(TvInputService.SERVICE_INTERFACE).setComponent(serviceState.component);
        serviceState.bound = mContext.bindServiceAsUser(i, serviceState.connection,
                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
                new UserHandle(userId));
                new UserHandle(bindUserId));
        if (!serviceState.bound) {
            Slog.e(TAG, "failed to bind " + serviceState.component + " for userId " + userId);
            mContext.unbindService(serviceState.connection);
@@ -4700,4 +4748,10 @@ public final class TvInputManagerService extends SystemService {
            super(name);
        }
    }

    private static class ClientUserIdNotFoundException extends IllegalArgumentException {
        ClientUserIdNotFoundException(String name) {
            super(name);
        }
    }
}