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

Commit 05329772 authored by Flavio Fiszman's avatar Flavio Fiszman Committed by Automerger Merge Worker
Browse files

Merge "Creates People ContentProvider" into sc-dev am: 79e65a51

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13517165

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I69b820d20fd9471ae4462cd22c337f7be15a3524
parents 89fbe1e1 79e65a51
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5482,6 +5482,9 @@
    <permission android:name="android.permission.SIGNAL_REBOOT_READINESS"
                android:protectionLevel="signature|privileged" />

    <!-- @hide Allows an application to get a People Tile preview for a given shortcut. -->
    <permission android:name="android.permission.GET_PEOPLE_TILE_PREVIEW"
        android:protectionLevel="signature|recents" />

    <!-- Attribution for Geofencing service. -->
    <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
+8 −0
Original line number Diff line number Diff line
@@ -600,6 +600,14 @@
            android:permission="android.permission.BIND_REMOTEVIEWS"
            android:exported="false" />

        <!-- ContentProvider that returns a People Tile preview for a given shortcut -->
        <provider
            android:name="com.android.systemui.people.PeopleProvider"
            android:authorities="com.android.systemui.people.PeopleProvider"
            android:exported="true"
            android:permission="android.permission.GET_PEOPLE_TILE_PREVIEW">
        </provider>

        <!-- a gallery of delicious treats -->
        <service
            android:name=".DessertCaseDream"
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.shared.system;

/**
 *  These strings are part of the {@link com.android.systemui.people.PeopleProvider} API
 *  contract. The API returns a People Tile preview that can be displayed by calling packages.
 *  The provider is part of the SystemUI service, and the strings live here for shared access with
 *  Launcher (caller).
 */
public class PeopleProviderUtils {
    /**
     * ContentProvider URI scheme.
     * @hide
     */
    public static final String PEOPLE_PROVIDER_SCHEME = "content://";

    /**
     * ContentProvider URI authority.
     * @hide
     */
    public static final String PEOPLE_PROVIDER_AUTHORITY =
            "com.android.systemui.people.PeopleProvider";

    /**
     * Method name for getting People Tile preview.
     * @hide
     */
    public static final String GET_PEOPLE_TILE_PREVIEW_METHOD = "get_people_tile_preview";

    /**
     * Extras bundle key specifying shortcut Id of the People Tile preview requested.
     * @hide
     */
    public static final String EXTRAS_KEY_SHORTCUT_ID = "shortcut_id";

    /**
     * Extras bundle key specifying package name of the People Tile preview requested.
     * @hide
     */
    public static final String EXTRAS_KEY_PACKAGE_NAME = "package_name";

    /**
     * Extras bundle key specifying {@code UserHandle} of the People Tile preview requested.
     * @hide
     */
    public static final String EXTRAS_KEY_USER_HANDLE = "user_handle";

    /**
     * Response bundle key to access the returned People Tile preview.
     * @hide
     */
    public static final String RESPONSE_KEY_REMOTE_VIEWS = "remote_views";

    /**
     * Name of the permission needed to get a People Tile preview for a given conversation shortcut.
     * @hide
     */
    public static final String GET_PEOPLE_TILE_PREVIEW_PERMISSION =
            "android.permission.GET_PEOPLE_TILE_PREVIEW";

}
+157 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.people;

import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.Log;
import android.widget.RemoteViews;

import com.android.systemui.shared.system.PeopleProviderUtils;

/** API that returns a People Tile preview. */
public class PeopleProvider extends ContentProvider {

    LauncherApps mLauncherApps;
    IPeopleManager mPeopleManager;

    private static final String TAG = "PeopleProvider";
    private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
    private static final String EMPTY_STRING = "";

    @Override
    public Bundle call(String method, String arg, Bundle extras) {
        if (!doesCallerHavePermission()) {
            String callingPackage = getCallingPackage();
            Log.w(TAG, "API not accessible to calling package: " + callingPackage);
            throw new SecurityException("API not accessible to calling package: " + callingPackage);
        }
        if (!PeopleProviderUtils.GET_PEOPLE_TILE_PREVIEW_METHOD.equals(method)) {
            Log.w(TAG, "Invalid method");
            throw new IllegalArgumentException("Invalid method");
        }

        // If services are not set as mocks in tests, fetch them now.
        mPeopleManager = mPeopleManager != null ? mPeopleManager
                : IPeopleManager.Stub.asInterface(
                        ServiceManager.getService(Context.PEOPLE_SERVICE));
        mLauncherApps = mLauncherApps != null ? mLauncherApps
                : getContext().getSystemService(LauncherApps.class);

        if (mPeopleManager == null || mLauncherApps == null) {
            Log.w(TAG, "Null system managers");
            return null;
        }

        if (extras == null) {
            Log.w(TAG, "Extras can't be null");
            throw new IllegalArgumentException("Extras can't be null");
        }

        String shortcutId = extras.getString(
                PeopleProviderUtils.EXTRAS_KEY_SHORTCUT_ID, EMPTY_STRING);
        String packageName = extras.getString(
                PeopleProviderUtils.EXTRAS_KEY_PACKAGE_NAME, EMPTY_STRING);
        UserHandle userHandle = extras.getParcelable(
                PeopleProviderUtils.EXTRAS_KEY_USER_HANDLE);
        if (shortcutId.isEmpty()) {
            Log.w(TAG, "Invalid shortcut id");
            throw new IllegalArgumentException("Invalid shortcut id");
        }

        if (packageName.isEmpty()) {
            Log.w(TAG, "Invalid package name");
            throw new IllegalArgumentException("Invalid package name");
        }
        if (userHandle == null) {
            Log.w(TAG, "Null user handle");
            throw new IllegalArgumentException("Null user handle");
        }

        ConversationChannel channel;
        try {
            channel = mPeopleManager.getConversation(
                    packageName, userHandle.getIdentifier(), shortcutId);
        } catch (Exception e) {
            Log.w(TAG, "Exception getting tiles: " + e);
            return null;
        }
        PeopleSpaceTile tile = PeopleSpaceUtils.getTile(channel, mLauncherApps);

        if (tile == null) {
            if (DEBUG) Log.i(TAG, "No tile was returned");
            return null;
        }

        if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
        RemoteViews view = PeopleSpaceUtils.createRemoteViews(getContext(), tile, 0);
        final Bundle bundle = new Bundle();
        bundle.putParcelable(PeopleProviderUtils.RESPONSE_KEY_REMOTE_VIEWS, view);
        return bundle;
    }

    private boolean doesCallerHavePermission() {
        return getContext().checkPermission(
                    PeopleProviderUtils.GET_PEOPLE_TILE_PREVIEW_PERMISSION,
                    Binder.getCallingPid(), Binder.getCallingUid())
                == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        throw new IllegalArgumentException("Invalid method");
    }

    @Override
    public String getType(Uri uri) {
        throw new IllegalArgumentException("Invalid method");
    }

    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
        throw new IllegalArgumentException("Invalid method");
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new IllegalArgumentException("Invalid method");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new IllegalArgumentException("Invalid method");
    }
}
+23 −6
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.provider.ContactsContract;
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
@@ -438,7 +439,7 @@ public class PeopleSpaceUtils {
    }

    /** Creates a {@link RemoteViews} for {@code tile}. */
    private static RemoteViews createRemoteViews(Context context,
    public static RemoteViews createRemoteViews(Context context,
            PeopleSpaceTile tile, int appWidgetId) {
        RemoteViews views;
        if (tile.getNotificationKey() != null) {
@@ -455,6 +456,9 @@ public class PeopleSpaceUtils {
            PeopleSpaceTile tile, int appWidgetId) {
        try {
            views.setTextViewText(R.id.name, tile.getUserName().toString());
            views.setImageViewIcon(R.id.person_icon, tile.getUserIcon());
            views.setBoolean(R.id.content_background, "setClipToOutline", true);

            views.setImageViewBitmap(
                    R.id.package_icon,
                    PeopleSpaceUtils.convertDrawableToBitmap(
@@ -462,8 +466,6 @@ public class PeopleSpaceUtils {
                                    tile.getPackageName())
                    )
            );
            views.setImageViewIcon(R.id.person_icon, tile.getUserIcon());
            views.setBoolean(R.id.content_background, "setClipToOutline", true);

            Intent activityIntent = new Intent(context, LaunchConversationActivity.class);
            activityIntent.addFlags(
@@ -612,6 +614,22 @@ public class PeopleSpaceUtils {
                .collect(Collectors.toList());
    }

    /** Returns {@code PeopleSpaceTile} based on provided  {@ConversationChannel}. */
    public static PeopleSpaceTile getTile(ConversationChannel channel, LauncherApps launcherApps) {
        if (channel == null) {
            Log.i(TAG, "ConversationChannel is null");
            return null;
        }

        PeopleSpaceTile tile = new PeopleSpaceTile.Builder(channel, launcherApps).build();
        if (!PeopleSpaceUtils.shouldKeepConversation(tile)) {
            Log.i(TAG, "PeopleSpaceTile is not valid");
            return null;
        }

        return tile;
    }

    /** Returns the last interaction time with the user specified by {@code PeopleSpaceTile}. */
    private static Long getLastInteraction(IPeopleManager peopleManager,
            PeopleSpaceTile tile) {
@@ -701,7 +719,7 @@ public class PeopleSpaceUtils {
     * </li>
     */
    public static boolean shouldKeepConversation(PeopleSpaceTile tile) {
        return tile != null && tile.getUserName().length() != 0;
        return tile != null && !TextUtils.isEmpty(tile.getUserName());
    }

    private static boolean hasBirthdayStatus(PeopleSpaceTile tile, Context context) {
@@ -792,8 +810,7 @@ public class PeopleSpaceUtils {
    private static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
            Context context, int appWidgetId, PeopleSpaceTile tile) {
        updateAppWidgetOptions(appWidgetManager, appWidgetId, tile);
        RemoteViews views = createRemoteViews(context,
                tile, appWidgetId);
        RemoteViews views = createRemoteViews(context, tile, appWidgetId);
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

Loading