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

src.android.service.selectiontoolbar.DefaultSelectionToolbarRenderService Maven / Gradle / Ivy

/*
 * 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.service.selectiontoolbar;

import static android.view.selectiontoolbar.SelectionToolbarManager.ERROR_DO_NOT_ALLOW_MULTIPLE_TOOL_BAR;
import static android.view.selectiontoolbar.SelectionToolbarManager.NO_TOOLBAR_ID;

import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.selectiontoolbar.ShowInfo;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.UUID;

/**
 * The default implementation of {@link SelectionToolbarRenderService}.
 *
 * 

NOTE: The requests are handled on the service main thread. * * @hide */ // TODO(b/214122495): fix class not found then move to system service folder public final class DefaultSelectionToolbarRenderService extends SelectionToolbarRenderService { private static final String TAG = "DefaultSelectionToolbarRenderService"; // TODO(b/215497659): handle remove if the client process dies. // Only show one toolbar, dismiss the old ones and remove from cache private final SparseArray> mToolbarCache = new SparseArray<>(); /** * Only allow one package to create one toolbar. */ private boolean canShowToolbar(int uid, ShowInfo showInfo) { if (showInfo.getWidgetToken() != NO_TOOLBAR_ID) { return true; } return mToolbarCache.indexOfKey(uid) < 0; } @Override public void onShow(int callingUid, ShowInfo showInfo, SelectionToolbarRenderService.RemoteCallbackWrapper callbackWrapper) { if (!canShowToolbar(callingUid, showInfo)) { Slog.e(TAG, "Do not allow multiple toolbar for the app."); callbackWrapper.onError(ERROR_DO_NOT_ALLOW_MULTIPLE_TOOL_BAR); return; } long widgetToken = showInfo.getWidgetToken() == NO_TOOLBAR_ID ? UUID.randomUUID().getMostSignificantBits() : showInfo.getWidgetToken(); if (mToolbarCache.indexOfKey(callingUid) < 0) { RemoteSelectionToolbar toolbar = new RemoteSelectionToolbar(this, widgetToken, showInfo.getHostInputToken(), callbackWrapper, this::transferTouch); mToolbarCache.put(callingUid, new Pair<>(widgetToken, toolbar)); } Slog.v(TAG, "onShow() for " + widgetToken); Pair toolbarPair = mToolbarCache.get(callingUid); if (toolbarPair.first == widgetToken) { toolbarPair.second.show(showInfo); } else { Slog.w(TAG, "onShow() for unknown " + widgetToken); } } @Override public void onHide(long widgetToken) { RemoteSelectionToolbar toolbar = getRemoteSelectionToolbarByTokenLocked(widgetToken); if (toolbar != null) { Slog.v(TAG, "onHide() for " + widgetToken); toolbar.hide(widgetToken); } } @Override public void onDismiss(long widgetToken) { RemoteSelectionToolbar toolbar = getRemoteSelectionToolbarByTokenLocked(widgetToken); if (toolbar != null) { Slog.v(TAG, "onDismiss() for " + widgetToken); toolbar.dismiss(widgetToken); removeRemoteSelectionToolbarByTokenLocked(widgetToken); } } @Override public void onToolbarShowTimeout(int callingUid) { Slog.w(TAG, "onToolbarShowTimeout for callingUid = " + callingUid); Pair toolbarPair = mToolbarCache.get(callingUid); if (toolbarPair != null) { RemoteSelectionToolbar remoteToolbar = toolbarPair.second; remoteToolbar.dismiss(toolbarPair.first); remoteToolbar.onToolbarShowTimeout(); mToolbarCache.remove(callingUid); } } private RemoteSelectionToolbar getRemoteSelectionToolbarByTokenLocked(long widgetToken) { for (int i = 0; i < mToolbarCache.size(); i++) { Pair toolbarPair = mToolbarCache.valueAt(i); if (toolbarPair.first == widgetToken) { return toolbarPair.second; } } return null; } private void removeRemoteSelectionToolbarByTokenLocked(long widgetToken) { for (int i = 0; i < mToolbarCache.size(); i++) { Pair toolbarPair = mToolbarCache.valueAt(i); if (toolbarPair.first == widgetToken) { mToolbarCache.remove(mToolbarCache.keyAt(i)); return; } } } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { int size = mToolbarCache.size(); pw.print("number selectionToolbar: "); pw.println(size); String pfx = " "; for (int i = 0; i < size; i++) { pw.print("#"); pw.println(i); int callingUid = mToolbarCache.keyAt(i); pw.print(pfx); pw.print("callingUid: "); pw.println(callingUid); Pair toolbarPair = mToolbarCache.valueAt(i); RemoteSelectionToolbar selectionToolbar = toolbarPair.second; pw.print(pfx); pw.print("selectionToolbar: "); selectionToolbar.dump(pfx, pw); pw.println(); } } }