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

Commit 94465cae authored by Hai Zhang's avatar Hai Zhang Committed by Automerger Merge Worker
Browse files

Merge "Unify USE_FULL_SCREEN_INTENT permission check." into udc-dev am: cc96b1e8

parents 3b403f96 cc96b1e8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationHistory;
import android.app.NotificationManager;
import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
@@ -225,6 +226,7 @@ interface INotificationManager
    void setNotificationDelegate(String callingPkg, String delegate);
    String getNotificationDelegate(String callingPkg);
    boolean canNotifyAsPackage(String callingPkg, String targetPkg, int userId);
    boolean canUseFullScreenIntent(in AttributionSource attributionSource);

    void setPrivateNotificationsAllowed(boolean allow);
    boolean getPrivateNotificationsAllowed();
+5 −14
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Icon;
@@ -877,19 +876,11 @@ public class NotificationManager {
     * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}.
     */
    public boolean canUseFullScreenIntent() {
        final int result = PermissionChecker.checkPermissionForPreflight(mContext,
                android.Manifest.permission.USE_FULL_SCREEN_INTENT,
                mContext.getAttributionSource());

        switch (result) {
            case PermissionChecker.PERMISSION_GRANTED:
                return true;
            case PermissionChecker.PERMISSION_SOFT_DENIED:
            case PermissionChecker.PERMISSION_HARD_DENIED:
                return false;
            default:
                if (localLOGV) Log.v(TAG, "Unknown PermissionChecker result: " + result);
                return false;
        INotificationManager service = getService();
        try {
            return service.canUseFullScreenIntent(mContext.getAttributionSource());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

+63 −25
Original line number Diff line number Diff line
@@ -3814,6 +3814,28 @@ public class NotificationManagerService extends SystemService {
            return false;
        }
        @Override
        public boolean canUseFullScreenIntent(@NonNull AttributionSource attributionSource) {
            final String packageName = attributionSource.getPackageName();
            final int uid = attributionSource.getUid();
            final int userId = UserHandle.getUserId(uid);
            checkCallerIsSameApp(packageName, uid, userId);
            final ApplicationInfo applicationInfo;
            try {
                applicationInfo = mPackageManagerClient.getApplicationInfoAsUser(
                        packageName, PackageManager.MATCH_DIRECT_BOOT_AUTO, userId);
            } catch (NameNotFoundException e) {
                Slog.e(TAG, "Failed to getApplicationInfo() in canUseFullScreenIntent()", e);
                return false;
            }
            final boolean showStickyHunIfDenied = mFlagResolver.isEnabled(
                    SystemUiSystemPropertiesFlags.NotificationFlags
                            .SHOW_STICKY_HUN_FOR_DENIED_FSI);
            return checkUseFullScreenIntentPermission(attributionSource, applicationInfo,
                    showStickyHunIfDenied /* isAppOpPermission */, false /* forDataDelivery */);
        }
        @Override
        public void updateNotificationChannelGroupForPackage(String pkg, int uid,
                NotificationChannelGroup group) throws RemoteException {
@@ -6826,39 +6848,31 @@ public class NotificationManagerService extends SystemService {
        notification.flags &= ~FLAG_FSI_REQUESTED_BUT_DENIED;
        if (notification.fullScreenIntent != null && ai.targetSdkVersion >= Build.VERSION_CODES.Q) {
        if (notification.fullScreenIntent != null) {
            final boolean forceDemoteFsiToStickyHun = mFlagResolver.isEnabled(
                    SystemUiSystemPropertiesFlags.NotificationFlags.FSI_FORCE_DEMOTE);
            final boolean showStickyHunIfDenied = mFlagResolver.isEnabled(
                    SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI);
            if (forceDemoteFsiToStickyHun) {
                makeStickyHun(notification, pkg, userId);
            } else if (showStickyHunIfDenied) {
                final AttributionSource source = new AttributionSource.Builder(notificationUid)
                        .setPackageName(pkg)
                        .build();
                final int permissionResult = mPermissionManager.checkPermissionForDataDelivery(
                        Manifest.permission.USE_FULL_SCREEN_INTENT, source, /* message= */ null);
                if (permissionResult != PermissionManager.PERMISSION_GRANTED) {
            } else {
                final AttributionSource attributionSource =
                        new AttributionSource.Builder(notificationUid).setPackageName(pkg).build();
                final boolean showStickyHunIfDenied = mFlagResolver.isEnabled(
                        SystemUiSystemPropertiesFlags.NotificationFlags
                                .SHOW_STICKY_HUN_FOR_DENIED_FSI);
                final boolean canUseFullScreenIntent = checkUseFullScreenIntentPermission(
                        attributionSource, ai, showStickyHunIfDenied /* isAppOpPermission */,
                        true /* forDataDelivery */);
                if (!canUseFullScreenIntent) {
                    if (showStickyHunIfDenied) {
                        makeStickyHun(notification, pkg, userId);
                }
                    } else {
                int fullscreenIntentPermission = getContext().checkPermission(
                        android.Manifest.permission.USE_FULL_SCREEN_INTENT, -1, notificationUid);
                if (fullscreenIntentPermission != PERMISSION_GRANTED) {
                        notification.fullScreenIntent = null;
                        Slog.w(TAG, "Package " + pkg + ": Use of fullScreenIntent requires the"
                                + "USE_FULL_SCREEN_INTENT permission");
                    }
                }
            }
        }
        // Ensure all actions are present
        if (notification.actions != null) {
@@ -6951,6 +6965,30 @@ public class NotificationManagerService extends SystemService {
                ai.packageName) == AppOpsManager.MODE_ALLOWED;
    }
    private boolean checkUseFullScreenIntentPermission(@NonNull AttributionSource attributionSource,
            @NonNull ApplicationInfo applicationInfo, boolean isAppOpPermission,
            boolean forDataDelivery) {
        if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) {
            return true;
        }
        if (isAppOpPermission) {
            final int permissionResult;
            if (forDataDelivery) {
                permissionResult = mPermissionManager.checkPermissionForDataDelivery(
                        permission.USE_FULL_SCREEN_INTENT, attributionSource, /* message= */ null);
            } else {
                permissionResult = mPermissionManager.checkPermissionForPreflight(
                        permission.USE_FULL_SCREEN_INTENT, attributionSource);
            }
            return permissionResult == PermissionManager.PERMISSION_GRANTED;
        } else {
            final int permissionResult = getContext().checkPermission(
                    permission.USE_FULL_SCREEN_INTENT, attributionSource.getPid(),
                    attributionSource.getUid());
            return permissionResult == PERMISSION_GRANTED;
        }
    }
    private void checkRemoteViews(String pkg, String tag, int id, Notification notification) {
        if (removeRemoteView(pkg, tag, id, notification.contentView)) {
            notification.contentView = null;