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

Commit 14e327b5 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge "API for querying/revoking current NotificationAssistant"

parents 5aea7e3e d9425663
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -501,6 +501,13 @@ package android.app {
    method public org.json.JSONObject toJson() throws org.json.JSONException;
  }
  public class NotificationManager {
    method @Nullable public android.content.ComponentName getAllowedNotificationAssistant();
    method @Nullable public android.content.ComponentName getAllowedNotificationAssistantForUser(android.os.UserHandle);
    method public void setNotificationAssistantAccessGranted(android.content.ComponentName, boolean);
    method public void setNotificationAssistantAccessGrantedForUser(android.content.ComponentName, android.os.UserHandle, boolean);
  }
  public final class StatsManager {
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void addConfig(long, byte[]) throws android.app.StatsManager.StatsUnavailableException;
    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
+2 −0
Original line number Diff line number Diff line
@@ -154,6 +154,8 @@ interface INotificationManager
    void setNotificationAssistantAccessGrantedForUser(in ComponentName assistant, int userId, boolean enabled);
    List<String> getEnabledNotificationListenerPackages();
    List<ComponentName> getEnabledNotificationListeners(int userId);
    ComponentName getAllowedNotificationAssistantForUser(int userId);
    ComponentName getAllowedNotificationAssistant();

    int getZenMode();
    ZenModeConfig getZenModeConfig();
+75 −0
Original line number Diff line number Diff line
@@ -1155,6 +1155,19 @@ public class NotificationManager {
        }
    }

    /**
     * Checks whether the user has approved a given
     * {@link android.service.notification.NotificationAssistantService}.
     *
     * <p>
     * The assistant service must belong to the calling app.
     *
     * <p>
     * Apps can request notification assistant access by sending the user to the activity that
     * matches the system intent action
     * TODO: STOPSHIP: Add correct intent
     * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
     */
    public boolean isNotificationAssistantAccessGranted(ComponentName assistant) {
        INotificationManager service = getService();
        try {
@@ -1266,6 +1279,45 @@ public class NotificationManager {
        }
    }

    /**
     * Grants/revokes Notification Assistant access to {@code assistant} for current user.
     *
     * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
     *                  current assistant
     * @param granted Grant/revoke access
     * @hide
     */
    @SystemApi
    public void setNotificationAssistantAccessGranted(ComponentName assistant, boolean granted) {
        INotificationManager service = getService();
        try {
            service.setNotificationAssistantAccessGranted(assistant, granted);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Grants/revokes Notification Assistant access to {@code assistant} for given user.
     *
     * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
     *                  current assistant
     * @param user handle to associate assistant with
     * @param granted Grant/revoke access
     * @hide
     */
    @SystemApi
    public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
            UserHandle user, boolean granted) {
        INotificationManager service = getService();
        try {
            service.setNotificationAssistantAccessGrantedForUser(assistant, user.getIdentifier(),
                    granted);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** @hide */
    public List<ComponentName> getEnabledNotificationListeners(int userId) {
        INotificationManager service = getService();
@@ -1276,6 +1328,29 @@ public class NotificationManager {
        }
    }

    /** @hide */
    @SystemApi
    public @Nullable ComponentName getAllowedNotificationAssistantForUser(UserHandle user) {
        INotificationManager service = getService();
        try {
            return service.getAllowedNotificationAssistantForUser(user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** @hide */
    @SystemApi
    public @Nullable ComponentName getAllowedNotificationAssistant() {
        INotificationManager service = getService();
        try {
            return service.getAllowedNotificationAssistant();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }


    private Context mContext;

    private static void checkRequired(String name, Object value) {
+45 −1
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
@@ -3654,6 +3655,22 @@ public class NotificationManagerService extends SystemService {
            return mListeners.getAllowedComponents(userId);
        }

        @Override
        public ComponentName getAllowedNotificationAssistantForUser(int userId) {
            checkCallerIsSystem();
            List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
            if (allowedComponents.size() > 1) {
                throw new IllegalStateException(
                        "At most one NotificationAssistant: " + allowedComponents.size());
            }
            return CollectionUtils.firstOrNull(allowedComponents);
        }

        @Override
        public ComponentName getAllowedNotificationAssistant() {
            return getAllowedNotificationAssistantForUser(getCallingUserHandle().getIdentifier());
        }

        @Override
        public boolean isNotificationListenerAccessGranted(ComponentName listener) {
            Preconditions.checkNotNull(listener);
@@ -3722,8 +3739,15 @@ public class NotificationManagerService extends SystemService {
        @Override
        public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
                int userId, boolean granted) throws RemoteException {
            Preconditions.checkNotNull(assistant);
            checkCallerIsSystemOrShell();
            if (assistant == null) {
                ComponentName allowedAssistant = CollectionUtils.firstOrNull(
                        mAssistants.getAllowedComponents(userId));
                if (allowedAssistant != null) {
                    setNotificationAssistantAccessGrantedForUser(allowedAssistant, userId, false);
                }
                return;
            }
            final long identity = Binder.clearCallingIdentity();
            try {
                if (mAllowedManagedServicePackages.test(assistant.getPackageName())) {
@@ -7264,6 +7288,26 @@ public class NotificationManagerService extends SystemService {
                }
            }
        }

        @Override
        protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
                boolean isPrimary, boolean enabled) {
            // Ensures that only one component is enabled at a time
            if (enabled) {
                List<ComponentName> allowedComponents = getAllowedComponents(userId);
                if (!allowedComponents.isEmpty()) {
                    ComponentName currentComponent = CollectionUtils.firstOrNull(allowedComponents);
                    if (currentComponent.flattenToString().equals(pkgOrComponent)) return;
                    try {
                        getBinderService().setNotificationAssistantAccessGrantedForUser(
                                currentComponent, userId, false);
                    } catch (RemoteException e) {
                        e.rethrowFromSystemServer();
                    }
                }
            }
            super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled);
        }
    }

    public class NotificationListeners extends ManagedServices {
+30 −5
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.INotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.IPackageManager;
@@ -36,22 +37,17 @@ import android.os.UserManager;
import android.util.IntArray;
import android.util.Xml;

import com.android.internal.util.FastXmlSerializer;
import com.android.server.UiServiceTestCase;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

@@ -65,6 +61,8 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
    private UserManager mUm;
    @Mock
    NotificationManagerService mNm;
    @Mock
    private INotificationManager mINm;

    NotificationAssistants mAssistants;

@@ -83,6 +81,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
        getContext().setMockPackageManager(mPm);
        getContext().addMockSystemService(Context.USER_SERVICE, mUm);
        mAssistants = spy(mNm.new NotificationAssistants(getContext(), mLock, mUserProfiles, miPm));
        when(mNm.getBinderService()).thenReturn(mINm);

        List<ResolveInfo> approved = new ArrayList<>();
        ResolveInfo resolve = new ResolveInfo();
@@ -136,4 +135,30 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
        verify(mAssistants, times(1)).addApprovedList(
                new ComponentName("b", "b").flattenToString(),10, true);
    }

    @Test
    public void testSetPackageOrComponentEnabled_onlyOnePackage() throws Exception {
        ComponentName component1 = ComponentName.unflattenFromString("package/Component1");
        ComponentName component2 = ComponentName.unflattenFromString("package/Component2");
        mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
                true);
        verify(mINm, never()).setNotificationAssistantAccessGrantedForUser(any(ComponentName.class),
                eq(mZero.id), anyBoolean());

        mAssistants.setPackageOrComponentEnabled(component2.flattenToString(), mZero.id, true,
                true);
        verify(mINm, times(1)).setNotificationAssistantAccessGrantedForUser(component1, mZero.id,
                false);
    }

    @Test
    public void testSetPackageOrComponentEnabled_samePackage() throws Exception {
        ComponentName component1 = ComponentName.unflattenFromString("package/Component1");
        mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
                true);
        mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
                true);
        verify(mINm, never()).setNotificationAssistantAccessGrantedForUser(any(ComponentName.class),
                eq(mZero.id), anyBoolean());
    }
}
Loading