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

Commit 759eb8a7 authored by Iavor-Valentin Iftime's avatar Iavor-Valentin Iftime Committed by Android (Google) Code Review
Browse files

Merge "Allow NotificationListenerService to be unbound by default"

parents 58cc973f cbf5855c
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -40779,6 +40779,7 @@ package android.service.notification {
    method public final void requestInterruptionFilter(int);
    method public final void requestInterruptionFilter(int);
    method public final void requestListenerHints(int);
    method public final void requestListenerHints(int);
    method public static void requestRebind(android.content.ComponentName);
    method public static void requestRebind(android.content.ComponentName);
    method public static void requestUnbind(@NonNull android.content.ComponentName);
    method public final void requestUnbind();
    method public final void requestUnbind();
    method public final void setNotificationsShown(String[]);
    method public final void setNotificationsShown(String[]);
    method public final void snoozeNotification(String, long);
    method public final void snoozeNotification(String, long);
@@ -40796,6 +40797,7 @@ package android.service.notification {
    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
    field public static final String META_DATA_DEFAULT_AUTOBIND = "android.service.notification.default_autobind_listenerservice";
    field public static final String META_DATA_DEFAULT_FILTER_TYPES = "android.service.notification.default_filter_types";
    field public static final String META_DATA_DEFAULT_FILTER_TYPES = "android.service.notification.default_filter_types";
    field public static final String META_DATA_DISABLED_FILTER_TYPES = "android.service.notification.disabled_filter_types";
    field public static final String META_DATA_DISABLED_FILTER_TYPES = "android.service.notification.disabled_filter_types";
    field public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1; // 0x1
    field public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1; // 0x1
+1 −0
Original line number Original line Diff line number Diff line
@@ -147,6 +147,7 @@ interface INotificationManager


    void requestBindListener(in ComponentName component);
    void requestBindListener(in ComponentName component);
    void requestUnbindListener(in INotificationListener token);
    void requestUnbindListener(in INotificationListener token);
    void requestUnbindListenerComponent(in ComponentName component);
    void requestBindProvider(in ComponentName component);
    void requestBindProvider(in ComponentName component);
    void requestUnbindProvider(in IConditionProvider token);
    void requestUnbindProvider(in IConditionProvider token);


+25 −0
Original line number Original line Diff line number Diff line
@@ -140,6 +140,16 @@ public abstract class NotificationListenerService extends Service {
    public static final String META_DATA_DISABLED_FILTER_TYPES
    public static final String META_DATA_DISABLED_FILTER_TYPES
            = "android.service.notification.disabled_filter_types";
            = "android.service.notification.disabled_filter_types";


    /**
     * The name of the {@code meta-data} tag containing a boolean value that is used to decide if
     * this listener should be automatically bound by default.
     * If the value is 'false', the listener can be bound on demand using {@link #requestRebind}
     * <p>An absent value means that the default is 'true'</p>
     *
     */
    public static final String META_DATA_DEFAULT_AUTOBIND
            = "android.service.notification.default_autobind_listenerservice";

    /**
    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Normal interruption filter.
     *     Normal interruption filter.
@@ -1323,6 +1333,21 @@ public abstract class NotificationListenerService extends Service {
        }
        }
    }
    }


    /**
     * Request that the service be unbound.
     *
     * <p>This method will fail for components that are not part of the calling app.
     */
    public static void requestUnbind(@NonNull ComponentName componentName) {
        INotificationManager noMan = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        try {
            noMan.requestUnbindListenerComponent(componentName);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
    /**
     * Request that the service be unbound.
     * Request that the service be unbound.
     *
     *
+62 −27
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.DEVICE_POLICY_SERVICE;
import static android.content.Context.DEVICE_POLICY_SERVICE;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_SYSTEM;
import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager;
@@ -60,6 +61,7 @@ import android.util.Log;
import android.util.Pair;
import android.util.Pair;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArray;
import android.util.SparseSetArray;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
@@ -390,14 +392,18 @@ abstract public class ManagedServices {
            }
            }
        }
        }


        final SparseSetArray<ComponentName> snoozingComponents;
        synchronized (mSnoozing) {
        synchronized (mSnoozing) {
            pw.println("    Snoozed " + getCaption() + "s ("
            snoozingComponents = new SparseSetArray<>(mSnoozing);
                    + mSnoozing.size() + "):");
            for (int i = 0; i < mSnoozing.size(); i++) {
                pw.println("      User: " + mSnoozing.keyAt(i));
                for (ComponentName name : mSnoozing.valuesAt(i)) {
                    pw.println("        " + name.flattenToShortString());
        }
        }
        pw.println("    Snoozed " + getCaption() + "s ("
                + snoozingComponents.size() + "):");
        for (int i = 0; i < snoozingComponents.size(); i++) {
            pw.println("      User: " + snoozingComponents.keyAt(i));
            for (ComponentName name : snoozingComponents.valuesAt(i)) {
                final ServiceInfo info = getServiceInfo(name, snoozingComponents.keyAt(i));
                pw.println("        " + name.flattenToShortString() + (isAutobindAllowed(info) ? ""
                        : " (META_DATA_DEFAULT_AUTOBIND=false)"));
            }
            }
        }
        }
    }
    }
@@ -1432,12 +1438,7 @@ abstract public class ManagedServices {
            final int userId = componentsToBind.keyAt(i);
            final int userId = componentsToBind.keyAt(i);
            final Set<ComponentName> add = componentsToBind.get(userId);
            final Set<ComponentName> add = componentsToBind.get(userId);
            for (ComponentName component : add) {
            for (ComponentName component : add) {
                try {
                ServiceInfo info = getServiceInfo(component, userId);
                    ServiceInfo info = mPm.getServiceInfo(component,
                            PackageManager.GET_META_DATA
                                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                            userId);
                if (info == null) {
                if (info == null) {
                    Slog.w(TAG, "Not binding " + getCaption() + " service " + component
                    Slog.w(TAG, "Not binding " + getCaption() + " service " + component
                            + ": service not found");
                            + ": service not found");
@@ -1448,12 +1449,19 @@ abstract public class ManagedServices {
                            + ": it does not require the permission " + mConfig.bindPermission);
                            + ": it does not require the permission " + mConfig.bindPermission);
                    continue;
                    continue;
                }
                }
                // Do not (auto)bind if service has meta-data to explicitly disallow it
                if (!isAutobindAllowed(info) && !isBoundOrRebinding(component, userId)) {
                    synchronized (mSnoozing) {
                        Slog.d(TAG, "Not binding " + getCaption() + " service " + component
                                + ": has META_DATA_DEFAULT_AUTOBIND = false");
                        mSnoozing.add(userId, component);
                    }
                    continue;
                }

                Slog.v(TAG,
                Slog.v(TAG,
                        "enabling " + getCaption() + " for " + userId + ": " + component);
                        "enabling " + getCaption() + " for " + userId + ": " + component);
                registerService(info, userId);
                registerService(info, userId);
                } catch (RemoteException e) {
                    e.rethrowFromSystemServer();
                }
            }
            }
        }
        }
    }
    }
@@ -1620,6 +1628,12 @@ abstract public class ManagedServices {
        return mServicesBound.contains(servicesBindingTag);
        return mServicesBound.contains(servicesBindingTag);
    }
    }


    protected boolean isBoundOrRebinding(final ComponentName cn, final int userId) {
        synchronized (mMutex) {
            return isBound(cn, userId) || mServicesRebinding.contains(Pair.create(cn, userId));
        }
    }

    /**
    /**
     * Remove a service for the given user by ComponentName
     * Remove a service for the given user by ComponentName
     */
     */
@@ -1718,6 +1732,27 @@ abstract public class ManagedServices {
        }
        }
    }
    }


    private ServiceInfo getServiceInfo(ComponentName component, int userId) {
        try {
            return mPm.getServiceInfo(component,
                    PackageManager.GET_META_DATA
                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                    userId);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return null;
    }

    private boolean isAutobindAllowed(ServiceInfo serviceInfo) {
        if (serviceInfo != null && serviceInfo.metaData != null && serviceInfo.metaData.containsKey(
                META_DATA_DEFAULT_AUTOBIND)) {
            return serviceInfo.metaData.getBoolean(META_DATA_DEFAULT_AUTOBIND, true);
        }
        return true;
    }

    public class ManagedServiceInfo implements IBinder.DeathRecipient {
    public class ManagedServiceInfo implements IBinder.DeathRecipient {
        public IInterface service;
        public IInterface service;
        public ComponentName component;
        public ComponentName component;
+21 −0
Original line number Original line Diff line number Diff line
@@ -4546,6 +4546,27 @@ public class NotificationManagerService extends SystemService {
            }
            }
        }
        }
        @Override
        public void requestUnbindListenerComponent(ComponentName component) {
            checkCallerIsSameApp(component.getPackageName());
            int uid = Binder.getCallingUid();
            final long identity = Binder.clearCallingIdentity();
            try {
                synchronized (mNotificationLock) {
                    ManagedServices manager =
                            mAssistants.isComponentEnabledForCurrentProfiles(component)
                                    ? mAssistants
                                    : mListeners;
                    if (manager.isPackageOrComponentAllowed(component.flattenToString(),
                            UserHandle.getUserId(uid))) {
                        manager.setComponentState(component, UserHandle.getUserId(uid), false);
                    }
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }
        @Override
        @Override
        public void setNotificationsShownFromListener(INotificationListener token, String[] keys) {
        public void setNotificationsShownFromListener(INotificationListener token, String[] keys) {
            final long identity = Binder.clearCallingIdentity();
            final long identity = Binder.clearCallingIdentity();
Loading