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

Commit 2b2a95bf authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Make DnD check work profile contacts" into rvc-dev am: 0e7efa97

Change-Id: I02324f1ef3a235af1550b9ceadffec9b273d8ac7
parents 03cd85ca 0e7efa97
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
@@ -2210,6 +2211,28 @@ public final class ContactsContract {
        public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri) {
            return openContactPhotoInputStream(cr, contactUri, false);
        }

        /**
         * Creates and returns a corp lookup URI from the given enterprise lookup URI by removing
         * {@link #ENTERPRISE_CONTACT_LOOKUP_PREFIX} from the key. Returns {@code null} if the given
         * URI is not an enterprise lookup URI.
         *
         * @hide
         */
        @Nullable
        public static Uri createCorpLookupUriFromEnterpriseLookupUri(
                @NonNull Uri enterpriseLookupUri) {
            final List<String> pathSegments = enterpriseLookupUri.getPathSegments();
            if (pathSegments == null || pathSegments.size() <= 2) {
                return null;
            }
            final String key = pathSegments.get(2);
            if (TextUtils.isEmpty(key) || !key.startsWith(ENTERPRISE_CONTACT_LOOKUP_PREFIX)) {
                return null;
            }
            final String actualKey = key.substring(ENTERPRISE_CONTACT_LOOKUP_PREFIX.length());
            return Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, actualKey);
        }
    }

    /**
+45 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.notification;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.Person;
import android.content.ContentProvider;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
@@ -28,6 +29,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.Settings;
@@ -38,6 +40,8 @@ import android.util.Log;
import android.util.LruCache;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;

import libcore.util.EmptyArray;

import java.util.ArrayList;
@@ -392,27 +396,58 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
        return searchContacts(context, numberUri);
    }

    private LookupResult searchContacts(Context context, Uri lookupUri) {
    @VisibleForTesting
    LookupResult searchContacts(Context context, Uri lookupUri) {
        LookupResult lookupResult = new LookupResult();
        Cursor c = null;
        try {
            c = context.getContentResolver().query(lookupUri, LOOKUP_PROJECTION, null, null, null);
        final Uri corpLookupUri =
                ContactsContract.Contacts.createCorpLookupUriFromEnterpriseLookupUri(lookupUri);
        if (corpLookupUri == null) {
            addContacts(lookupResult, context, lookupUri);
        } else {
            addWorkContacts(lookupResult, context, corpLookupUri);
        }
        return lookupResult;
    }

    private void addWorkContacts(LookupResult lookupResult, Context context, Uri corpLookupUri) {
        final int workUserId = findWorkUserId(context);
        if (workUserId == -1) {
            Slog.w(TAG, "Work profile user ID not found for work contact: " + corpLookupUri);
            return;
        }
        final Uri corpLookupUriWithUserId =
                ContentProvider.maybeAddUserId(corpLookupUri, workUserId);
        addContacts(lookupResult, context, corpLookupUriWithUserId);
    }

    /** Returns the user ID of the managed profile or -1 if none is found. */
    private int findWorkUserId(Context context) {
        final UserManager userManager = context.getSystemService(UserManager.class);
        final int[] profileIds =
                userManager.getProfileIds(context.getUserId(), /* enabledOnly= */ true);
        for (int profileId : profileIds) {
            if (userManager.isManagedProfile(profileId)) {
                return profileId;
            }
        }
        return -1;
    }

    /** Modifies the given lookup result to add contacts found at the given URI. */
    private void addContacts(LookupResult lookupResult, Context context, Uri uri) {
        try (Cursor c = context.getContentResolver().query(
                uri, LOOKUP_PROJECTION, null, null, null)) {
            if (c == null) {
                Slog.w(TAG, "Null cursor from contacts query.");
                return lookupResult;
                return;
            }
            while (c.moveToNext()) {
                lookupResult.mergeContact(c);
            }
        } catch (Throwable t) {
            Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t);
        } finally {
            if (c != null) {
                c.close();
        }
    }
        return lookupResult;
    }

    private static class LookupResult {
        private static final long CONTACT_REFRESH_MILLIS = 60 * 60 * 1000;  // 1hr
+71 −0
Original line number Diff line number Diff line
@@ -16,11 +16,23 @@
package com.android.server.notification;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Notification;
import android.app.Person;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserManager;
import android.provider.ContactsContract;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.SpannableString;

@@ -30,6 +42,7 @@ import com.android.server.UiServiceTestCase;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

import java.util.ArrayList;
import java.util.Arrays;
@@ -169,6 +182,64 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
        assertStringArrayEquals("testPeopleArrayList", expected, result);
    }

    @Test
    public void testSearchContacts_workContact_queriesWorkContactProvider()
            throws Exception {
        final int personalUserId = 0;
        final int workUserId = 12;
        final int contactId = 12345;
        final Context mockContext = mock(Context.class);
        when(mockContext.getUserId()).thenReturn(personalUserId);
        final UserManager mockUserManager = mock(UserManager.class);
        when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
        when(mockUserManager.getProfileIds(personalUserId, /* enabledOnly= */ true))
                .thenReturn(new int[] {personalUserId, workUserId});
        when(mockUserManager.isManagedProfile(workUserId)).thenReturn(true);
        final ContentResolver mockContentResolver = mock(ContentResolver.class);
        when(mockContext.getContentResolver()).thenReturn(mockContentResolver);
        final Uri lookupUri = Uri.withAppendedPath(
                ContactsContract.Contacts.CONTENT_LOOKUP_URI,
                ContactsContract.Contacts.ENTERPRISE_CONTACT_LOOKUP_PREFIX + contactId);

        new ValidateNotificationPeople().searchContacts(mockContext, lookupUri);

        ArgumentCaptor<Uri> queryUri = ArgumentCaptor.forClass(Uri.class);
        verify(mockContentResolver).query(
                queryUri.capture(),
                any(),
                /* selection= */ isNull(),
                /* selectionArgs= */ isNull(),
                /* sortOrder= */ isNull());
        assertEquals(workUserId, ContentProvider.getUserIdFromUri(queryUri.getValue()));
    }

    @Test
    public void testSearchContacts_personalContact_queriesPersonalContactProvider()
            throws Exception {
        final int personalUserId = 0;
        final int workUserId = 12;
        final int contactId = 12345;
        final Context mockContext = mock(Context.class);
        when(mockContext.getUserId()).thenReturn(personalUserId);
        final UserManager mockUserManager = mock(UserManager.class);
        when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
        final ContentResolver mockContentResolver = mock(ContentResolver.class);
        when(mockContext.getContentResolver()).thenReturn(mockContentResolver);
        final Uri lookupUri = Uri.withAppendedPath(
                ContactsContract.Contacts.CONTENT_LOOKUP_URI, String.valueOf(contactId));

        new ValidateNotificationPeople().searchContacts(mockContext, lookupUri);

        ArgumentCaptor<Uri> queryUri = ArgumentCaptor.forClass(Uri.class);
        verify(mockContentResolver).query(
                queryUri.capture(),
                any(),
                /* selection= */ isNull(),
                /* selectionArgs= */ isNull(),
                /* sortOrder= */ isNull());
        assertFalse(ContentProvider.uriHasUserId(queryUri.getValue()));
    }

    private void assertStringArrayEquals(String message, String[] expected, String[] result) {
        String expectedString = Arrays.toString(expected);
        String resultString = Arrays.toString(result);