All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.app.people.PeopleManager Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * 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 android.app.people;

import static java.util.Objects.requireNonNull;

import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Pair;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * This class allows interaction with conversation and people data.
 */
@SystemService(Context.PEOPLE_SERVICE)
public final class PeopleManager {

    private static final String LOG_TAG = PeopleManager.class.getSimpleName();

    /**
     * @hide
     */
    @VisibleForTesting
    public Map>
            mConversationListeners = new HashMap<>();

    @NonNull
    private Context mContext;

    @NonNull
    private IPeopleManager mService;

    /**
     * @hide
     */
    public PeopleManager(@NonNull Context context) throws ServiceManager.ServiceNotFoundException {
        mContext = context;
        mService = IPeopleManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
                Context.PEOPLE_SERVICE));
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public PeopleManager(@NonNull Context context, IPeopleManager service) {
        mContext = context;
        mService = service;
    }

    /**
     * Returns whether a shortcut has a conversation associated.
     *
     * 

Requires android.permission.READ_PEOPLE_DATA permission. * *

This method may return different results for the same shortcut over time, as an app adopts * conversation features or if a user hasn't communicated with the conversation associated to * the shortcut in a while, so the result should not be stored and relied on indefinitely by * clients. * * @param packageName name of the package the conversation is part of * @param shortcutId the shortcut id backing the conversation * @return whether the {@shortcutId} is backed by a Conversation. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.READ_PEOPLE_DATA) public boolean isConversation(@NonNull String packageName, @NonNull String shortcutId) { Preconditions.checkStringNotEmpty(packageName); Preconditions.checkStringNotEmpty(shortcutId); try { return mService.isConversation(packageName, mContext.getUserId(), shortcutId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Sets or updates a {@link ConversationStatus} for a conversation. * *

Statuses are meant to represent current information about the conversation. Like * notifications, they are transient and are not persisted beyond a reboot, nor are they * backed up and restored.

*

If the provided conversation shortcut is not already pinned, or cached by the system, * it will remain cached as long as the status is active.

* * @param conversationId the {@link ShortcutInfo#getId() id} of the shortcut backing the * conversation that has an active status * @param status the current status for the given conversation * @return whether the role is available in the system */ public void addOrUpdateStatus(@NonNull String conversationId, @NonNull ConversationStatus status) { Preconditions.checkStringNotEmpty(conversationId); Objects.requireNonNull(status); try { mService.addOrUpdateStatus( mContext.getPackageName(), mContext.getUserId(), conversationId, status); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Unpublishes a given status from the given conversation. * * @param conversationId the {@link ShortcutInfo#getId() id} of the shortcut backing the * conversation that has an active status * @param statusId the {@link ConversationStatus#getId() id} of a published status for the * given conversation */ public void clearStatus(@NonNull String conversationId, @NonNull String statusId) { Preconditions.checkStringNotEmpty(conversationId); Preconditions.checkStringNotEmpty(statusId); try { mService.clearStatus( mContext.getPackageName(), mContext.getUserId(), conversationId, statusId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Removes all published statuses for the given conversation. * * @param conversationId the {@link ShortcutInfo#getId() id} of the shortcut backing the * conversation that has one or more active statuses */ public void clearStatuses(@NonNull String conversationId) { Preconditions.checkStringNotEmpty(conversationId); try { mService.clearStatuses( mContext.getPackageName(), mContext.getUserId(), conversationId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns all of the currently published statuses for a given conversation. * * @param conversationId the {@link ShortcutInfo#getId() id} of the shortcut backing the * conversation that has one or more active statuses */ public @NonNull List getStatuses(@NonNull String conversationId) { try { final ParceledListSlice parceledList = mService.getStatuses( mContext.getPackageName(), mContext.getUserId(), conversationId); if (parceledList != null) { return parceledList.getList(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } return new ArrayList<>(); } /** * Listeners for conversation changes. * * @hide */ public interface ConversationListener { /** * Triggers when the conversation registered for a listener has been updated. * * @param conversation The conversation with modified data * @see IPeopleManager#registerConversationListener(String, int, String, * android.app.people.ConversationListener) * *

Only system root and SysUI have access to register the listener. */ default void onConversationUpdate(@NonNull ConversationChannel conversation) { } } /** * Register a listener to watch for changes to the conversation identified by {@code * packageName}, {@code userId}, and {@code shortcutId}. * * @param packageName The package name to match and filter the conversation to send updates for. * @param userId The user ID to match and filter the conversation to send updates for. * @param shortcutId The shortcut ID to match and filter the conversation to send updates for. * @param listener The listener to register to receive conversation updates. * @param executor {@link Executor} to handle the listeners. To dispatch listeners to the * main thread of your application, you can use * {@link android.content.Context#getMainExecutor()}. * @hide */ public void registerConversationListener(String packageName, int userId, String shortcutId, ConversationListener listener, Executor executor) { requireNonNull(listener, "Listener cannot be null"); requireNonNull(packageName, "Package name cannot be null"); requireNonNull(shortcutId, "Shortcut ID cannot be null"); synchronized (mConversationListeners) { IConversationListener proxy = (IConversationListener) new ConversationListenerProxy( executor, listener); try { mService.registerConversationListener( packageName, userId, shortcutId, proxy); mConversationListeners.put(listener, new Pair<>(executor, proxy)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Unregisters the listener previously registered to watch conversation changes. * * @param listener The listener to register to receive conversation updates. * @hide */ public void unregisterConversationListener( ConversationListener listener) { requireNonNull(listener, "Listener cannot be null"); synchronized (mConversationListeners) { if (mConversationListeners.containsKey(listener)) { IConversationListener proxy = mConversationListeners.remove(listener).second; try { mService.unregisterConversationListener(proxy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } } /** * Listener proxy class for {@link ConversationListener} * * @hide */ private static class ConversationListenerProxy extends IConversationListener.Stub { private final Executor mExecutor; private final ConversationListener mListener; ConversationListenerProxy(Executor executor, ConversationListener listener) { mExecutor = executor; mListener = listener; } @Override public void onConversationUpdate(@NonNull ConversationChannel conversation) { if (mListener == null || mExecutor == null) { // Binder is dead. Slog.e(LOG_TAG, "Binder is dead"); return; } mExecutor.execute(() -> mListener.onConversationUpdate(conversation)); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy