Android AOSP定制禁用某些app的通知

Android AOSP定制禁用某些app的通知

前言:

​ 最近在做AOSP系统定制时发现gms定制好了后,Google应用商店用不了,提示此设备未获得Play保护机制认证,Google应用和服务无法在此设备上运行,查看官方文档和资料,说是由于Android设备id生成不对引起的,可以通过修改系统属性解决,需求简单描述还是如何默认关闭掉Google Play服务的通知,或者某个app的通知.

1.报错信息如下:

在这里插入图片描述

2.解决方法1:

  • 源码路径:/frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
  • 源码:
  • 通过包名判断过滤过需要关闭通知的应用

在这里插入图片描述

void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
    final int callingPid, final String tag, final int id, final Notification notification,
    int incomingUserId, boolean postSilently) {
    if (HwNotificationManagerService.disableNotification()) {
        return;
    }
    if (DBG) {
        Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                + " notification=" + notification);
    }
    if (pkg == null || notification == null) {
        throw new IllegalArgumentException("null not allowed: pkg=" + pkg
                + " id=" + id + " notification=" + notification);
    }

    final int userId = ActivityManager.handleIncomingUser(callingPid,
            callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
    final UserHandle user = UserHandle.of(userId);

    // Can throw a SecurityException if the calling uid doesn't have permission to post
    // as "pkg"
    final int notificationUid = resolveNotificationUid(opPkg, pkg, callingUid, userId);

    if (notificationUid == INVALID_UID) {
        throw new SecurityException("Caller " + opPkg + ":" + callingUid
                + " trying to post for invalid pkg " + pkg + " in user " + incomingUserId);
    }

    checkRestrictedCategories(pkg, notification);

    // Fix the notification as best we can.
    try {
        fixNotification(notification, pkg, tag, id, userId);

    } catch (Exception e) {
        Slog.e(TAG, "Cannot fix notification", e);
        return;
    }

    mUsageStats.registerEnqueuedByApp(pkg);

    final StatusBarNotification n = new StatusBarNotification(
            pkg, opPkg, id, tag, notificationUid, callingPid, notification,
            user, null, mSystemClock.currentTimeMillis());

    // setup local book-keeping
    String channelId = notification.getChannelId();
    if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
        channelId = (new Notification.TvExtender(notification)).getChannelId();
    }
    String shortcutId = n.getShortcutId();
    final NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel(
            pkg, notificationUid, channelId, shortcutId,
            true /* parent ok */, false /* includeDeleted */);
    if (channel == null) {
        final String noChannelStr = "No Channel found for "
                + "pkg=" + pkg
                + ", channelId=" + channelId
                + ", id=" + id
                + ", tag=" + tag
                + ", opPkg=" + opPkg
                + ", callingUid=" + callingUid
                + ", userId=" + userId
                + ", incomingUserId=" + incomingUserId
                + ", notificationUid=" + notificationUid
                + ", notification=" + notification;
        Slog.e(TAG, noChannelStr);
        boolean appNotificationsOff = mPreferencesHelper.getImportance(pkg, notificationUid)
                == NotificationManager.IMPORTANCE_NONE;

        if (!appNotificationsOff) {
            doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" +
                    "Failed to post notification on channel \"" + channelId + "\"\n" +
                    "See log for more details");
        }
        return;
    }

    final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
    r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
    r.setPostSilently(postSilently);
    r.setFlagBubbleRemoved(false);
    r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg));

    if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
        final boolean fgServiceShown = channel.isFgServiceShown();
        if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
                    || !fgServiceShown)
                && (r.getImportance() == IMPORTANCE_MIN
                        || r.getImportance() == IMPORTANCE_NONE)) {
            // Increase the importance of foreground service notifications unless the user had
            // an opinion otherwise (and the channel hasn't yet shown a fg service).
            if (TextUtils.isEmpty(channelId)
                    || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
                r.setSystemImportance(IMPORTANCE_LOW);
            } else {
                channel.setImportance(IMPORTANCE_LOW);
                r.setSystemImportance(IMPORTANCE_LOW);
                if (!fgServiceShown) {
                    channel.unlockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
                    channel.setFgServiceShown(true);
                }
                mPreferencesHelper.updateNotificationChannel(
                        pkg, notificationUid, channel, false);
                r.updateNotificationChannel(channel);
            }
        } else if (!fgServiceShown && !TextUtils.isEmpty(channelId)
                && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
            channel.setFgServiceShown(true);
            r.updateNotificationChannel(channel);
        }
    }

    ShortcutInfo info = mShortcutHelper != null
            ? mShortcutHelper.getValidShortcutInfo(notification.getShortcutId(), pkg, user)
            : null;
    if (notification.getShortcutId() != null && info == null) {
        Slog.w(TAG, "notification " + r.getKey() + " added an invalid shortcut");
    }
    r.setShortcutInfo(info);
    r.setHasSentValidMsg(mPreferencesHelper.hasSentValidMsg(pkg, notificationUid));
    r.userDemotedAppFromConvoSpace(
            mPreferencesHelper.hasUserDemotedInvalidMsgApp(pkg, notificationUid));

    if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
            r.getSbn().getOverrideGroupKey() != null)) {
        return;
    }

    if (info != null) {
        // Cache the shortcut synchronously after the associated notification is posted in case
        // the app unpublishes this shortcut immediately after posting the notification. If the
        // user does not modify the notification settings on this conversation, the shortcut
        // will be uncached by People Service when all the associated notifications are removed.
        mShortcutHelper.cacheShortcut(info, user);
    }

    // Whitelist pending intents.
    if (notification.allPendingIntents != null) {
        final int intentCount = notification.allPendingIntents.size();
        if (intentCount > 0) {
            final ActivityManagerInternal am = LocalServices
                    .getService(ActivityManagerInternal.class);
            final long duration = LocalServices.getService(
                    DeviceIdleInternal.class).getNotificationWhitelistDuration();
            for (int i = 0; i < intentCount; i++) {
                PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
                if (pendingIntent != null) {
                    am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
                            WHITELIST_TOKEN, duration);
                    am.setPendingIntentAllowBgActivityStarts(pendingIntent.getTarget(),
                            WHITELIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER
                                    | FLAG_SERVICE_SENDER));
                }
            }
        }
    }

    // Need escalated privileges to get package importance
    final long token = Binder.clearCallingIdentity();
    boolean isAppForeground;
    try {
        isAppForeground = mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
    } finally {
        Binder.restoreCallingIdentity(token);
    }
    mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground));
}

3.修改后的源码如下:

在这里插入图片描述

void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
    final int callingPid, final String tag, final int id, final Notification notification,
    int incomingUserId, boolean postSilently) {
    if (HwNotificationManagerService.disableNotification()) {
        return;
    }
    if (DBG) {
        Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                + " notification=" + notification);
    }
    if(pkg.equals("com.google.android.gms") || pkg.equals("com.android.vending")){
        return;
    }
    if (pkg == null || notification == null) {
        throw new IllegalArgumentException("null not allowed: pkg=" + pkg
                + " id=" + id + " notification=" + notification);
    }

    final int userId = ActivityManager.handleIncomingUser(callingPid,
            callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
    final UserHandle user = UserHandle.of(userId);

    // Can throw a SecurityException if the calling uid doesn't have permission to post
    // as "pkg"
    final int notificationUid = resolveNotificationUid(opPkg, pkg, callingUid, userId);

    if (notificationUid == INVALID_UID) {
        throw new SecurityException("Caller " + opPkg + ":" + callingUid
                + " trying to post for invalid pkg " + pkg + " in user " + incomingUserId);
    }

    checkRestrictedCategories(pkg, notification);

    // Fix the notification as best we can.
    try {
        fixNotification(notification, pkg, tag, id, userId);

    } catch (Exception e) {
        Slog.e(TAG, "Cannot fix notification", e);
        return;
    }

    mUsageStats.registerEnqueuedByApp(pkg);

    final StatusBarNotification n = new StatusBarNotification(
            pkg, opPkg, id, tag, notificationUid, callingPid, notification,
            user, null, mSystemClock.currentTimeMillis());

    // setup local book-keeping
    String channelId = notification.getChannelId();
    if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
        channelId = (new Notification.TvExtender(notification)).getChannelId();
    }
    String shortcutId = n.getShortcutId();
    final NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel(
            pkg, notificationUid, channelId, shortcutId,
            true /* parent ok */, false /* includeDeleted */);
    if (channel == null) {
        final String noChannelStr = "No Channel found for "
                + "pkg=" + pkg
                + ", channelId=" + channelId
                + ", id=" + id
                + ", tag=" + tag
                + ", opPkg=" + opPkg
                + ", callingUid=" + callingUid
                + ", userId=" + userId
                + ", incomingUserId=" + incomingUserId
                + ", notificationUid=" + notificationUid
                + ", notification=" + notification;
        Slog.e(TAG, noChannelStr);
        boolean appNotificationsOff = mPreferencesHelper.getImportance(pkg, notificationUid)
                == NotificationManager.IMPORTANCE_NONE;

        if (!appNotificationsOff) {
            doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" +
                    "Failed to post notification on channel \"" + channelId + "\"\n" +
                    "See log for more details");
        }
        return;
    }

    final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
    r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
    r.setPostSilently(postSilently);
    r.setFlagBubbleRemoved(false);
    r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg));

    if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
        final boolean fgServiceShown = channel.isFgServiceShown();
        if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
                    || !fgServiceShown)
                && (r.getImportance() == IMPORTANCE_MIN
                        || r.getImportance() == IMPORTANCE_NONE)) {
            // Increase the importance of foreground service notifications unless the user had
            // an opinion otherwise (and the channel hasn't yet shown a fg service).
            if (TextUtils.isEmpty(channelId)
                    || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
                r.setSystemImportance(IMPORTANCE_LOW);
            } else {
                channel.setImportance(IMPORTANCE_LOW);
                r.setSystemImportance(IMPORTANCE_LOW);
                if (!fgServiceShown) {
                    channel.unlockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
                    channel.setFgServiceShown(true);
                }
                mPreferencesHelper.updateNotificationChannel(
                        pkg, notificationUid, channel, false);
                r.updateNotificationChannel(channel);
            }
        } else if (!fgServiceShown && !TextUtils.isEmpty(channelId)
                && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
            channel.setFgServiceShown(true);
            r.updateNotificationChannel(channel);
        }
    }

    ShortcutInfo info = mShortcutHelper != null
            ? mShortcutHelper.getValidShortcutInfo(notification.getShortcutId(), pkg, user)
            : null;
    if (notification.getShortcutId() != null && info == null) {
        Slog.w(TAG, "notification " + r.getKey() + " added an invalid shortcut");
    }
    r.setShortcutInfo(info);
    r.setHasSentValidMsg(mPreferencesHelper.hasSentValidMsg(pkg, notificationUid));
    r.userDemotedAppFromConvoSpace(
            mPreferencesHelper.hasUserDemotedInvalidMsgApp(pkg, notificationUid));

    if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
            r.getSbn().getOverrideGroupKey() != null)) {
        return;
    }

    if (info != null) {
        // Cache the shortcut synchronously after the associated notification is posted in case
        // the app unpublishes this shortcut immediately after posting the notification. If the
        // user does not modify the notification settings on this conversation, the shortcut
        // will be uncached by People Service when all the associated notifications are removed.
        mShortcutHelper.cacheShortcut(info, user);
    }

    // Whitelist pending intents.
    if (notification.allPendingIntents != null) {
        final int intentCount = notification.allPendingIntents.size();
        if (intentCount > 0) {
            final ActivityManagerInternal am = LocalServices
                    .getService(ActivityManagerInternal.class);
            final long duration = LocalServices.getService(
                    DeviceIdleInternal.class).getNotificationWhitelistDuration();
            for (int i = 0; i < intentCount; i++) {
                PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
                if (pendingIntent != null) {
                    am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
                            WHITELIST_TOKEN, duration);
                    am.setPendingIntentAllowBgActivityStarts(pendingIntent.getTarget(),
                            WHITELIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER
                                    | FLAG_SERVICE_SENDER));
                }
            }
        }
    }

    // Need escalated privileges to get package importance
    final long token = Binder.clearCallingIdentity();
    boolean isAppForeground;
    try {
        isAppForeground = mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
    } finally {
        Binder.restoreCallingIdentity(token);
    }
    mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground));
}

4.解决方法2:

  • 源码路径:/frameworks/base/services/core/java/com/android/server/wm/AlertWindowNotification.java
  • 源码:
void post() {
    // We can't create/post the notification while the window manager lock is held since it will
    // end up calling into activity manager. So, we post a message to do it later.
    mService.mH.post(this::onPostNotification);
}

在这里插入图片描述

  • 修改后的源码:
void post() {
    // We can't create/post the notification while the window manager lock is held since it will
    // end up calling into activity manager. So, we post a message to do it later.
    if(mPackageName.contains("com.google.android.gms") || mPackageName.contains("com.android.vending")){
    }else {
        mService.mH.post(this::onPostNotification);
    }
}

在这里插入图片描述

5.实现的效果截图如下:

在这里插入图片描述

6.总结:

可以看到上面的截图已经去掉了Google商店和Google服务默认的安全提示的通知,基本上满足了需求,重启模拟器和手机,打开gms通知栏都没有提示了,这样优化了用户体验,不会让用户频繁开机或者多个手机一直都看到安全警告提示.

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值