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

Commit d08c338d authored by Jin Seok Park's avatar Jin Seok Park Committed by Android (Google) Code Review
Browse files

Merge "Add hasEnabledNotificationListener API"

parents d1618468 e1f4d51d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@ package android.app {
    field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
  }

  public class NotificationManager {
    method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
  }

}

package android.content.rollback {
+1 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ interface INotificationManager
    List<ComponentName> getEnabledNotificationListeners(int userId);
    ComponentName getAllowedNotificationAssistantForUser(int userId);
    ComponentName getAllowedNotificationAssistant();
    boolean hasEnabledNotificationListener(String packageName, int userId);

    @UnsupportedAppUsage
    int getZenMode();
+20 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -1539,6 +1540,25 @@ public class NotificationManager {
        }
    }

    /**
     * Whether the given user has an enabled
     * {@link android.service.notification.NotificationListenerService} with the given package name.
     *
     * @param packageName the package name of the NotificationListenerService class
     * @param userHandle the handle of the user that set the listener
     * @hide
     */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @SuppressLint("UserHandle")
    public boolean hasEnabledNotificationListener(@NonNull String packageName,
            @NonNull UserHandle userHandle) {
        INotificationManager service = getService();
        try {
            return service.hasEnabledNotificationListener(packageName, userHandle.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private Context mContext;

+4 −0
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@ package android.app {
    field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
  }

  public class NotificationManager {
    method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
  }

}

package android.content.rollback {
+21 −34
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@ import static com.android.server.media.MediaKeyDispatcher.isSingleTapOverridden;
import static com.android.server.media.MediaKeyDispatcher.isTripleTapOverridden;

import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
@@ -68,7 +68,6 @@ import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManager;
@@ -118,7 +117,7 @@ public class MediaSessionService extends SystemService implements Monitor {
    private final SessionManagerImpl mSessionManagerImpl;
    private final MessageHandler mHandler = new MessageHandler();
    private final PowerManager.WakeLock mMediaEventWakeLock;
    private final INotificationManager mNotificationManager;
    private final NotificationManager mNotificationManager;
    private final Object mLock = new Object();
    private final HandlerThread mRecordThread = new HandlerThread("SessionRecordThread");
    // Keeps the full user id for each user.
@@ -158,10 +157,9 @@ public class MediaSessionService extends SystemService implements Monitor {
        super(context);
        mContext = context;
        mSessionManagerImpl = new SessionManagerImpl();
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager pm = mContext.getSystemService(PowerManager.class);
        mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
        mNotificationManager = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        mNotificationManager = mContext.getSystemService(NotificationManager.class);
    }

    @Override
@@ -507,11 +505,12 @@ public class MediaSessionService extends SystemService implements Monitor {
    private void enforceMediaPermissions(ComponentName compName, int pid, int uid,
            int resolvedUserId) {
        if (hasStatusBarServicePermission(pid, uid)) return;
        // TODO: Refactor to use hasMediaControlPermission and hasEnabledNotificationListener
        if (mContext
                .checkPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid)
                != PackageManager.PERMISSION_GRANTED
                && !isEnabledNotificationListener(compName,
                UserHandle.getUserHandleForUid(uid).getIdentifier(), resolvedUserId)) {
                UserHandle.getUserHandleForUid(uid), resolvedUserId)) {
            throw new SecurityException("Missing permission to control media.");
        }
    }
@@ -547,13 +546,13 @@ public class MediaSessionService extends SystemService implements Monitor {
     * they're running as.
     *
     * @param compName The component that is enabled.
     * @param userId The user id of the caller.
     * @param userHandle The user handle of the caller.
     * @param forUserId The user id they're making the request on behalf of.
     * @return True if the component is enabled, false otherwise
     */
    private boolean isEnabledNotificationListener(ComponentName compName, int userId,
    private boolean isEnabledNotificationListener(ComponentName compName, UserHandle userHandle,
            int forUserId) {
        if (userId != forUserId) {
        if (userHandle.getIdentifier() != forUserId) {
            // You may not access another user's content as an enabled listener.
            return false;
        }
@@ -561,12 +560,8 @@ public class MediaSessionService extends SystemService implements Monitor {
            Log.d(TAG, "Checking if enabled notification listener " + compName);
        }
        if (compName != null) {
            try {
                return mNotificationManager.isNotificationListenerAccessGrantedForUser(
                        compName, userId);
            } catch (RemoteException e) {
                Log.w(TAG, "Dead NotificationManager in isEnabledNotificationListener", e);
            }
            return mNotificationManager.hasEnabledNotificationListener(compName.getPackageName(),
                    userHandle);
        }
        return false;
    }
@@ -1922,8 +1917,8 @@ public class MediaSessionService extends SystemService implements Monitor {
         * @param controllerUid uid of the controller app
         */
        @Override
        public boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid)
                throws RemoteException {
        public boolean isTrusted(String controllerPackageName, int controllerPid,
                int controllerUid) {
            final int uid = Binder.getCallingUid();
            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
            final long token = Binder.clearCallingIdentity();
@@ -1937,7 +1932,7 @@ public class MediaSessionService extends SystemService implements Monitor {
                // Context#getPackageName() for getting package name that matches with the PID/UID,
                // but it doesn't tell which package has created the MediaController, so useless.
                return hasMediaControlPermission(controllerPid, controllerUid)
                        || hasEnabledNotificationListener(userId, controllerPackageName);
                        || hasEnabledNotificationListener(userId, controllerPackageName, uid);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
@@ -2001,28 +1996,20 @@ public class MediaSessionService extends SystemService implements Monitor {
            return resolvedUserId;
        }

        private boolean hasEnabledNotificationListener(int resolvedUserId, String packageName)
                throws RemoteException {
        private boolean hasEnabledNotificationListener(int resolvedUserId, String packageName,
                int uid) {
            // TODO: revisit this checking code
            // You may not access another user's content as an enabled listener.
            final int userId = UserHandle.getUserHandleForUid(resolvedUserId).getIdentifier();
            if (resolvedUserId != userId) {
                return false;
            }

            // TODO(jaewan): (Post-P) Propose NotificationManager#hasEnabledNotificationListener(
            //               String pkgName) to notification team for optimization
            final List<ComponentName> enabledNotificationListeners =
                    mNotificationManager.getEnabledNotificationListeners(userId);
            if (enabledNotificationListeners != null) {
                for (int i = 0; i < enabledNotificationListeners.size(); i++) {
                    if (TextUtils.equals(packageName,
                            enabledNotificationListeners.get(i).getPackageName())) {
            if (mNotificationManager.hasEnabledNotificationListener(packageName,
                    UserHandle.getUserHandleForUid(uid))) {
                return true;
            }
                }
            }
            if (DEBUG) {
                Log.d(TAG, packageName + " (uid=" + resolvedUserId + ") doesn't have an enabled "
                Log.d(TAG, packageName + " (uid=" + uid + ") doesn't have an enabled "
                        + "notification listener");
            }
            return false;
Loading