diff options
29 files changed, 2 insertions, 4419 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 8647dd29b71a..e57849957f13 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -237,8 +237,6 @@ import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.IContentCaptureManager; import android.view.displayhash.DisplayHashManager; import android.view.inputmethod.InputMethodManager; -import android.view.selectiontoolbar.ISelectionToolbarManager; -import android.view.selectiontoolbar.SelectionToolbarManager; import android.view.textclassifier.TextClassificationManager; import android.view.textservice.TextServicesManager; import android.view.translation.ITranslationManager; @@ -379,17 +377,6 @@ public final class SystemServiceRegistry { return new TextClassificationManager(ctx); }}); - registerService(Context.SELECTION_TOOLBAR_SERVICE, SelectionToolbarManager.class, - new CachedServiceFetcher<SelectionToolbarManager>() { - @Override - public SelectionToolbarManager createService(ContextImpl ctx) - throws ServiceNotFoundException { - IBinder b = ServiceManager.getServiceOrThrow( - Context.SELECTION_TOOLBAR_SERVICE); - return new SelectionToolbarManager(ctx.getOuterContext(), - ISelectionToolbarManager.Stub.asInterface(b)); - }}); - registerService(Context.FONT_SERVICE, FontManager.class, new CachedServiceFetcher<FontManager>() { @Override diff --git a/core/java/android/service/selectiontoolbar/DefaultSelectionToolbarRenderService.java b/core/java/android/service/selectiontoolbar/DefaultSelectionToolbarRenderService.java deleted file mode 100644 index ad73a53cfd87..000000000000 --- a/core/java/android/service/selectiontoolbar/DefaultSelectionToolbarRenderService.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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}. - * - * <p><b>NOTE:<b/> 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<Pair<Long, RemoteSelectionToolbar>> 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, - callbackWrapper, this::transferTouch); - mToolbarCache.put(callingUid, new Pair<>(widgetToken, toolbar)); - } - Slog.v(TAG, "onShow() for " + widgetToken); - Pair<Long, RemoteSelectionToolbar> 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<Long, RemoteSelectionToolbar> 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<Long, RemoteSelectionToolbar> 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<Long, RemoteSelectionToolbar> 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<Long, RemoteSelectionToolbar> toolbarPair = mToolbarCache.valueAt(i); - RemoteSelectionToolbar selectionToolbar = toolbarPair.second; - pw.print(pfx); pw.print("selectionToolbar: "); - selectionToolbar.dump(pfx, pw); - pw.println(); - } - } -} - diff --git a/core/java/android/service/selectiontoolbar/FloatingToolbarRoot.java b/core/java/android/service/selectiontoolbar/FloatingToolbarRoot.java deleted file mode 100644 index adc9251d89be..000000000000 --- a/core/java/android/service/selectiontoolbar/FloatingToolbarRoot.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2022 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 android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Rect; -import android.os.IBinder; -import android.util.Log; -import android.view.MotionEvent; -import android.widget.LinearLayout; - -import java.io.PrintWriter; - -/** - * This class is the root view for the selection toolbar. It is responsible for - * detecting the click on the item and to also transfer input focus to the application. - * - * @hide - */ -@SuppressLint("ViewConstructor") -public class FloatingToolbarRoot extends LinearLayout { - - private static final boolean DEBUG = false; - private static final String TAG = "FloatingToolbarRoot"; - - private final IBinder mTargetInputToken; - private final SelectionToolbarRenderService.TransferTouchListener mTransferTouchListener; - private final Rect mContentRect = new Rect(); - - private int mLastDownX = -1; - private int mLastDownY = -1; - - public FloatingToolbarRoot(Context context, IBinder targetInputToken, - SelectionToolbarRenderService.TransferTouchListener transferTouchListener) { - super(context); - mTargetInputToken = targetInputToken; - mTransferTouchListener = transferTouchListener; - setFocusable(false); - } - - /** - * Sets the Rect that shows the selection toolbar content. - */ - public void setContentRect(Rect contentRect) { - mContentRect.set(contentRect); - } - - @Override - @SuppressLint("ClickableViewAccessibility") - public boolean dispatchTouchEvent(MotionEvent event) { - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - mLastDownX = (int) event.getX(); - mLastDownY = (int) event.getY(); - if (DEBUG) { - Log.d(TAG, "downX=" + mLastDownX + " downY=" + mLastDownY); - } - // TODO(b/215497659): Check FLAG_WINDOW_IS_PARTIALLY_OBSCURED - if (!mContentRect.contains(mLastDownX, mLastDownY)) { - if (DEBUG) { - Log.d(TAG, "Transfer touch focus to application."); - } - mTransferTouchListener.onTransferTouch(getViewRootImpl().getInputToken(), - mTargetInputToken); - } - } - return super.dispatchTouchEvent(event); - } - - void dump(String prefix, PrintWriter pw) { - pw.print(prefix); pw.println("FloatingToolbarRoot:"); - pw.print(prefix + " "); pw.print("last down X: "); pw.println(mLastDownX); - pw.print(prefix + " "); pw.print("last down Y: "); pw.println(mLastDownY); - } -} diff --git a/core/java/android/service/selectiontoolbar/ISelectionToolbarRenderService.aidl b/core/java/android/service/selectiontoolbar/ISelectionToolbarRenderService.aidl deleted file mode 100644 index 79281b8b361d..000000000000 --- a/core/java/android/service/selectiontoolbar/ISelectionToolbarRenderService.aidl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.ShowInfo; - -/** - * The service to render the selection toolbar menus. - * - * @hide - */ -oneway interface ISelectionToolbarRenderService { - void onConnected(in IBinder callback); - void onShow(int callingUid, in ShowInfo showInfo, in ISelectionToolbarCallback callback); - void onHide(long widgetToken); - void onDismiss(int callingUid, long widgetToken); -} diff --git a/core/java/android/service/selectiontoolbar/ISelectionToolbarRenderServiceCallback.aidl b/core/java/android/service/selectiontoolbar/ISelectionToolbarRenderServiceCallback.aidl deleted file mode 100644 index f6c47ddf1e00..000000000000 --- a/core/java/android/service/selectiontoolbar/ISelectionToolbarRenderServiceCallback.aidl +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2022 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 android.os.IBinder; - -/** - * The interface from the SelectionToolbarRenderService to the system. - * - * @hide - */ -oneway interface ISelectionToolbarRenderServiceCallback { - void transferTouch(in IBinder source, in IBinder target); -} diff --git a/core/java/android/service/selectiontoolbar/OWNERS b/core/java/android/service/selectiontoolbar/OWNERS deleted file mode 100644 index 5500b92868dd..000000000000 --- a/core/java/android/service/selectiontoolbar/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# Bug component: 709498 - -augale@google.com -joannechung@google.com -licha@google.com -lpeter@google.com -svetoslavganov@google.com -toki@google.com -tonymak@google.com -tymtsai@google.com
\ No newline at end of file diff --git a/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java b/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java deleted file mode 100644 index 59e3a5e70376..000000000000 --- a/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java +++ /dev/null @@ -1,1398 +0,0 @@ -/* - * Copyright (C) 2022 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 android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.content.Context; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.drawable.AnimatedVectorDrawable; -import android.graphics.drawable.Drawable; -import android.os.IBinder; -import android.text.TextUtils; -import android.util.Log; -import android.util.Size; -import android.view.ContextThemeWrapper; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.SurfaceControlViewHost; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.view.animation.Animation; -import android.view.animation.AnimationSet; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.Transformation; -import android.view.selectiontoolbar.ShowInfo; -import android.view.selectiontoolbar.ToolbarMenuItem; -import android.view.selectiontoolbar.WidgetInfo; -import android.widget.ArrayAdapter; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; - -import com.android.internal.R; -import com.android.internal.util.Preconditions; -import com.android.internal.widget.floatingtoolbar.FloatingToolbar; - -import java.io.PrintWriter; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; - -/** - * This class is responsible for rendering/animation of the selection toolbar in the remote - * system process. It holds 2 panels (i.e. main panel and overflow panel) and an overflow - * button to transition between panels. - * - * @hide - */ -// TODO(b/215497659): share code with LocalFloatingToolbarPopup -final class RemoteSelectionToolbar { - private static final String TAG = "RemoteSelectionToolbar"; - - /* Minimum and maximum number of items allowed in the overflow. */ - private static final int MIN_OVERFLOW_SIZE = 2; - private static final int MAX_OVERFLOW_SIZE = 4; - - private final Context mContext; - - /* Margins between the popup window and its content. */ - private final int mMarginHorizontal; - private final int mMarginVertical; - - /* View components */ - private final ViewGroup mContentContainer; // holds all contents. - private final ViewGroup mMainPanel; // holds menu items that are initially displayed. - // holds menu items hidden in the overflow. - private final OverflowPanel mOverflowPanel; - private final ImageButton mOverflowButton; // opens/closes the overflow. - /* overflow button drawables. */ - private final Drawable mArrow; - private final Drawable mOverflow; - private final AnimatedVectorDrawable mToArrow; - private final AnimatedVectorDrawable mToOverflow; - - private final OverflowPanelViewHelper mOverflowPanelViewHelper; - - /* Animation interpolators. */ - private final Interpolator mLogAccelerateInterpolator; - private final Interpolator mFastOutSlowInInterpolator; - private final Interpolator mLinearOutSlowInInterpolator; - private final Interpolator mFastOutLinearInInterpolator; - - /* Animations. */ - private final AnimatorSet mShowAnimation; - private final AnimatorSet mDismissAnimation; - private final AnimatorSet mHideAnimation; - private final AnimationSet mOpenOverflowAnimation; - private final AnimationSet mCloseOverflowAnimation; - private final Animation.AnimationListener mOverflowAnimationListener; - - private final Rect mViewPortOnScreen = new Rect(); // portion of screen we can draw in. - - private final int mLineHeight; - private final int mIconTextSpacing; - - private final long mSelectionToolbarToken; - private IBinder mHostInputToken; - private final SelectionToolbarRenderService.RemoteCallbackWrapper mCallbackWrapper; - private final SelectionToolbarRenderService.TransferTouchListener mTransferTouchListener; - private int mPopupWidth; - private int mPopupHeight; - // Coordinates to show the toolbar relative to the specified view port - private final Point mRelativeCoordsForToolbar = new Point(); - private List<ToolbarMenuItem> mMenuItems; - private SurfaceControlViewHost mSurfaceControlViewHost; - private SurfaceControlViewHost.SurfacePackage mSurfacePackage; - - /** - * @see OverflowPanelViewHelper#preparePopupContent(). - */ - private final Runnable mPreparePopupContentRTLHelper = new Runnable() { - @Override - public void run() { - setPanelsStatesAtRestingPosition(); - mContentContainer.setAlpha(1); - } - }; - - private boolean mDismissed = true; // tracks whether this popup is dismissed or dismissing. - private boolean mHidden; // tracks whether this popup is hidden or hiding. - - /* Calculated sizes for panels and overflow button. */ - private final Size mOverflowButtonSize; - private Size mOverflowPanelSize; // Should be null when there is no overflow. - private Size mMainPanelSize; - - /* Menu items and click listeners */ - private final View.OnClickListener mMenuItemButtonOnClickListener; - - private boolean mOpenOverflowUpwards; // Whether the overflow opens upwards or downwards. - private boolean mIsOverflowOpen; - - private int mTransitionDurationScale; // Used to scale the toolbar transition duration. - - private final Rect mPreviousContentRect = new Rect(); - - private final Rect mTempContentRect = new Rect(); - private final Rect mTempContentRectForRoot = new Rect(); - private final int[] mTempCoords = new int[2]; - - RemoteSelectionToolbar(Context context, long selectionToolbarToken, ShowInfo showInfo, - SelectionToolbarRenderService.RemoteCallbackWrapper callbackWrapper, - SelectionToolbarRenderService.TransferTouchListener transferTouchListener) { - mContext = applyDefaultTheme(context, showInfo.isIsLightTheme()); - mSelectionToolbarToken = selectionToolbarToken; - mCallbackWrapper = callbackWrapper; - mTransferTouchListener = transferTouchListener; - mHostInputToken = showInfo.getHostInputToken(); - mContentContainer = createContentContainer(mContext); - mMarginHorizontal = mContext.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin); - mMarginVertical = mContext.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin); - mLineHeight = mContext.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_height); - mIconTextSpacing = mContext.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_icon_text_spacing); - - // Interpolators - mLogAccelerateInterpolator = new LogAccelerateInterpolator(); - mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator( - mContext, android.R.interpolator.fast_out_slow_in); - mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator( - mContext, android.R.interpolator.linear_out_slow_in); - mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator( - mContext, android.R.interpolator.fast_out_linear_in); - - // Drawables. Needed for views. - mArrow = mContext.getResources() - .getDrawable(R.drawable.ft_avd_tooverflow, mContext.getTheme()); - mArrow.setAutoMirrored(true); - mOverflow = mContext.getResources() - .getDrawable(R.drawable.ft_avd_toarrow, mContext.getTheme()); - mOverflow.setAutoMirrored(true); - mToArrow = (AnimatedVectorDrawable) mContext.getResources() - .getDrawable(R.drawable.ft_avd_toarrow_animation, mContext.getTheme()); - mToArrow.setAutoMirrored(true); - mToOverflow = (AnimatedVectorDrawable) mContext.getResources() - .getDrawable(R.drawable.ft_avd_tooverflow_animation, mContext.getTheme()); - mToOverflow.setAutoMirrored(true); - - // Views - mOverflowButton = createOverflowButton(); - mOverflowButtonSize = measure(mOverflowButton); - mMainPanel = createMainPanel(); - mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing); - mOverflowPanel = createOverflowPanel(); - - // Animation. Need views. - mOverflowAnimationListener = createOverflowAnimationListener(); - mOpenOverflowAnimation = new AnimationSet(true); - mOpenOverflowAnimation.setAnimationListener(mOverflowAnimationListener); - mCloseOverflowAnimation = new AnimationSet(true); - mCloseOverflowAnimation.setAnimationListener(mOverflowAnimationListener); - mShowAnimation = createEnterAnimation(mContentContainer, - new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - updateFloatingToolbarRootContentRect(); - } - }); - mDismissAnimation = createExitAnimation( - mContentContainer, - 150, // startDelay - new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // TODO(b/215497659): should dismiss window after animation - mContentContainer.removeAllViews(); - mSurfaceControlViewHost.release(); - mSurfaceControlViewHost = null; - mSurfacePackage = null; - } - }); - mHideAnimation = createExitAnimation( - mContentContainer, - 0, // startDelay - null); // TODO(b/215497659): should handle hide after animation - mMenuItemButtonOnClickListener = v -> { - Object tag = v.getTag(); - if (!(tag instanceof ToolbarMenuItem)) { - return; - } - mCallbackWrapper.onMenuItemClicked((ToolbarMenuItem) tag); - }; - } - - private void updateFloatingToolbarRootContentRect() { - if (mSurfaceControlViewHost == null) { - return; - } - final FloatingToolbarRoot root = (FloatingToolbarRoot) mSurfaceControlViewHost.getView(); - mContentContainer.getLocationOnScreen(mTempCoords); - int contentLeft = mTempCoords[0]; - int contentTop = mTempCoords[1]; - mTempContentRectForRoot.set(contentLeft, contentTop, - contentLeft + mContentContainer.getWidth(), - contentTop + mContentContainer.getHeight()); - root.setContentRect(mTempContentRectForRoot); - } - - private WidgetInfo createWidgetInfo() { - mTempContentRect.set(mRelativeCoordsForToolbar.x, mRelativeCoordsForToolbar.y, - mRelativeCoordsForToolbar.x + mPopupWidth, - mRelativeCoordsForToolbar.y + mPopupHeight); - return new WidgetInfo(mSelectionToolbarToken, mTempContentRect, getSurfacePackage()); - } - - private SurfaceControlViewHost.SurfacePackage getSurfacePackage() { - if (mSurfaceControlViewHost == null) { - final FloatingToolbarRoot contentHolder = new FloatingToolbarRoot(mContext, - mHostInputToken, mTransferTouchListener); - contentHolder.addView(mContentContainer); - mSurfaceControlViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), - mHostInputToken, "RemoteSelectionToolbar"); - mSurfaceControlViewHost.setView(contentHolder, mPopupWidth, mPopupHeight); - } - if (mSurfacePackage == null) { - mSurfacePackage = mSurfaceControlViewHost.getSurfacePackage(); - } - return mSurfacePackage; - } - - private void layoutMenuItems( - List<ToolbarMenuItem> menuItems, - int suggestedWidth) { - cancelOverflowAnimations(); - clearPanels(); - - menuItems = layoutMainPanelItems(menuItems, getAdjustedToolbarWidth(suggestedWidth)); - if (!menuItems.isEmpty()) { - // Add remaining items to the overflow. - layoutOverflowPanelItems(menuItems); - } - updatePopupSize(); - } - - public void onToolbarShowTimeout() { - mCallbackWrapper.onToolbarShowTimeout(); - } - - /** - * Show the specified selection toolbar. - */ - public void show(ShowInfo showInfo) { - debugLog("show() for " + showInfo); - - mMenuItems = showInfo.getMenuItems(); - mViewPortOnScreen.set(showInfo.getViewPortOnScreen()); - - debugLog("show(): layoutRequired=" + showInfo.isLayoutRequired()); - if (showInfo.isLayoutRequired()) { - layoutMenuItems(mMenuItems, showInfo.getSuggestedWidth()); - } - Rect contentRect = showInfo.getContentRect(); - if (!isShowing()) { - show(contentRect); - } else if (!mPreviousContentRect.equals(contentRect)) { - updateCoordinates(contentRect); - } - mPreviousContentRect.set(contentRect); - } - - private void show(Rect contentRectOnScreen) { - Objects.requireNonNull(contentRectOnScreen); - - mHidden = false; - mDismissed = false; - cancelDismissAndHideAnimations(); - cancelOverflowAnimations(); - refreshCoordinatesAndOverflowDirection(contentRectOnScreen); - preparePopupContent(); - mCallbackWrapper.onShown(createWidgetInfo()); - // TODO(b/215681595): Use Choreographer to coordinate for show between different thread - mShowAnimation.start(); - } - - /** - * Dismiss the specified selection toolbar. - */ - public void dismiss(long floatingToolbarToken) { - debugLog("dismiss for " + floatingToolbarToken); - if (mDismissed) { - return; - } - mHidden = false; - mDismissed = true; - - mHideAnimation.cancel(); - mDismissAnimation.start(); - } - - /** - * Hide the specified selection toolbar. - */ - public void hide(long floatingToolbarToken) { - debugLog("hide for " + floatingToolbarToken); - if (!isShowing()) { - return; - } - - mHidden = true; - mHideAnimation.start(); - } - - public boolean isShowing() { - return !mDismissed && !mHidden; - } - - private void updateCoordinates(Rect contentRectOnScreen) { - Objects.requireNonNull(contentRectOnScreen); - - if (!isShowing()) { - return; - } - cancelOverflowAnimations(); - refreshCoordinatesAndOverflowDirection(contentRectOnScreen); - preparePopupContent(); - WidgetInfo widgetInfo = createWidgetInfo(); - mSurfaceControlViewHost.relayout(mPopupWidth, mPopupHeight); - mCallbackWrapper.onWidgetUpdated(widgetInfo); - } - - private void refreshCoordinatesAndOverflowDirection(Rect contentRectOnScreen) { - // Initialize x ensuring that the toolbar isn't rendered behind the nav bar in - // landscape. - final int x = Math.min( - contentRectOnScreen.centerX() - mPopupWidth / 2, - mViewPortOnScreen.right - mPopupWidth); - - final int y; - - final int availableHeightAboveContent = - contentRectOnScreen.top - mViewPortOnScreen.top; - final int availableHeightBelowContent = - mViewPortOnScreen.bottom - contentRectOnScreen.bottom; - - final int margin = 2 * mMarginVertical; - final int toolbarHeightWithVerticalMargin = mLineHeight + margin; - - if (!hasOverflow()) { - if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin) { - // There is enough space at the top of the content. - y = contentRectOnScreen.top - toolbarHeightWithVerticalMargin; - } else if (availableHeightBelowContent >= toolbarHeightWithVerticalMargin) { - // There is enough space at the bottom of the content. - y = contentRectOnScreen.bottom; - } else if (availableHeightBelowContent >= mLineHeight) { - // Just enough space to fit the toolbar with no vertical margins. - y = contentRectOnScreen.bottom - mMarginVertical; - } else { - // Not enough space. Prefer to position as high as possible. - y = Math.max( - mViewPortOnScreen.top, - contentRectOnScreen.top - toolbarHeightWithVerticalMargin); - } - } else { - // Has an overflow. - final int minimumOverflowHeightWithMargin = - calculateOverflowHeight(MIN_OVERFLOW_SIZE) + margin; - final int availableHeightThroughContentDown = - mViewPortOnScreen.bottom - contentRectOnScreen.top - + toolbarHeightWithVerticalMargin; - final int availableHeightThroughContentUp = - contentRectOnScreen.bottom - mViewPortOnScreen.top - + toolbarHeightWithVerticalMargin; - - if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) { - // There is enough space at the top of the content rect for the overflow. - // Position above and open upwards. - updateOverflowHeight(availableHeightAboveContent - margin); - y = contentRectOnScreen.top - mPopupHeight; - mOpenOverflowUpwards = true; - } else if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin - && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) { - // There is enough space at the top of the content rect for the main panel - // but not the overflow. - // Position above but open downwards. - updateOverflowHeight(availableHeightThroughContentDown - margin); - y = contentRectOnScreen.top - toolbarHeightWithVerticalMargin; - mOpenOverflowUpwards = false; - } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) { - // There is enough space at the bottom of the content rect for the overflow. - // Position below and open downwards. - updateOverflowHeight(availableHeightBelowContent - margin); - y = contentRectOnScreen.bottom; - mOpenOverflowUpwards = false; - } else if (availableHeightBelowContent >= toolbarHeightWithVerticalMargin - && mViewPortOnScreen.height() >= minimumOverflowHeightWithMargin) { - // There is enough space at the bottom of the content rect for the main panel - // but not the overflow. - // Position below but open upwards. - updateOverflowHeight(availableHeightThroughContentUp - margin); - y = contentRectOnScreen.bottom + toolbarHeightWithVerticalMargin - - mPopupHeight; - mOpenOverflowUpwards = true; - } else { - // Not enough space. - // Position at the top of the view port and open downwards. - updateOverflowHeight(mViewPortOnScreen.height() - margin); - y = mViewPortOnScreen.top; - mOpenOverflowUpwards = false; - } - } - mRelativeCoordsForToolbar.set(x, y); - } - - private void cancelDismissAndHideAnimations() { - mDismissAnimation.cancel(); - mHideAnimation.cancel(); - } - - private void cancelOverflowAnimations() { - mContentContainer.clearAnimation(); - mMainPanel.animate().cancel(); - mOverflowPanel.animate().cancel(); - mToArrow.stop(); - mToOverflow.stop(); - } - - private void openOverflow() { - final int targetWidth = mOverflowPanelSize.getWidth(); - final int targetHeight = mOverflowPanelSize.getHeight(); - final int startWidth = mContentContainer.getWidth(); - final int startHeight = mContentContainer.getHeight(); - final float startY = mContentContainer.getY(); - final float left = mContentContainer.getX(); - final float right = left + mContentContainer.getWidth(); - Animation widthAnimation = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth)); - setWidth(mContentContainer, startWidth + deltaWidth); - if (isInRTLMode()) { - mContentContainer.setX(left); - - // Lock the panels in place. - mMainPanel.setX(0); - mOverflowPanel.setX(0); - } else { - mContentContainer.setX(right - mContentContainer.getWidth()); - - // Offset the panels' positions so they look like they're locked in place - // on the screen. - mMainPanel.setX(mContentContainer.getWidth() - startWidth); - mOverflowPanel.setX(mContentContainer.getWidth() - targetWidth); - } - } - }; - Animation heightAnimation = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight)); - setHeight(mContentContainer, startHeight + deltaHeight); - if (mOpenOverflowUpwards) { - mContentContainer.setY( - startY - (mContentContainer.getHeight() - startHeight)); - positionContentYCoordinatesIfOpeningOverflowUpwards(); - } - } - }; - final float overflowButtonStartX = mOverflowButton.getX(); - final float overflowButtonTargetX = - isInRTLMode() ? overflowButtonStartX + targetWidth - mOverflowButton.getWidth() - : overflowButtonStartX - targetWidth + mOverflowButton.getWidth(); - Animation overflowButtonAnimation = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - float overflowButtonX = overflowButtonStartX - + interpolatedTime * (overflowButtonTargetX - overflowButtonStartX); - float deltaContainerWidth = - isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth; - float actualOverflowButtonX = overflowButtonX + deltaContainerWidth; - mOverflowButton.setX(actualOverflowButtonX); - updateFloatingToolbarRootContentRect(); - } - }; - widthAnimation.setInterpolator(mLogAccelerateInterpolator); - widthAnimation.setDuration(getAnimationDuration()); - heightAnimation.setInterpolator(mFastOutSlowInInterpolator); - heightAnimation.setDuration(getAnimationDuration()); - overflowButtonAnimation.setInterpolator(mFastOutSlowInInterpolator); - overflowButtonAnimation.setDuration(getAnimationDuration()); - mOpenOverflowAnimation.getAnimations().clear(); - mOpenOverflowAnimation.addAnimation(widthAnimation); - mOpenOverflowAnimation.addAnimation(heightAnimation); - mOpenOverflowAnimation.addAnimation(overflowButtonAnimation); - mContentContainer.startAnimation(mOpenOverflowAnimation); - mIsOverflowOpen = true; - mMainPanel.animate() - .alpha(0).withLayer() - .setInterpolator(mLinearOutSlowInInterpolator) - .setDuration(250) - .start(); - mOverflowPanel.setAlpha(1); // fadeIn in 0ms. - } - - private void closeOverflow() { - final int targetWidth = mMainPanelSize.getWidth(); - final int startWidth = mContentContainer.getWidth(); - final float left = mContentContainer.getX(); - final float right = left + mContentContainer.getWidth(); - Animation widthAnimation = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth)); - setWidth(mContentContainer, startWidth + deltaWidth); - if (isInRTLMode()) { - mContentContainer.setX(left); - - // Lock the panels in place. - mMainPanel.setX(0); - mOverflowPanel.setX(0); - } else { - mContentContainer.setX(right - mContentContainer.getWidth()); - - // Offset the panels' positions so they look like they're locked in place - // on the screen. - mMainPanel.setX(mContentContainer.getWidth() - targetWidth); - mOverflowPanel.setX(mContentContainer.getWidth() - startWidth); - } - } - }; - final int targetHeight = mMainPanelSize.getHeight(); - final int startHeight = mContentContainer.getHeight(); - final float bottom = mContentContainer.getY() + mContentContainer.getHeight(); - Animation heightAnimation = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight)); - setHeight(mContentContainer, startHeight + deltaHeight); - if (mOpenOverflowUpwards) { - mContentContainer.setY(bottom - mContentContainer.getHeight()); - positionContentYCoordinatesIfOpeningOverflowUpwards(); - } - } - }; - final float overflowButtonStartX = mOverflowButton.getX(); - final float overflowButtonTargetX = - isInRTLMode() ? overflowButtonStartX - startWidth + mOverflowButton.getWidth() - : overflowButtonStartX + startWidth - mOverflowButton.getWidth(); - Animation overflowButtonAnimation = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - float overflowButtonX = overflowButtonStartX - + interpolatedTime * (overflowButtonTargetX - overflowButtonStartX); - float deltaContainerWidth = - isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth; - float actualOverflowButtonX = overflowButtonX + deltaContainerWidth; - mOverflowButton.setX(actualOverflowButtonX); - updateFloatingToolbarRootContentRect(); - } - }; - widthAnimation.setInterpolator(mFastOutSlowInInterpolator); - widthAnimation.setDuration(getAnimationDuration()); - heightAnimation.setInterpolator(mLogAccelerateInterpolator); - heightAnimation.setDuration(getAnimationDuration()); - overflowButtonAnimation.setInterpolator(mFastOutSlowInInterpolator); - overflowButtonAnimation.setDuration(getAnimationDuration()); - mCloseOverflowAnimation.getAnimations().clear(); - mCloseOverflowAnimation.addAnimation(widthAnimation); - mCloseOverflowAnimation.addAnimation(heightAnimation); - mCloseOverflowAnimation.addAnimation(overflowButtonAnimation); - mContentContainer.startAnimation(mCloseOverflowAnimation); - mIsOverflowOpen = false; - mMainPanel.animate() - .alpha(1).withLayer() - .setInterpolator(mFastOutLinearInInterpolator) - .setDuration(100) - .start(); - mOverflowPanel.animate() - .alpha(0).withLayer() - .setInterpolator(mLinearOutSlowInInterpolator) - .setDuration(150) - .start(); - } - - /** - * Defines the position of the floating toolbar popup panels when transition animation has - * stopped. - */ - private void setPanelsStatesAtRestingPosition() { - mOverflowButton.setEnabled(true); - mOverflowPanel.awakenScrollBars(); - - if (mIsOverflowOpen) { - // Set open state. - final Size containerSize = mOverflowPanelSize; - setSize(mContentContainer, containerSize); - mMainPanel.setAlpha(0); - mMainPanel.setVisibility(View.INVISIBLE); - mOverflowPanel.setAlpha(1); - mOverflowPanel.setVisibility(View.VISIBLE); - mOverflowButton.setImageDrawable(mArrow); - mOverflowButton.setContentDescription(mContext.getString( - R.string.floating_toolbar_close_overflow_description)); - - // Update x-coordinates depending on RTL state. - if (isInRTLMode()) { - mContentContainer.setX(mMarginHorizontal); // align left - mMainPanel.setX(0); // align left - mOverflowButton.setX(// align right - containerSize.getWidth() - mOverflowButtonSize.getWidth()); - mOverflowPanel.setX(0); // align left - } else { - mContentContainer.setX(// align right - mPopupWidth - containerSize.getWidth() - mMarginHorizontal); - mMainPanel.setX(-mContentContainer.getX()); // align right - mOverflowButton.setX(0); // align left - mOverflowPanel.setX(0); // align left - } - - // Update y-coordinates depending on overflow's open direction. - if (mOpenOverflowUpwards) { - mContentContainer.setY(mMarginVertical); // align top - mMainPanel.setY(// align bottom - containerSize.getHeight() - mContentContainer.getHeight()); - mOverflowButton.setY(// align bottom - containerSize.getHeight() - mOverflowButtonSize.getHeight()); - mOverflowPanel.setY(0); // align top - } else { - // opens downwards. - mContentContainer.setY(mMarginVertical); // align top - mMainPanel.setY(0); // align top - mOverflowButton.setY(0); // align top - mOverflowPanel.setY(mOverflowButtonSize.getHeight()); // align bottom - } - } else { - // Overflow not open. Set closed state. - final Size containerSize = mMainPanelSize; - setSize(mContentContainer, containerSize); - mMainPanel.setAlpha(1); - mMainPanel.setVisibility(View.VISIBLE); - mOverflowPanel.setAlpha(0); - mOverflowPanel.setVisibility(View.INVISIBLE); - mOverflowButton.setImageDrawable(mOverflow); - mOverflowButton.setContentDescription(mContext.getString( - R.string.floating_toolbar_open_overflow_description)); - - if (hasOverflow()) { - // Update x-coordinates depending on RTL state. - if (isInRTLMode()) { - mContentContainer.setX(mMarginHorizontal); // align left - mMainPanel.setX(0); // align left - mOverflowButton.setX(0); // align left - mOverflowPanel.setX(0); // align left - } else { - mContentContainer.setX(// align right - mPopupWidth - containerSize.getWidth() - mMarginHorizontal); - mMainPanel.setX(0); // align left - mOverflowButton.setX(// align right - containerSize.getWidth() - mOverflowButtonSize.getWidth()); - mOverflowPanel.setX(// align right - containerSize.getWidth() - mOverflowPanelSize.getWidth()); - } - - // Update y-coordinates depending on overflow's open direction. - if (mOpenOverflowUpwards) { - mContentContainer.setY(// align bottom - mMarginVertical + mOverflowPanelSize.getHeight() - - containerSize.getHeight()); - mMainPanel.setY(0); // align top - mOverflowButton.setY(0); // align top - mOverflowPanel.setY(// align bottom - containerSize.getHeight() - mOverflowPanelSize.getHeight()); - } else { - // opens downwards. - mContentContainer.setY(mMarginVertical); // align top - mMainPanel.setY(0); // align top - mOverflowButton.setY(0); // align top - mOverflowPanel.setY(mOverflowButtonSize.getHeight()); // align bottom - } - } else { - // No overflow. - mContentContainer.setX(mMarginHorizontal); // align left - mContentContainer.setY(mMarginVertical); // align top - mMainPanel.setX(0); // align left - mMainPanel.setY(0); // align top - } - } - } - - private void updateOverflowHeight(int suggestedHeight) { - if (hasOverflow()) { - final int maxItemSize = - (suggestedHeight - mOverflowButtonSize.getHeight()) / mLineHeight; - final int newHeight = calculateOverflowHeight(maxItemSize); - if (mOverflowPanelSize.getHeight() != newHeight) { - mOverflowPanelSize = new Size(mOverflowPanelSize.getWidth(), newHeight); - } - setSize(mOverflowPanel, mOverflowPanelSize); - if (mIsOverflowOpen) { - setSize(mContentContainer, mOverflowPanelSize); - if (mOpenOverflowUpwards) { - final int deltaHeight = mOverflowPanelSize.getHeight() - newHeight; - mContentContainer.setY(mContentContainer.getY() + deltaHeight); - mOverflowButton.setY(mOverflowButton.getY() - deltaHeight); - } - } else { - setSize(mContentContainer, mMainPanelSize); - } - updatePopupSize(); - } - } - - private void updatePopupSize() { - int width = 0; - int height = 0; - if (mMainPanelSize != null) { - width = Math.max(width, mMainPanelSize.getWidth()); - height = Math.max(height, mMainPanelSize.getHeight()); - } - if (mOverflowPanelSize != null) { - width = Math.max(width, mOverflowPanelSize.getWidth()); - height = Math.max(height, mOverflowPanelSize.getHeight()); - } - - mPopupWidth = width + mMarginHorizontal * 2; - mPopupHeight = height + mMarginVertical * 2; - maybeComputeTransitionDurationScale(); - } - - private int getAdjustedToolbarWidth(int suggestedWidth) { - int width = suggestedWidth; - int maximumWidth = mViewPortOnScreen.width() - 2 * mContext.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin); - if (width <= 0) { - width = mContext.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width); - } - return Math.min(width, maximumWidth); - } - - private boolean isInRTLMode() { - return mContext.getApplicationInfo().hasRtlSupport() - && mContext.getResources().getConfiguration().getLayoutDirection() - == View.LAYOUT_DIRECTION_RTL; - } - - private boolean hasOverflow() { - return mOverflowPanelSize != null; - } - - /** - * Fits as many menu items in the main panel and returns a list of the menu items that - * were not fit in. - * - * @return The menu items that are not included in this main panel. - */ - private List<ToolbarMenuItem> layoutMainPanelItems(List<ToolbarMenuItem> menuItems, - int toolbarWidth) { - final LinkedList<ToolbarMenuItem> remainingMenuItems = new LinkedList<>(); - // add the overflow menu items to the end of the remainingMenuItems list. - final LinkedList<ToolbarMenuItem> overflowMenuItems = new LinkedList(); - for (ToolbarMenuItem menuItem : menuItems) { - if (menuItem.getItemId() != android.R.id.textAssist - && menuItem.getPriority() == ToolbarMenuItem.PRIORITY_OVERFLOW) { - overflowMenuItems.add(menuItem); - } else { - remainingMenuItems.add(menuItem); - } - } - remainingMenuItems.addAll(overflowMenuItems); - - mMainPanel.removeAllViews(); - mMainPanel.setPaddingRelative(0, 0, 0, 0); - - int availableWidth = toolbarWidth; - boolean isFirstItem = true; - while (!remainingMenuItems.isEmpty()) { - ToolbarMenuItem menuItem = remainingMenuItems.peek(); - // if this is the first item, regardless of requiresOverflow(), it should be - // displayed on the main panel. Otherwise all items including this one will be - // overflow items, and should be displayed in overflow panel. - if (!isFirstItem && menuItem.getPriority() == ToolbarMenuItem.PRIORITY_OVERFLOW) { - break; - } - final boolean showIcon = isFirstItem && menuItem.getItemId() == R.id.textAssist; - final View menuItemButton = createMenuItemButton( - mContext, menuItem, mIconTextSpacing, showIcon); - if (!showIcon && menuItemButton instanceof LinearLayout) { - ((LinearLayout) menuItemButton).setGravity(Gravity.CENTER); - } - // Adding additional start padding for the first button to even out button spacing. - if (isFirstItem) { - menuItemButton.setPaddingRelative( - (int) (1.5 * menuItemButton.getPaddingStart()), - menuItemButton.getPaddingTop(), - menuItemButton.getPaddingEnd(), - menuItemButton.getPaddingBottom()); - } - // Adding additional end padding for the last button to even out button spacing. - boolean isLastItem = remainingMenuItems.size() == 1; - if (isLastItem) { - menuItemButton.setPaddingRelative( - menuItemButton.getPaddingStart(), - menuItemButton.getPaddingTop(), - (int) (1.5 * menuItemButton.getPaddingEnd()), - menuItemButton.getPaddingBottom()); - } - menuItemButton.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - final int menuItemButtonWidth = Math.min( - menuItemButton.getMeasuredWidth(), toolbarWidth); - // Check if we can fit an item while reserving space for the overflowButton. - final boolean canFitWithOverflow = - menuItemButtonWidth <= availableWidth - mOverflowButtonSize.getWidth(); - final boolean canFitNoOverflow = - isLastItem && menuItemButtonWidth <= availableWidth; - if (canFitWithOverflow || canFitNoOverflow) { - menuItemButton.setTag(menuItem); - menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener); - // Set tooltips for main panel items, but not overflow items (b/35726766). - menuItemButton.setTooltipText(menuItem.getTooltipText()); - mMainPanel.addView(menuItemButton); - final ViewGroup.LayoutParams params = menuItemButton.getLayoutParams(); - params.width = menuItemButtonWidth; - menuItemButton.setLayoutParams(params); - availableWidth -= menuItemButtonWidth; - remainingMenuItems.pop(); - } else { - break; - } - isFirstItem = false; - } - if (!remainingMenuItems.isEmpty()) { - // Reserve space for overflowButton. - mMainPanel.setPaddingRelative(0, 0, mOverflowButtonSize.getWidth(), 0); - } - mMainPanelSize = measure(mMainPanel); - - return remainingMenuItems; - } - - private void layoutOverflowPanelItems(List<ToolbarMenuItem> menuItems) { - ArrayAdapter<ToolbarMenuItem> overflowPanelAdapter = - (ArrayAdapter<ToolbarMenuItem>) mOverflowPanel.getAdapter(); - overflowPanelAdapter.clear(); - final int size = menuItems.size(); - for (int i = 0; i < size; i++) { - overflowPanelAdapter.add(menuItems.get(i)); - } - mOverflowPanel.setAdapter(overflowPanelAdapter); - if (mOpenOverflowUpwards) { - mOverflowPanel.setY(0); - } else { - mOverflowPanel.setY(mOverflowButtonSize.getHeight()); - } - int width = Math.max(getOverflowWidth(), mOverflowButtonSize.getWidth()); - int height = calculateOverflowHeight(MAX_OVERFLOW_SIZE); - mOverflowPanelSize = new Size(width, height); - setSize(mOverflowPanel, mOverflowPanelSize); - } - - /** - * Resets the content container and appropriately position it's panels. - */ - private void preparePopupContent() { - mContentContainer.removeAllViews(); - // Add views in the specified order so they stack up as expected. - // Order: overflowPanel, mainPanel, overflowButton. - if (hasOverflow()) { - mContentContainer.addView(mOverflowPanel); - } - mContentContainer.addView(mMainPanel); - if (hasOverflow()) { - mContentContainer.addView(mOverflowButton); - } - setPanelsStatesAtRestingPosition(); - - // The positioning of contents in RTL is wrong when the view is first rendered. - // Hide the view and post a runnable to recalculate positions and render the view. - // TODO: Investigate why this happens and fix. - if (isInRTLMode()) { - mContentContainer.setAlpha(0); - mContentContainer.post(mPreparePopupContentRTLHelper); - } - } - - /** - * Clears out the panels and their container. Resets their calculated sizes. - */ - private void clearPanels() { - mIsOverflowOpen = false; - mMainPanelSize = null; - mMainPanel.removeAllViews(); - mOverflowPanelSize = null; - ArrayAdapter<ToolbarMenuItem> overflowPanelAdapter = - (ArrayAdapter<ToolbarMenuItem>) mOverflowPanel.getAdapter(); - overflowPanelAdapter.clear(); - mOverflowPanel.setAdapter(overflowPanelAdapter); - mContentContainer.removeAllViews(); - } - - private void positionContentYCoordinatesIfOpeningOverflowUpwards() { - if (mOpenOverflowUpwards) { - mMainPanel.setY(mContentContainer.getHeight() - mMainPanelSize.getHeight()); - mOverflowButton.setY(mContentContainer.getHeight() - mOverflowButton.getHeight()); - mOverflowPanel.setY(mContentContainer.getHeight() - mOverflowPanelSize.getHeight()); - } - } - - private int getOverflowWidth() { - int overflowWidth = 0; - final int count = mOverflowPanel.getAdapter().getCount(); - for (int i = 0; i < count; i++) { - ToolbarMenuItem menuItem = (ToolbarMenuItem) mOverflowPanel.getAdapter().getItem(i); - overflowWidth = - Math.max(mOverflowPanelViewHelper.calculateWidth(menuItem), overflowWidth); - } - return overflowWidth; - } - - private int calculateOverflowHeight(int maxItemSize) { - // Maximum of 4 items, minimum of 2 if the overflow has to scroll. - int actualSize = Math.min( - MAX_OVERFLOW_SIZE, - Math.min( - Math.max(MIN_OVERFLOW_SIZE, maxItemSize), - mOverflowPanel.getCount())); - int extension = 0; - if (actualSize < mOverflowPanel.getCount()) { - // The overflow will require scrolling to get to all the items. - // Extend the height so that part of the hidden items is displayed. - extension = (int) (mLineHeight * 0.5f); - } - return actualSize * mLineHeight - + mOverflowButtonSize.getHeight() - + extension; - } - - /** - * NOTE: Use only in android.view.animation.* animations. Do not use in android.animation.* - * animations. See comment about this in the code. - */ - private int getAnimationDuration() { - if (mTransitionDurationScale < 150) { - // For smaller transition, decrease the time. - return 200; - } else if (mTransitionDurationScale > 300) { - // For bigger transition, increase the time. - return 300; - } - - // Scale the animation duration with getDurationScale(). This allows - // android.view.animation.* animations to scale just like android.animation.* animations - // when animator duration scale is adjusted in "Developer Options". - // For this reason, do not use this method for android.animation.* animations. - return (int) (250 * ValueAnimator.getDurationScale()); - } - - private void maybeComputeTransitionDurationScale() { - if (mMainPanelSize != null && mOverflowPanelSize != null) { - int w = mMainPanelSize.getWidth() - mOverflowPanelSize.getWidth(); - int h = mOverflowPanelSize.getHeight() - mMainPanelSize.getHeight(); - mTransitionDurationScale = (int) (Math.sqrt(w * w + h * h) - / mContentContainer.getContext().getResources().getDisplayMetrics().density); - } - } - - private ViewGroup createMainPanel() { - return new LinearLayout(mContext) { - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - if (isOverflowAnimating()) { - // Update widthMeasureSpec to make sure that this view is not clipped - // as we offset its coordinates with respect to its parent. - widthMeasureSpec = MeasureSpec.makeMeasureSpec( - mMainPanelSize.getWidth(), - MeasureSpec.EXACTLY); - } - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - // Intercept the touch event while the overflow is animating. - return isOverflowAnimating(); - } - }; - } - - private ImageButton createOverflowButton() { - final ImageButton overflowButton = (ImageButton) LayoutInflater.from(mContext) - .inflate(R.layout.floating_popup_overflow_button, null); - overflowButton.setImageDrawable(mOverflow); - overflowButton.setOnClickListener(v -> { - if (isShowing()) { - preparePopupContent(); - WidgetInfo widgetInfo = createWidgetInfo(); - mSurfaceControlViewHost.relayout(mPopupWidth, mPopupHeight); - mCallbackWrapper.onWidgetUpdated(widgetInfo); - } - if (mIsOverflowOpen) { - overflowButton.setImageDrawable(mToOverflow); - mToOverflow.start(); - closeOverflow(); - } else { - overflowButton.setImageDrawable(mToArrow); - mToArrow.start(); - openOverflow(); - } - }); - return overflowButton; - } - - private OverflowPanel createOverflowPanel() { - final OverflowPanel overflowPanel = new OverflowPanel(this); - overflowPanel.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - overflowPanel.setDivider(null); - overflowPanel.setDividerHeight(0); - - final ArrayAdapter adapter = - new ArrayAdapter<ToolbarMenuItem>(mContext, 0) { - @Override - public View getView(int position, View convertView, ViewGroup parent) { - return mOverflowPanelViewHelper.getView( - getItem(position), mOverflowPanelSize.getWidth(), convertView); - } - }; - overflowPanel.setAdapter(adapter); - overflowPanel.setOnItemClickListener((parent, view, position, id) -> { - ToolbarMenuItem menuItem = - (ToolbarMenuItem) overflowPanel.getAdapter().getItem(position); - mCallbackWrapper.onMenuItemClicked(menuItem); - }); - return overflowPanel; - } - - private boolean isOverflowAnimating() { - final boolean overflowOpening = mOpenOverflowAnimation.hasStarted() - && !mOpenOverflowAnimation.hasEnded(); - final boolean overflowClosing = mCloseOverflowAnimation.hasStarted() - && !mCloseOverflowAnimation.hasEnded(); - return overflowOpening || overflowClosing; - } - - private Animation.AnimationListener createOverflowAnimationListener() { - return new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - // Disable the overflow button while it's animating. - // It will be re-enabled when the animation stops. - mOverflowButton.setEnabled(false); - // Ensure both panels have visibility turned on when the overflow animation - // starts. - mMainPanel.setVisibility(View.VISIBLE); - mOverflowPanel.setVisibility(View.VISIBLE); - } - - @Override - public void onAnimationEnd(Animation animation) { - // Posting this because it seems like this is called before the animation - // actually ends. - mContentContainer.post(() -> { - setPanelsStatesAtRestingPosition(); - }); - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - }; - } - - private static Size measure(View view) { - Preconditions.checkState(view.getParent() == null); - view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - return new Size(view.getMeasuredWidth(), view.getMeasuredHeight()); - } - - private static void setSize(View view, int width, int height) { - view.setMinimumWidth(width); - view.setMinimumHeight(height); - ViewGroup.LayoutParams params = view.getLayoutParams(); - params = (params == null) ? new ViewGroup.LayoutParams(0, 0) : params; - params.width = width; - params.height = height; - view.setLayoutParams(params); - } - - private static void setSize(View view, Size size) { - setSize(view, size.getWidth(), size.getHeight()); - } - - private static void setWidth(View view, int width) { - ViewGroup.LayoutParams params = view.getLayoutParams(); - setSize(view, width, params.height); - } - - private static void setHeight(View view, int height) { - ViewGroup.LayoutParams params = view.getLayoutParams(); - setSize(view, params.width, height); - } - - /** - * A custom ListView for the overflow panel. - */ - private static final class OverflowPanel extends ListView { - - private final RemoteSelectionToolbar mPopup; - - OverflowPanel(RemoteSelectionToolbar popup) { - super(Objects.requireNonNull(popup).mContext); - this.mPopup = popup; - setScrollBarDefaultDelayBeforeFade(ViewConfiguration.getScrollDefaultDelay() * 3); - setScrollIndicators(View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Update heightMeasureSpec to make sure that this view is not clipped - // as we offset it's coordinates with respect to its parent. - int height = mPopup.mOverflowPanelSize.getHeight() - - mPopup.mOverflowButtonSize.getHeight(); - heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - if (mPopup.isOverflowAnimating()) { - // Eat the touch event. - return true; - } - return super.dispatchTouchEvent(ev); - } - - @Override - protected boolean awakenScrollBars() { - return super.awakenScrollBars(); - } - } - - /** - * A custom interpolator used for various floating toolbar animations. - */ - private static final class LogAccelerateInterpolator implements Interpolator { - - private static final int BASE = 100; - private static final float LOGS_SCALE = 1f / computeLog(1, BASE); - - private static float computeLog(float t, int base) { - return (float) (1 - Math.pow(base, -t)); - } - - @Override - public float getInterpolation(float t) { - return 1 - computeLog(1 - t, BASE) * LOGS_SCALE; - } - } - - /** - * A helper for generating views for the overflow panel. - */ - private static final class OverflowPanelViewHelper { - private final Context mContext; - private final View mCalculator; - private final int mIconTextSpacing; - private final int mSidePadding; - - OverflowPanelViewHelper(Context context, int iconTextSpacing) { - mContext = Objects.requireNonNull(context); - mIconTextSpacing = iconTextSpacing; - mSidePadding = context.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_overflow_side_padding); - mCalculator = createMenuButton(null); - } - - public View getView(ToolbarMenuItem menuItem, int minimumWidth, View convertView) { - Objects.requireNonNull(menuItem); - if (convertView != null) { - updateMenuItemButton( - convertView, menuItem, mIconTextSpacing, shouldShowIcon(menuItem)); - } else { - convertView = createMenuButton(menuItem); - } - convertView.setMinimumWidth(minimumWidth); - return convertView; - } - - public int calculateWidth(ToolbarMenuItem menuItem) { - updateMenuItemButton( - mCalculator, menuItem, mIconTextSpacing, shouldShowIcon(menuItem)); - mCalculator.measure( - View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - return mCalculator.getMeasuredWidth(); - } - - private View createMenuButton(ToolbarMenuItem menuItem) { - View button = createMenuItemButton( - mContext, menuItem, mIconTextSpacing, shouldShowIcon(menuItem)); - button.setPadding(mSidePadding, 0, mSidePadding, 0); - return button; - } - - private boolean shouldShowIcon(ToolbarMenuItem menuItem) { - if (menuItem != null) { - return menuItem.getGroupId() == android.R.id.textAssist; - } - return false; - } - } - - /** - * Creates and returns a menu button for the specified menu item. - */ - private static View createMenuItemButton( - Context context, ToolbarMenuItem menuItem, int iconTextSpacing, boolean showIcon) { - final View menuItemButton = LayoutInflater.from(context) - .inflate(R.layout.floating_popup_menu_button, null); - if (menuItem != null) { - updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing, showIcon); - } - return menuItemButton; - } - - /** - * Updates the specified menu item button with the specified menu item data. - */ - private static void updateMenuItemButton(View menuItemButton, ToolbarMenuItem menuItem, - int iconTextSpacing, boolean showIcon) { - final TextView buttonText = menuItemButton.findViewById( - R.id.floating_toolbar_menu_item_text); - buttonText.setEllipsize(null); - if (TextUtils.isEmpty(menuItem.getTitle())) { - buttonText.setVisibility(View.GONE); - } else { - buttonText.setVisibility(View.VISIBLE); - buttonText.setText(menuItem.getTitle()); - } - final ImageView buttonIcon = menuItemButton.findViewById( - R.id.floating_toolbar_menu_item_image); - if (menuItem.getIcon() == null || !showIcon) { - buttonIcon.setVisibility(View.GONE); - buttonText.setPaddingRelative(0, 0, 0, 0); - } else { - buttonIcon.setVisibility(View.VISIBLE); - buttonIcon.setImageDrawable( - menuItem.getIcon().loadDrawable(menuItemButton.getContext())); - buttonText.setPaddingRelative(iconTextSpacing, 0, 0, 0); - } - final CharSequence contentDescription = menuItem.getContentDescription(); - if (TextUtils.isEmpty(contentDescription)) { - menuItemButton.setContentDescription(menuItem.getTitle()); - } else { - menuItemButton.setContentDescription(contentDescription); - } - } - - private static ViewGroup createContentContainer(Context context) { - ViewGroup contentContainer = (ViewGroup) LayoutInflater.from(context) - .inflate(R.layout.floating_popup_container, null); - contentContainer.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - contentContainer.setTag(FloatingToolbar.FLOATING_TOOLBAR_TAG); - contentContainer.setClipToOutline(true); - return contentContainer; - } - - /** - * Creates an "appear" animation for the specified view. - * - * @param view The view to animate - */ - private static AnimatorSet createEnterAnimation(View view, Animator.AnimatorListener listener) { - AnimatorSet animation = new AnimatorSet(); - animation.playTogether( - ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(150)); - animation.addListener(listener); - return animation; - } - - /** - * Creates a "disappear" animation for the specified view. - * - * @param view The view to animate - * @param startDelay The start delay of the animation - * @param listener The animation listener - */ - private static AnimatorSet createExitAnimation( - View view, int startDelay, Animator.AnimatorListener listener) { - AnimatorSet animation = new AnimatorSet(); - animation.playTogether( - ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(100)); - animation.setStartDelay(startDelay); - if (listener != null) { - animation.addListener(listener); - } - return animation; - } - - /** - * Returns a re-themed context with controlled look and feel for views. - */ - private static Context applyDefaultTheme(Context originalContext, boolean isLightTheme) { - int themeId = - isLightTheme ? R.style.Theme_DeviceDefault_Light : R.style.Theme_DeviceDefault; - return new ContextThemeWrapper(originalContext, themeId); - } - - private static void debugLog(String message) { - if (Log.isLoggable(FloatingToolbar.FLOATING_TOOLBAR_TAG, Log.DEBUG)) { - Log.v(TAG, message); - } - } - - void dump(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("toolbar token: "); pw.println(mSelectionToolbarToken); - pw.print(prefix); pw.print("dismissed: "); pw.println(mDismissed); - pw.print(prefix); pw.print("hidden: "); pw.println(mHidden); - pw.print(prefix); pw.print("popup width: "); pw.println(mPopupWidth); - pw.print(prefix); pw.print("popup height: "); pw.println(mPopupHeight); - pw.print(prefix); pw.print("relative coords: "); pw.println(mRelativeCoordsForToolbar); - pw.print(prefix); pw.print("main panel size: "); pw.println(mMainPanelSize); - boolean hasOverflow = hasOverflow(); - pw.print(prefix); pw.print("has overflow: "); pw.println(hasOverflow); - if (hasOverflow) { - pw.print(prefix); pw.print("overflow open: "); pw.println(mIsOverflowOpen); - pw.print(prefix); pw.print("overflow size: "); pw.println(mOverflowPanelSize); - } - if (mSurfaceControlViewHost != null) { - FloatingToolbarRoot root = (FloatingToolbarRoot) mSurfaceControlViewHost.getView(); - root.dump(prefix, pw); - } - if (mMenuItems != null) { - int menuItemSize = mMenuItems.size(); - pw.print(prefix); pw.print("number menu items: "); pw.println(menuItemSize); - for (int i = 0; i < menuItemSize; i++) { - pw.print(prefix); pw.print("#"); pw.println(i); - pw.print(prefix + " "); pw.println(mMenuItems.get(i)); - } - } - } -} diff --git a/core/java/android/service/selectiontoolbar/SelectionToolbarRenderCallback.java b/core/java/android/service/selectiontoolbar/SelectionToolbarRenderCallback.java deleted file mode 100644 index a10b6a8ac8cb..000000000000 --- a/core/java/android/service/selectiontoolbar/SelectionToolbarRenderCallback.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 android.view.selectiontoolbar.ToolbarMenuItem; -import android.view.selectiontoolbar.WidgetInfo; - -/** - * The callback that the render service uses to communicate with the host of the selection toolbar - * container. - * - * @hide - */ -public interface SelectionToolbarRenderCallback { - /** - * The selection toolbar is shown. - */ - void onShown(WidgetInfo widgetInfo); - /** - * The selection toolbar has changed. - */ - void onWidgetUpdated(WidgetInfo info); - /** - * The menu item on the selection toolbar has been clicked. - */ - void onMenuItemClicked(ToolbarMenuItem item); - /** - * The toolbar doesn't be dismissed after showing on a given timeout. - */ - void onToolbarShowTimeout(); - /** - * The error occurred when operating on the selection toolbar. - */ - void onError(int errorCode); -} diff --git a/core/java/android/service/selectiontoolbar/SelectionToolbarRenderService.java b/core/java/android/service/selectiontoolbar/SelectionToolbarRenderService.java deleted file mode 100644 index f33feaec6dde..000000000000 --- a/core/java/android/service/selectiontoolbar/SelectionToolbarRenderService.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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 com.android.internal.util.function.pooled.PooledLambda.obtainMessage; - -import android.annotation.CallSuper; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.Service; -import android.content.Intent; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteException; -import android.util.Log; -import android.util.Pair; -import android.util.SparseArray; -import android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.ShowInfo; -import android.view.selectiontoolbar.ToolbarMenuItem; -import android.view.selectiontoolbar.WidgetInfo; - -/** - * Service for rendering selection toolbar. - * - * @hide - */ -public abstract class SelectionToolbarRenderService extends Service { - - private static final String TAG = "SelectionToolbarRenderService"; - - // TODO(b/215497659): read from DeviceConfig - // The timeout to clean the cache if the client forgot to call dismiss() - private static final int CACHE_CLEAN_AFTER_SHOW_TIMEOUT_IN_MS = 10 * 60 * 1000; // 10 minutes - - /** - * The {@link Intent} that must be declared as handled by the service. - * - * <p>To be supported, the service must also require the - * {@link android.Manifest.permission#BIND_SELECTION_TOOLBAR_RENDER_SERVICE} permission so - * that other applications can not abuse it. - */ - public static final String SERVICE_INTERFACE = - "android.service.selectiontoolbar.SelectionToolbarRenderService"; - - private Handler mHandler; - private ISelectionToolbarRenderServiceCallback mServiceCallback; - - private final SparseArray<Pair<RemoteCallbackWrapper, CleanCacheRunnable>> mCache = - new SparseArray<>(); - - /** - * Binder to receive calls from system server. - */ - private final ISelectionToolbarRenderService mInterface = - new ISelectionToolbarRenderService.Stub() { - - @Override - public void onShow(int callingUid, ShowInfo showInfo, ISelectionToolbarCallback callback) { - if (mCache.indexOfKey(callingUid) < 0) { - mCache.put(callingUid, new Pair<>(new RemoteCallbackWrapper(callback), - new CleanCacheRunnable(callingUid))); - } - Pair<RemoteCallbackWrapper, CleanCacheRunnable> toolbarPair = mCache.get(callingUid); - CleanCacheRunnable cleanRunnable = toolbarPair.second; - mHandler.removeCallbacks(cleanRunnable); - mHandler.sendMessage(obtainMessage(SelectionToolbarRenderService::onShow, - SelectionToolbarRenderService.this, callingUid, showInfo, - toolbarPair.first)); - mHandler.postDelayed(cleanRunnable, CACHE_CLEAN_AFTER_SHOW_TIMEOUT_IN_MS); - } - - @Override - public void onHide(long widgetToken) { - mHandler.sendMessage(obtainMessage(SelectionToolbarRenderService::onHide, - SelectionToolbarRenderService.this, widgetToken)); - } - - @Override - public void onDismiss(int callingUid, long widgetToken) { - mHandler.sendMessage(obtainMessage(SelectionToolbarRenderService::onDismiss, - SelectionToolbarRenderService.this, widgetToken)); - Pair<RemoteCallbackWrapper, CleanCacheRunnable> toolbarPair = mCache.get(callingUid); - if (toolbarPair != null) { - mHandler.removeCallbacks(toolbarPair.second); - mCache.remove(callingUid); - } - } - - @Override - public void onConnected(IBinder callback) { - mHandler.sendMessage(obtainMessage(SelectionToolbarRenderService::handleOnConnected, - SelectionToolbarRenderService.this, callback)); - } - }; - - @CallSuper - @Override - public void onCreate() { - super.onCreate(); - mHandler = new Handler(Looper.getMainLooper(), null, true); - } - - @Override - @Nullable - public final IBinder onBind(@NonNull Intent intent) { - if (SERVICE_INTERFACE.equals(intent.getAction())) { - return mInterface.asBinder(); - } - Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent); - return null; - } - - private void handleOnConnected(@NonNull IBinder callback) { - mServiceCallback = ISelectionToolbarRenderServiceCallback.Stub.asInterface(callback); - } - - protected void transferTouch(@NonNull IBinder source, @NonNull IBinder target) { - final ISelectionToolbarRenderServiceCallback callback = mServiceCallback; - if (callback == null) { - Log.e(TAG, "transferTouch(): no server callback"); - return; - } - try { - callback.transferTouch(source, target); - } catch (RemoteException e) { - // no-op - } - } - - /** - * Called when showing the selection toolbar. - */ - public abstract void onShow(int callingUid, ShowInfo showInfo, - RemoteCallbackWrapper callbackWrapper); - - /** - * Called when hiding the selection toolbar. - */ - public abstract void onHide(long widgetToken); - - - /** - * Called when dismissing the selection toolbar. - */ - public abstract void onDismiss(long widgetToken); - - /** - * Called when showing the selection toolbar for a specific timeout. This avoids the client - * forgot to call dismiss to clean the state. - */ - public void onToolbarShowTimeout(int callingUid) { - // no-op - } - - /** - * Callback to notify the client toolbar events. - */ - public static final class RemoteCallbackWrapper implements SelectionToolbarRenderCallback { - - private final ISelectionToolbarCallback mRemoteCallback; - - RemoteCallbackWrapper(ISelectionToolbarCallback remoteCallback) { - // TODO(b/215497659): handle if the binder dies. - mRemoteCallback = remoteCallback; - } - - @Override - public void onShown(WidgetInfo widgetInfo) { - try { - mRemoteCallback.onShown(widgetInfo); - } catch (RemoteException e) { - // no-op - } - } - - @Override - public void onToolbarShowTimeout() { - try { - mRemoteCallback.onToolbarShowTimeout(); - } catch (RemoteException e) { - // no-op - } - } - - @Override - public void onWidgetUpdated(WidgetInfo widgetInfo) { - try { - mRemoteCallback.onWidgetUpdated(widgetInfo); - } catch (RemoteException e) { - // no-op - } - } - - @Override - public void onMenuItemClicked(ToolbarMenuItem item) { - try { - mRemoteCallback.onMenuItemClicked(item); - } catch (RemoteException e) { - // no-op - } - } - - @Override - public void onError(int errorCode) { - try { - mRemoteCallback.onError(errorCode); - } catch (RemoteException e) { - // no-op - } - } - } - - private class CleanCacheRunnable implements Runnable { - - int mCleanUid; - - CleanCacheRunnable(int cleanUid) { - mCleanUid = cleanUid; - } - - @Override - public void run() { - Pair<RemoteCallbackWrapper, CleanCacheRunnable> toolbarPair = mCache.get(mCleanUid); - if (toolbarPair != null) { - Log.w(TAG, "CleanCacheRunnable: remove " + mCleanUid + " from cache."); - mCache.remove(mCleanUid); - onToolbarShowTimeout(mCleanUid); - } - } - } - - /** - * A listener to notify the service to the transfer touch focus. - */ - public interface TransferTouchListener { - /** - * Notify the service to transfer the touch focus. - */ - void onTransferTouch(IBinder source, IBinder target); - } -} diff --git a/core/java/android/view/selectiontoolbar/ISelectionToolbarCallback.aidl b/core/java/android/view/selectiontoolbar/ISelectionToolbarCallback.aidl deleted file mode 100644 index aaeb12012f68..000000000000 --- a/core/java/android/view/selectiontoolbar/ISelectionToolbarCallback.aidl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -import android.view.selectiontoolbar.ToolbarMenuItem; -import android.view.selectiontoolbar.WidgetInfo; - -/** - * Binder interface to notify the selection toolbar events from one process to the other. - * @hide - */ -oneway interface ISelectionToolbarCallback { - void onShown(in WidgetInfo info); - void onWidgetUpdated(in WidgetInfo info); - void onToolbarShowTimeout(); - void onMenuItemClicked(in ToolbarMenuItem item); - void onError(int errorCode); -} diff --git a/core/java/android/view/selectiontoolbar/ISelectionToolbarManager.aidl b/core/java/android/view/selectiontoolbar/ISelectionToolbarManager.aidl deleted file mode 100644 index 4a647ada1d6c..000000000000 --- a/core/java/android/view/selectiontoolbar/ISelectionToolbarManager.aidl +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -import android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.ShowInfo; - -/** - * Mediator between apps and selection toolbar service implementation. - * - * @hide - */ -oneway interface ISelectionToolbarManager { - void showToolbar(in ShowInfo showInfo, in ISelectionToolbarCallback callback, int userId); - void hideToolbar(long widgetToken, int userId); - void dismissToolbar(long widgetToken, int userId); -}
\ No newline at end of file diff --git a/core/java/android/view/selectiontoolbar/OWNERS b/core/java/android/view/selectiontoolbar/OWNERS deleted file mode 100644 index 5500b92868dd..000000000000 --- a/core/java/android/view/selectiontoolbar/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# Bug component: 709498 - -augale@google.com -joannechung@google.com -licha@google.com -lpeter@google.com -svetoslavganov@google.com -toki@google.com -tonymak@google.com -tymtsai@google.com
\ No newline at end of file diff --git a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java deleted file mode 100644 index 6de031628768..000000000000 --- a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -import android.annotation.NonNull; -import android.annotation.SystemService; -import android.content.Context; -import android.os.RemoteException; -import android.provider.DeviceConfig; - -import java.util.Objects; - -/** - * The {@link SelectionToolbarManager} class provides ways for apps to control the - * selection toolbar. - * - * @hide - */ -@SystemService(Context.SELECTION_TOOLBAR_SERVICE) -public final class SelectionToolbarManager { - - private static final String TAG = "SelectionToolbar"; - - /** - * The tag which uses for enabling debug log dump. To enable it, we can use command "adb shell - * setprop log.tag.UiTranslation DEBUG". - */ - public static final String LOG_TAG = "SelectionToolbar"; - - /** - * Whether system selection toolbar is enabled. - */ - private static final String REMOTE_SELECTION_TOOLBAR_ENABLED = - "remote_selection_toolbar_enabled"; - - /** - * Used to mark a toolbar that has no toolbar token id. - */ - public static final long NO_TOOLBAR_ID = 0; - - /** - * The error code that do not allow to create multiple toolbar. - */ - public static final int ERROR_DO_NOT_ALLOW_MULTIPLE_TOOL_BAR = 1; - - @NonNull - private final Context mContext; - private final ISelectionToolbarManager mService; - - public SelectionToolbarManager(@NonNull Context context, - @NonNull ISelectionToolbarManager service) { - mContext = Objects.requireNonNull(context); - mService = service; - } - - /** - * Request to show selection toolbar for a given View. - */ - public void showToolbar(@NonNull ShowInfo showInfo, - @NonNull ISelectionToolbarCallback callback) { - try { - Objects.requireNonNull(showInfo); - Objects.requireNonNull(callback); - mService.showToolbar(showInfo, callback, mContext.getUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Request to hide selection toolbar. - */ - public void hideToolbar(long widgetToken) { - try { - mService.hideToolbar(widgetToken, mContext.getUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Dismiss to dismiss selection toolbar. - */ - public void dismissToolbar(long widgetToken) { - try { - mService.dismissToolbar(widgetToken, mContext.getUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - private boolean isRemoteSelectionToolbarEnabled() { - return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SELECTION_TOOLBAR, - REMOTE_SELECTION_TOOLBAR_ENABLED, false); - } - - /** - * Returns {@code true} if remote render selection toolbar enabled, otherwise - * returns {@code false}. - */ - public static boolean isRemoteSelectionToolbarEnabled(Context context) { - SelectionToolbarManager manager = context.getSystemService(SelectionToolbarManager.class); - if (manager != null) { - return manager.isRemoteSelectionToolbarEnabled(); - } - return false; - } -} diff --git a/core/java/android/view/selectiontoolbar/ShowInfo.aidl b/core/java/android/view/selectiontoolbar/ShowInfo.aidl deleted file mode 100644 index dce9c15dce3e..000000000000 --- a/core/java/android/view/selectiontoolbar/ShowInfo.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -/** - * @hide - */ -parcelable ShowInfo; diff --git a/core/java/android/view/selectiontoolbar/ShowInfo.java b/core/java/android/view/selectiontoolbar/ShowInfo.java deleted file mode 100644 index 28b4480d4967..000000000000 --- a/core/java/android/view/selectiontoolbar/ShowInfo.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -import android.annotation.NonNull; -import android.graphics.Rect; -import android.os.IBinder; -import android.os.Parcelable; - -import com.android.internal.util.DataClass; - -import java.util.List; - - -/** - * The class holds menu information for render service to render the selection toolbar. - * - * @hide - */ -@DataClass(genToString = true, genEqualsHashCode = true) -public final class ShowInfo implements Parcelable { - - /** - * The token that is used to identify the selection toolbar. This is initially set to 0 - * until a selection toolbar has been created for the showToolbar request. - */ - private final long mWidgetToken; - - /** - * If the toolbar menu items need to be re-layout. - */ - private final boolean mLayoutRequired; - - /** - * The menu items to be rendered in the selection toolbar. - */ - @NonNull - private final List<ToolbarMenuItem> mMenuItems; - - /** - * A rect specifying where the selection toolbar on the screen. - */ - @NonNull - private final Rect mContentRect; - - /** - * A recommended maximum suggested width of the selection toolbar. - */ - private final int mSuggestedWidth; - - /** - * The portion of the screen that is available to the selection toolbar. - */ - @NonNull - private final Rect mViewPortOnScreen; - - /** - * The host application's input token, this allows the remote render service to transfer - * the touch focus to the host application. - */ - @NonNull - private final IBinder mHostInputToken; - - /** - * If the host application uses light theme. - */ - private final boolean mIsLightTheme; - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/selectiontoolbar/ShowInfo.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - /** - * Creates a new ShowInfo. - * - * @param widgetToken - * The token that is used to identify the selection toolbar. This is initially set to 0 - * until a selection toolbar has been created for the showToolbar request. - * @param layoutRequired - * If the toolbar menu items need to be re-layout. - * @param menuItems - * The menu items to be rendered in the selection toolbar. - * @param contentRect - * A rect specifying where the selection toolbar on the screen. - * @param suggestedWidth - * A recommended maximum suggested width of the selection toolbar. - * @param viewPortOnScreen - * The portion of the screen that is available to the selection toolbar. - * @param hostInputToken - * The host application's input token, this allows the remote render service to transfer - * the touch focus to the host application. - * @param isLightTheme - * If the host application uses light theme. - */ - @DataClass.Generated.Member - public ShowInfo( - long widgetToken, - boolean layoutRequired, - @NonNull List<ToolbarMenuItem> menuItems, - @NonNull Rect contentRect, - int suggestedWidth, - @NonNull Rect viewPortOnScreen, - @NonNull IBinder hostInputToken, - boolean isLightTheme) { - this.mWidgetToken = widgetToken; - this.mLayoutRequired = layoutRequired; - this.mMenuItems = menuItems; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMenuItems); - this.mContentRect = contentRect; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mContentRect); - this.mSuggestedWidth = suggestedWidth; - this.mViewPortOnScreen = viewPortOnScreen; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mViewPortOnScreen); - this.mHostInputToken = hostInputToken; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHostInputToken); - this.mIsLightTheme = isLightTheme; - - // onConstructed(); // You can define this method to get a callback - } - - /** - * The token that is used to identify the selection toolbar. This is initially set to 0 - * until a selection toolbar has been created for the showToolbar request. - */ - @DataClass.Generated.Member - public long getWidgetToken() { - return mWidgetToken; - } - - /** - * If the toolbar menu items need to be re-layout. - */ - @DataClass.Generated.Member - public boolean isLayoutRequired() { - return mLayoutRequired; - } - - /** - * The menu items to be rendered in the selection toolbar. - */ - @DataClass.Generated.Member - public @NonNull List<ToolbarMenuItem> getMenuItems() { - return mMenuItems; - } - - /** - * A rect specifying where the selection toolbar on the screen. - */ - @DataClass.Generated.Member - public @NonNull Rect getContentRect() { - return mContentRect; - } - - /** - * A recommended maximum suggested width of the selection toolbar. - */ - @DataClass.Generated.Member - public int getSuggestedWidth() { - return mSuggestedWidth; - } - - /** - * The portion of the screen that is available to the selection toolbar. - */ - @DataClass.Generated.Member - public @NonNull Rect getViewPortOnScreen() { - return mViewPortOnScreen; - } - - /** - * The host application's input token, this allows the remote render service to transfer - * the touch focus to the host application. - */ - @DataClass.Generated.Member - public @NonNull IBinder getHostInputToken() { - return mHostInputToken; - } - - /** - * If the host application uses light theme. - */ - @DataClass.Generated.Member - public boolean isIsLightTheme() { - return mIsLightTheme; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "ShowInfo { " + - "widgetToken = " + mWidgetToken + ", " + - "layoutRequired = " + mLayoutRequired + ", " + - "menuItems = " + mMenuItems + ", " + - "contentRect = " + mContentRect + ", " + - "suggestedWidth = " + mSuggestedWidth + ", " + - "viewPortOnScreen = " + mViewPortOnScreen + ", " + - "hostInputToken = " + mHostInputToken + ", " + - "isLightTheme = " + mIsLightTheme + - " }"; - } - - @Override - @DataClass.Generated.Member - public boolean equals(@android.annotation.Nullable Object o) { - // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(ShowInfo other) { ... } - // boolean fieldNameEquals(FieldType otherValue) { ... } - - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - @SuppressWarnings("unchecked") - ShowInfo that = (ShowInfo) o; - //noinspection PointlessBooleanExpression - return true - && mWidgetToken == that.mWidgetToken - && mLayoutRequired == that.mLayoutRequired - && java.util.Objects.equals(mMenuItems, that.mMenuItems) - && java.util.Objects.equals(mContentRect, that.mContentRect) - && mSuggestedWidth == that.mSuggestedWidth - && java.util.Objects.equals(mViewPortOnScreen, that.mViewPortOnScreen) - && java.util.Objects.equals(mHostInputToken, that.mHostInputToken) - && mIsLightTheme == that.mIsLightTheme; - } - - @Override - @DataClass.Generated.Member - public int hashCode() { - // You can override field hashCode logic by defining methods like: - // int fieldNameHashCode() { ... } - - int _hash = 1; - _hash = 31 * _hash + Long.hashCode(mWidgetToken); - _hash = 31 * _hash + Boolean.hashCode(mLayoutRequired); - _hash = 31 * _hash + java.util.Objects.hashCode(mMenuItems); - _hash = 31 * _hash + java.util.Objects.hashCode(mContentRect); - _hash = 31 * _hash + mSuggestedWidth; - _hash = 31 * _hash + java.util.Objects.hashCode(mViewPortOnScreen); - _hash = 31 * _hash + java.util.Objects.hashCode(mHostInputToken); - _hash = 31 * _hash + Boolean.hashCode(mIsLightTheme); - return _hash; - } - - @Override - @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - - int flg = 0; - if (mLayoutRequired) flg |= 0x2; - if (mIsLightTheme) flg |= 0x80; - dest.writeInt(flg); - dest.writeLong(mWidgetToken); - dest.writeParcelableList(mMenuItems, flags); - dest.writeTypedObject(mContentRect, flags); - dest.writeInt(mSuggestedWidth); - dest.writeTypedObject(mViewPortOnScreen, flags); - dest.writeStrongBinder(mHostInputToken); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ ShowInfo(@NonNull android.os.Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - int flg = in.readInt(); - boolean layoutRequired = (flg & 0x2) != 0; - boolean isLightTheme = (flg & 0x80) != 0; - long widgetToken = in.readLong(); - List<ToolbarMenuItem> menuItems = new java.util.ArrayList<>(); - in.readParcelableList(menuItems, ToolbarMenuItem.class.getClassLoader(), android.view.selectiontoolbar.ToolbarMenuItem.class); - Rect contentRect = (Rect) in.readTypedObject(Rect.CREATOR); - int suggestedWidth = in.readInt(); - Rect viewPortOnScreen = (Rect) in.readTypedObject(Rect.CREATOR); - IBinder hostInputToken = (IBinder) in.readStrongBinder(); - - this.mWidgetToken = widgetToken; - this.mLayoutRequired = layoutRequired; - this.mMenuItems = menuItems; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMenuItems); - this.mContentRect = contentRect; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mContentRect); - this.mSuggestedWidth = suggestedWidth; - this.mViewPortOnScreen = viewPortOnScreen; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mViewPortOnScreen); - this.mHostInputToken = hostInputToken; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHostInputToken); - this.mIsLightTheme = isLightTheme; - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<ShowInfo> CREATOR - = new Parcelable.Creator<ShowInfo>() { - @Override - public ShowInfo[] newArray(int size) { - return new ShowInfo[size]; - } - - @Override - public ShowInfo createFromParcel(@NonNull android.os.Parcel in) { - return new ShowInfo(in); - } - }; - - @DataClass.Generated( - time = 1645108384245L, - codegenVersion = "1.0.23", - sourceFile = "frameworks/base/core/java/android/view/selectiontoolbar/ShowInfo.java", - inputSignatures = "private final long mWidgetToken\nprivate final boolean mLayoutRequired\nprivate final @android.annotation.NonNull java.util.List<android.view.selectiontoolbar.ToolbarMenuItem> mMenuItems\nprivate final @android.annotation.NonNull android.graphics.Rect mContentRect\nprivate final int mSuggestedWidth\nprivate final @android.annotation.NonNull android.graphics.Rect mViewPortOnScreen\nprivate final @android.annotation.NonNull android.os.IBinder mHostInputToken\nprivate final boolean mIsLightTheme\nclass ShowInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/android/view/selectiontoolbar/ToolbarMenuItem.aidl b/core/java/android/view/selectiontoolbar/ToolbarMenuItem.aidl deleted file mode 100644 index 711a85a7771e..000000000000 --- a/core/java/android/view/selectiontoolbar/ToolbarMenuItem.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -/** - * @hide - */ -parcelable ToolbarMenuItem; diff --git a/core/java/android/view/selectiontoolbar/ToolbarMenuItem.java b/core/java/android/view/selectiontoolbar/ToolbarMenuItem.java deleted file mode 100644 index 89347c613310..000000000000 --- a/core/java/android/view/selectiontoolbar/ToolbarMenuItem.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.graphics.drawable.Icon; -import android.os.Parcelable; -import android.view.MenuItem; - -import com.android.internal.util.DataClass; - -/** - * The menu item that is used to show the selection toolbar. - * - * @hide - */ -@DataClass(genBuilder = true, genToString = true, genEqualsHashCode = true) -public final class ToolbarMenuItem implements Parcelable { - - /** - * The priority of menu item is unknown. - */ - public static final int PRIORITY_UNKNOWN = 0; - - /** - * The priority of menu item is shown in primary selection toolbar. - */ - public static final int PRIORITY_PRIMARY = 1; - - /** - * The priority of menu item is shown in overflow selection toolbar. - */ - public static final int PRIORITY_OVERFLOW = 2; - - /** - * The id of the menu item. - * - * @see MenuItem#getItemId() - */ - private final int mItemId; - - /** - * The title of the menu item. - * - * @see MenuItem#getTitle() - */ - @NonNull - private final CharSequence mTitle; - - /** - * The content description of the menu item. - * - * @see MenuItem#getContentDescription() - */ - @Nullable - private final CharSequence mContentDescription; - - /** - * The group id of the menu item. - * - * @see MenuItem#getGroupId() - */ - private final int mGroupId; - - /** - * The icon id of the menu item. - * - * @see MenuItem#getIcon() - */ - @Nullable - private final Icon mIcon; - - /** - * The tooltip text of the menu item. - * - * @see MenuItem#getTooltipText() - */ - @Nullable - private final CharSequence mTooltipText; - - /** - * The priority of the menu item used to display the order of the menu item. - */ - private final int mPriority; - - /** - * Returns the priority from a given {@link MenuItem}. - */ - public static int getPriorityFromMenuItem(MenuItem menuItem) { - if (menuItem.requiresActionButton()) { - return PRIORITY_PRIMARY; - } else if (menuItem.requiresOverflow()) { - return PRIORITY_OVERFLOW; - } - return PRIORITY_UNKNOWN; - } - - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/selectiontoolbar/ToolbarMenuItem.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - @android.annotation.IntDef(prefix = "PRIORITY_", value = { - PRIORITY_UNKNOWN, - PRIORITY_PRIMARY, - PRIORITY_OVERFLOW - }) - @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) - @DataClass.Generated.Member - public @interface Priority {} - - @DataClass.Generated.Member - public static String priorityToString(@Priority int value) { - switch (value) { - case PRIORITY_UNKNOWN: - return "PRIORITY_UNKNOWN"; - case PRIORITY_PRIMARY: - return "PRIORITY_PRIMARY"; - case PRIORITY_OVERFLOW: - return "PRIORITY_OVERFLOW"; - default: return Integer.toHexString(value); - } - } - - @DataClass.Generated.Member - /* package-private */ ToolbarMenuItem( - int itemId, - @NonNull CharSequence title, - @Nullable CharSequence contentDescription, - int groupId, - @Nullable Icon icon, - @Nullable CharSequence tooltipText, - int priority) { - this.mItemId = itemId; - this.mTitle = title; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mTitle); - this.mContentDescription = contentDescription; - this.mGroupId = groupId; - this.mIcon = icon; - this.mTooltipText = tooltipText; - this.mPriority = priority; - - // onConstructed(); // You can define this method to get a callback - } - - /** - * The id of the menu item. - * - * @see MenuItem#getItemId() - */ - @DataClass.Generated.Member - public int getItemId() { - return mItemId; - } - - /** - * The title of the menu item. - * - * @see MenuItem#getTitle() - */ - @DataClass.Generated.Member - public @NonNull CharSequence getTitle() { - return mTitle; - } - - /** - * The content description of the menu item. - * - * @see MenuItem#getContentDescription() - */ - @DataClass.Generated.Member - public @Nullable CharSequence getContentDescription() { - return mContentDescription; - } - - /** - * The group id of the menu item. - * - * @see MenuItem#getGroupId() - */ - @DataClass.Generated.Member - public int getGroupId() { - return mGroupId; - } - - /** - * The icon id of the menu item. - * - * @see MenuItem#getIcon() - */ - @DataClass.Generated.Member - public @Nullable Icon getIcon() { - return mIcon; - } - - /** - * The tooltip text of the menu item. - * - * @see MenuItem#getTooltipText() - */ - @DataClass.Generated.Member - public @Nullable CharSequence getTooltipText() { - return mTooltipText; - } - - /** - * The priority of the menu item used to display the order of the menu item. - */ - @DataClass.Generated.Member - public int getPriority() { - return mPriority; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "ToolbarMenuItem { " + - "itemId = " + mItemId + ", " + - "title = " + mTitle + ", " + - "contentDescription = " + mContentDescription + ", " + - "groupId = " + mGroupId + ", " + - "icon = " + mIcon + ", " + - "tooltipText = " + mTooltipText + ", " + - "priority = " + mPriority + - " }"; - } - - @Override - @DataClass.Generated.Member - public boolean equals(@Nullable Object o) { - // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(ToolbarMenuItem other) { ... } - // boolean fieldNameEquals(FieldType otherValue) { ... } - - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - @SuppressWarnings("unchecked") - ToolbarMenuItem that = (ToolbarMenuItem) o; - //noinspection PointlessBooleanExpression - return true - && mItemId == that.mItemId - && java.util.Objects.equals(mTitle, that.mTitle) - && java.util.Objects.equals(mContentDescription, that.mContentDescription) - && mGroupId == that.mGroupId - && java.util.Objects.equals(mIcon, that.mIcon) - && java.util.Objects.equals(mTooltipText, that.mTooltipText) - && mPriority == that.mPriority; - } - - @Override - @DataClass.Generated.Member - public int hashCode() { - // You can override field hashCode logic by defining methods like: - // int fieldNameHashCode() { ... } - - int _hash = 1; - _hash = 31 * _hash + mItemId; - _hash = 31 * _hash + java.util.Objects.hashCode(mTitle); - _hash = 31 * _hash + java.util.Objects.hashCode(mContentDescription); - _hash = 31 * _hash + mGroupId; - _hash = 31 * _hash + java.util.Objects.hashCode(mIcon); - _hash = 31 * _hash + java.util.Objects.hashCode(mTooltipText); - _hash = 31 * _hash + mPriority; - return _hash; - } - - @Override - @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - - byte flg = 0; - if (mContentDescription != null) flg |= 0x4; - if (mIcon != null) flg |= 0x10; - if (mTooltipText != null) flg |= 0x20; - dest.writeByte(flg); - dest.writeInt(mItemId); - dest.writeCharSequence(mTitle); - if (mContentDescription != null) dest.writeCharSequence(mContentDescription); - dest.writeInt(mGroupId); - if (mIcon != null) dest.writeTypedObject(mIcon, flags); - if (mTooltipText != null) dest.writeCharSequence(mTooltipText); - dest.writeInt(mPriority); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ ToolbarMenuItem(@NonNull android.os.Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - byte flg = in.readByte(); - int itemId = in.readInt(); - CharSequence title = (CharSequence) in.readCharSequence(); - CharSequence contentDescription = (flg & 0x4) == 0 ? null : (CharSequence) in.readCharSequence(); - int groupId = in.readInt(); - Icon icon = (flg & 0x10) == 0 ? null : (Icon) in.readTypedObject(Icon.CREATOR); - CharSequence tooltipText = (flg & 0x20) == 0 ? null : (CharSequence) in.readCharSequence(); - int priority = in.readInt(); - - this.mItemId = itemId; - this.mTitle = title; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mTitle); - this.mContentDescription = contentDescription; - this.mGroupId = groupId; - this.mIcon = icon; - this.mTooltipText = tooltipText; - this.mPriority = priority; - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<ToolbarMenuItem> CREATOR - = new Parcelable.Creator<ToolbarMenuItem>() { - @Override - public ToolbarMenuItem[] newArray(int size) { - return new ToolbarMenuItem[size]; - } - - @Override - public ToolbarMenuItem createFromParcel(@NonNull android.os.Parcel in) { - return new ToolbarMenuItem(in); - } - }; - - /** - * A builder for {@link ToolbarMenuItem} - */ - @SuppressWarnings("WeakerAccess") - @DataClass.Generated.Member - public static final class Builder { - - private int mItemId; - private @NonNull CharSequence mTitle; - private @Nullable CharSequence mContentDescription; - private int mGroupId; - private @Nullable Icon mIcon; - private @Nullable CharSequence mTooltipText; - private int mPriority; - - private long mBuilderFieldsSet = 0L; - - /** - * Creates a new Builder. - * - * @param itemId - * The id of the menu item. - * @param title - * The title of the menu item. - * @param contentDescription - * The content description of the menu item. - * @param groupId - * The group id of the menu item. - * @param icon - * The icon id of the menu item. - * @param tooltipText - * The tooltip text of the menu item. - * @param priority - * The priority of the menu item used to display the order of the menu item. - */ - public Builder( - int itemId, - @NonNull CharSequence title, - @Nullable CharSequence contentDescription, - int groupId, - @Nullable Icon icon, - @Nullable CharSequence tooltipText, - int priority) { - mItemId = itemId; - mTitle = title; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mTitle); - mContentDescription = contentDescription; - mGroupId = groupId; - mIcon = icon; - mTooltipText = tooltipText; - mPriority = priority; - } - - /** - * The id of the menu item. - * - * @see MenuItem#getItemId() - */ - @DataClass.Generated.Member - public @NonNull Builder setItemId(int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x1; - mItemId = value; - return this; - } - - /** - * The title of the menu item. - * - * @see MenuItem#getTitle() - */ - @DataClass.Generated.Member - public @NonNull Builder setTitle(@NonNull CharSequence value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x2; - mTitle = value; - return this; - } - - /** - * The content description of the menu item. - * - * @see MenuItem#getContentDescription() - */ - @DataClass.Generated.Member - public @NonNull Builder setContentDescription(@NonNull CharSequence value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x4; - mContentDescription = value; - return this; - } - - /** - * The group id of the menu item. - * - * @see MenuItem#getGroupId() - */ - @DataClass.Generated.Member - public @NonNull Builder setGroupId(int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x8; - mGroupId = value; - return this; - } - - /** - * The icon id of the menu item. - * - * @see MenuItem#getIcon() - */ - @DataClass.Generated.Member - public @NonNull Builder setIcon(@NonNull Icon value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x10; - mIcon = value; - return this; - } - - /** - * The tooltip text of the menu item. - * - * @see MenuItem#getTooltipText() - */ - @DataClass.Generated.Member - public @NonNull Builder setTooltipText(@NonNull CharSequence value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x20; - mTooltipText = value; - return this; - } - - /** - * The priority of the menu item used to display the order of the menu item. - */ - @DataClass.Generated.Member - public @NonNull Builder setPriority(int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x40; - mPriority = value; - return this; - } - - /** Builds the instance. This builder should not be touched after calling this! */ - public @NonNull ToolbarMenuItem build() { - checkNotUsed(); - mBuilderFieldsSet |= 0x80; // Mark builder used - - ToolbarMenuItem o = new ToolbarMenuItem( - mItemId, - mTitle, - mContentDescription, - mGroupId, - mIcon, - mTooltipText, - mPriority); - return o; - } - - private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x80) != 0) { - throw new IllegalStateException( - "This Builder should not be reused. Use a new Builder instance instead"); - } - } - } - - @DataClass.Generated( - time = 1643200806234L, - codegenVersion = "1.0.23", - sourceFile = "frameworks/base/core/java/android/view/selectiontoolbar/ToolbarMenuItem.java", - inputSignatures = "public static final int PRIORITY_UNKNOWN\npublic static final int PRIORITY_PRIMARY\npublic static final int PRIORITY_OVERFLOW\nprivate final int mItemId\nprivate final @android.annotation.NonNull java.lang.CharSequence mTitle\nprivate final @android.annotation.Nullable java.lang.CharSequence mContentDescription\nprivate final int mGroupId\nprivate final @android.annotation.Nullable android.graphics.drawable.Icon mIcon\nprivate final @android.annotation.Nullable java.lang.CharSequence mTooltipText\nprivate final int mPriority\npublic static int getPriorityFromMenuItem(android.view.MenuItem)\nclass ToolbarMenuItem extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genToString=true, genEqualsHashCode=true)") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/android/view/selectiontoolbar/WidgetInfo.aidl b/core/java/android/view/selectiontoolbar/WidgetInfo.aidl deleted file mode 100644 index 1057c516e233..000000000000 --- a/core/java/android/view/selectiontoolbar/WidgetInfo.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -/** - * @hide - */ -parcelable WidgetInfo; diff --git a/core/java/android/view/selectiontoolbar/WidgetInfo.java b/core/java/android/view/selectiontoolbar/WidgetInfo.java deleted file mode 100644 index 5d0fd473c914..000000000000 --- a/core/java/android/view/selectiontoolbar/WidgetInfo.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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.view.selectiontoolbar; - -import android.annotation.NonNull; -import android.graphics.Rect; -import android.os.Parcel; -import android.os.Parcelable; -import android.view.SurfaceControlViewHost; - -import com.android.internal.util.DataClass; - -/** - * The class holds the rendered content and the related information from the render service to - * be used to show on the selection toolbar. - * - * @hide - */ -@DataClass(genToString = true, genEqualsHashCode = true) -public final class WidgetInfo implements Parcelable { - - /** - * The token that is used to identify the selection toolbar. - */ - private final long mWidgetToken; - - /** - * A Rect that defines the size and positioning of the remote view with respect to - * its host window. - */ - @NonNull - private final Rect mContentRect; - - /** - * The SurfacePackage pointing to the remote view. - */ - @NonNull - private final SurfaceControlViewHost.SurfacePackage mSurfacePackage; - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/selectiontoolbar/WidgetInfo.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - /** - * Creates a new WidgetInfo. - * - * @param widgetToken - * The token that is used to identify the selection toolbar. - * @param contentRect - * A Rect that defines the size and positioning of the remote view with respect to - * its host window. - * @param surfacePackage - * The SurfacePackage pointing to the remote view. - */ - @DataClass.Generated.Member - public WidgetInfo( - long widgetToken, - @NonNull Rect contentRect, - @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { - this.mWidgetToken = widgetToken; - this.mContentRect = contentRect; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mContentRect); - this.mSurfacePackage = surfacePackage; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mSurfacePackage); - - // onConstructed(); // You can define this method to get a callback - } - - /** - * The token that is used to identify the selection toolbar. - */ - @DataClass.Generated.Member - public long getWidgetToken() { - return mWidgetToken; - } - - /** - * A Rect that defines the size and positioning of the remote view with respect to - * its host window. - */ - @DataClass.Generated.Member - public @NonNull Rect getContentRect() { - return mContentRect; - } - - /** - * The SurfacePackage pointing to the remote view. - */ - @DataClass.Generated.Member - public @NonNull SurfaceControlViewHost.SurfacePackage getSurfacePackage() { - return mSurfacePackage; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "WidgetInfo { " + - "widgetToken = " + mWidgetToken + ", " + - "contentRect = " + mContentRect + ", " + - "surfacePackage = " + mSurfacePackage + - " }"; - } - - @Override - @DataClass.Generated.Member - public boolean equals(@android.annotation.Nullable Object o) { - // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(WidgetInfo other) { ... } - // boolean fieldNameEquals(FieldType otherValue) { ... } - - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - @SuppressWarnings("unchecked") - WidgetInfo that = (WidgetInfo) o; - //noinspection PointlessBooleanExpression - return true - && mWidgetToken == that.mWidgetToken - && java.util.Objects.equals(mContentRect, that.mContentRect) - && java.util.Objects.equals(mSurfacePackage, that.mSurfacePackage); - } - - @Override - @DataClass.Generated.Member - public int hashCode() { - // You can override field hashCode logic by defining methods like: - // int fieldNameHashCode() { ... } - - int _hash = 1; - _hash = 31 * _hash + Long.hashCode(mWidgetToken); - _hash = 31 * _hash + java.util.Objects.hashCode(mContentRect); - _hash = 31 * _hash + java.util.Objects.hashCode(mSurfacePackage); - return _hash; - } - - @Override - @DataClass.Generated.Member - public void writeToParcel(@NonNull Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - - dest.writeLong(mWidgetToken); - dest.writeTypedObject(mContentRect, flags); - dest.writeTypedObject(mSurfacePackage, flags); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ WidgetInfo(@NonNull Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - long widgetToken = in.readLong(); - Rect contentRect = (Rect) in.readTypedObject(Rect.CREATOR); - SurfaceControlViewHost.SurfacePackage surfacePackage = (SurfaceControlViewHost.SurfacePackage) in.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR); - - this.mWidgetToken = widgetToken; - this.mContentRect = contentRect; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mContentRect); - this.mSurfacePackage = surfacePackage; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mSurfacePackage); - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<WidgetInfo> CREATOR - = new Parcelable.Creator<WidgetInfo>() { - @Override - public WidgetInfo[] newArray(int size) { - return new WidgetInfo[size]; - } - - @Override - public WidgetInfo createFromParcel(@NonNull Parcel in) { - return new WidgetInfo(in); - } - }; - - @DataClass.Generated( - time = 1643281495056L, - codegenVersion = "1.0.23", - sourceFile = "frameworks/base/core/java/android/view/selectiontoolbar/WidgetInfo.java", - inputSignatures = "private final long mWidgetToken\nprivate final @android.annotation.NonNull android.graphics.Rect mContentRect\nprivate final @android.annotation.NonNull android.view.SurfaceControlViewHost.SurfacePackage mSurfacePackage\nclass WidgetInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java index f7af67b3b2a8..e9449eb96bb3 100644 --- a/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java +++ b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java @@ -21,7 +21,6 @@ import android.content.Context; import android.graphics.Rect; import android.view.MenuItem; import android.view.View; -import android.view.selectiontoolbar.SelectionToolbarManager; import android.widget.PopupWindow; import java.util.List; @@ -89,14 +88,10 @@ public interface FloatingToolbarPopup { @Nullable PopupWindow.OnDismissListener onDismiss); /** - * Returns {@link RemoteFloatingToolbarPopup} implementation if the system selection toolbar - * enabled, otherwise returns {@link LocalFloatingToolbarPopup} implementation. + * Returns {@link LocalFloatingToolbarPopup} implementation. */ static FloatingToolbarPopup createInstance(Context context, View parent) { - boolean enabled = SelectionToolbarManager.isRemoteSelectionToolbarEnabled(context); - return enabled - ? new RemoteFloatingToolbarPopup(context, parent) - : new LocalFloatingToolbarPopup(context, parent); + return new LocalFloatingToolbarPopup(context, parent); } } diff --git a/core/java/com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java deleted file mode 100644 index 8787c39458b9..000000000000 --- a/core/java/com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java +++ /dev/null @@ -1,572 +0,0 @@ -/* - * 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.internal.widget.floatingtoolbar; - -import static android.view.selectiontoolbar.SelectionToolbarManager.NO_TOOLBAR_ID; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.UiThread; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.PixelFormat; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; -import android.text.TextUtils; -import android.util.Log; -import android.view.Gravity; -import android.view.MenuItem; -import android.view.SurfaceView; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.SelectionToolbarManager; -import android.view.selectiontoolbar.ShowInfo; -import android.view.selectiontoolbar.ToolbarMenuItem; -import android.view.selectiontoolbar.WidgetInfo; -import android.widget.LinearLayout; -import android.widget.PopupWindow; - -import com.android.internal.R; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; - -/** - * A popup window used by the floating toolbar to render menu items in the remote system process. - * - * It holds 2 panels (i.e. main panel and overflow panel) and an overflow button - * to transition between panels. - */ -public final class RemoteFloatingToolbarPopup implements FloatingToolbarPopup { - - private static final boolean DEBUG = - Log.isLoggable(FloatingToolbar.FLOATING_TOOLBAR_TAG, Log.VERBOSE); - - private static final int TOOLBAR_STATE_SHOWN = 1; - private static final int TOOLBAR_STATE_HIDDEN = 2; - private static final int TOOLBAR_STATE_DISMISSED = 3; - - @IntDef(prefix = {"TOOLBAR_STATE_"}, value = { - TOOLBAR_STATE_SHOWN, - TOOLBAR_STATE_HIDDEN, - TOOLBAR_STATE_DISMISSED - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ToolbarState { - } - - @NonNull - private final SelectionToolbarManager mSelectionToolbarManager; - // Parent for the popup window. - @NonNull - private final View mParent; - // A popup window used for showing menu items rendered by the remote system process - @NonNull - private final PopupWindow mPopupWindow; - // The callback to handle remote rendered selection toolbar. - @NonNull - private final SelectionToolbarCallbackImpl mSelectionToolbarCallback; - - // tracks this popup state. - private @ToolbarState int mState; - - // The token of the current showing floating toolbar. - private long mFloatingToolbarToken; - private final Rect mPreviousContentRect = new Rect(); - private List<MenuItem> mMenuItems; - private MenuItem.OnMenuItemClickListener mMenuItemClickListener; - private int mSuggestedWidth; - private final Rect mScreenViewPort = new Rect(); - private boolean mWidthChanged = true; - private final boolean mIsLightTheme; - - private final int[] mCoordsOnScreen = new int[2]; - private final int[] mCoordsOnWindow = new int[2]; - - public RemoteFloatingToolbarPopup(Context context, View parent) { - mParent = Objects.requireNonNull(parent); - mPopupWindow = createPopupWindow(context); - mSelectionToolbarManager = context.getSystemService(SelectionToolbarManager.class); - mSelectionToolbarCallback = new SelectionToolbarCallbackImpl(this); - mIsLightTheme = isLightTheme(context); - mFloatingToolbarToken = NO_TOOLBAR_ID; - } - - private boolean isLightTheme(Context context) { - TypedArray a = context.obtainStyledAttributes(new int[]{R.attr.isLightTheme}); - boolean isLightTheme = a.getBoolean(0, true); - a.recycle(); - return isLightTheme; - } - - @UiThread - @Override - public void show(List<MenuItem> menuItems, - MenuItem.OnMenuItemClickListener menuItemClickListener, Rect contentRect) { - Objects.requireNonNull(menuItems); - Objects.requireNonNull(menuItemClickListener); - if (isShowing() && Objects.equals(menuItems, mMenuItems) - && Objects.equals(contentRect, mPreviousContentRect)) { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "Ignore duplicate show() for the same content."); - } - return; - } - - boolean isLayoutRequired = mMenuItems == null - || !MenuItemRepr.reprEquals(menuItems, mMenuItems) - || mWidthChanged; - if (isLayoutRequired) { - mSelectionToolbarManager.dismissToolbar(mFloatingToolbarToken); - doDismissPopupWindow(); - } - mMenuItemClickListener = menuItemClickListener; - mMenuItems = menuItems; - - mParent.getWindowVisibleDisplayFrame(mScreenViewPort); - final int suggestWidth = mSuggestedWidth > 0 - ? mSuggestedWidth - : mParent.getResources().getDimensionPixelSize( - R.dimen.floating_toolbar_preferred_width); - final ShowInfo showInfo = new ShowInfo( - mFloatingToolbarToken, isLayoutRequired, - getToolbarMenuItems(mMenuItems), - contentRect, - suggestWidth, - mScreenViewPort, - mParent.getViewRootImpl().getInputToken(), mIsLightTheme); - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "RemoteFloatingToolbarPopup.show() for " + showInfo); - } - mSelectionToolbarManager.showToolbar(showInfo, mSelectionToolbarCallback); - mPreviousContentRect.set(contentRect); - } - - @UiThread - @Override - public void dismiss() { - if (mState == TOOLBAR_STATE_DISMISSED) { - Log.w(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "The floating toolbar already dismissed."); - return; - } - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "RemoteFloatingToolbarPopup.dismiss()."); - } - mSelectionToolbarManager.dismissToolbar(mFloatingToolbarToken); - doDismissPopupWindow(); - } - - @UiThread - @Override - public void hide() { - if (mState == TOOLBAR_STATE_DISMISSED || mState == TOOLBAR_STATE_HIDDEN) { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "The floating toolbar already dismissed or hidden."); - } - return; - } - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "RemoteFloatingToolbarPopup.hide()."); - } - mSelectionToolbarManager.hideToolbar(mFloatingToolbarToken); - mState = TOOLBAR_STATE_HIDDEN; - mPopupWindow.dismiss(); - } - - @UiThread - @Override - public void setSuggestedWidth(int suggestedWidth) { - int difference = Math.abs(suggestedWidth - mSuggestedWidth); - mWidthChanged = difference > (mSuggestedWidth * 0.2); - mSuggestedWidth = suggestedWidth; - } - - @Override - public void setWidthChanged(boolean widthChanged) { - mWidthChanged = widthChanged; - } - - @UiThread - @Override - public boolean isHidden() { - return mState == TOOLBAR_STATE_HIDDEN; - } - - @UiThread - @Override - public boolean isShowing() { - return mState == TOOLBAR_STATE_SHOWN; - } - - @UiThread - @Override - public boolean setOutsideTouchable(boolean outsideTouchable, - @Nullable PopupWindow.OnDismissListener onDismiss) { - if (mState == TOOLBAR_STATE_DISMISSED) { - return false; - } - boolean ret = false; - if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) { - mPopupWindow.setOutsideTouchable(outsideTouchable); - mPopupWindow.setFocusable(!outsideTouchable); - mPopupWindow.update(); - ret = true; - } - mPopupWindow.setOnDismissListener(onDismiss); - return ret; - } - - private void updatePopupWindowContent(WidgetInfo widgetInfo) { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, "updatePopupWindowContent."); - } - ViewGroup contentContainer = (ViewGroup) mPopupWindow.getContentView(); - contentContainer.removeAllViews(); - SurfaceView surfaceView = new SurfaceView(mParent.getContext()); - surfaceView.setZOrderOnTop(true); - surfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT); - surfaceView.setChildSurfacePackage(widgetInfo.getSurfacePackage()); - contentContainer.addView(surfaceView); - } - - private MenuItem getMenuItemByToolbarMenuItem(ToolbarMenuItem toolbarMenuItem) { - for (MenuItem item : mMenuItems) { - if (toolbarMenuItem.getItemId() == item.getItemId()) { - return item; - } - } - return null; - } - - private Point getCoordinatesInWindow(int x, int y) { - // We later specify the location of PopupWindow relative to the attached window. - // The idea here is that 1) we can get the location of a View in both window coordinates - // and screen coordinates, where the offset between them should be equal to the window - // origin, and 2) we can use an arbitrary for this calculation while calculating the - // location of the rootview is supposed to be least expensive. - // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can avoid - // the following calculation. - mParent.getRootView().getLocationOnScreen(mCoordsOnScreen); - mParent.getRootView().getLocationInWindow(mCoordsOnWindow); - int windowLeftOnScreen = mCoordsOnScreen[0] - mCoordsOnWindow[0]; - int windowTopOnScreen = mCoordsOnScreen[1] - mCoordsOnWindow[1]; - return new Point(Math.max(0, x - windowLeftOnScreen), Math.max(0, y - windowTopOnScreen)); - } - - private static List<ToolbarMenuItem> getToolbarMenuItems(List<MenuItem> menuItems) { - final List<ToolbarMenuItem> list = new ArrayList<>(menuItems.size()); - for (MenuItem menuItem : menuItems) { - // TODO: use ToolbarMenuItem.Builder(MenuItem) instead - ToolbarMenuItem toolbarMenuItem = new ToolbarMenuItem.Builder(menuItem.getItemId(), - menuItem.getTitle(), menuItem.getContentDescription(), menuItem.getGroupId(), - convertDrawableToIcon(menuItem.getIcon()), - menuItem.getTooltipText(), - ToolbarMenuItem.getPriorityFromMenuItem(menuItem)).build(); - list.add(toolbarMenuItem); - } - return list; - } - - private static Icon convertDrawableToIcon(Drawable drawable) { - if (drawable == null) { - return null; - } - if (drawable instanceof BitmapDrawable) { - final BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - if (bitmapDrawable.getBitmap() != null) { - return Icon.createWithBitmap(bitmapDrawable.getBitmap()); - } - } - final Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), - drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); - return Icon.createWithBitmap(bitmap); - } - - private static PopupWindow createPopupWindow(Context content) { - ViewGroup popupContentHolder = new LinearLayout(content); - PopupWindow popupWindow = new PopupWindow(popupContentHolder); - popupWindow.setClippingEnabled(false); - popupWindow.setWindowLayoutType( - WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL); - popupWindow.setAnimationStyle(0); - popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); - return popupWindow; - } - - private void doDismissPopupWindow() { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, "RemoteFloatingToolbarPopup.doDismiss()."); - } - mState = TOOLBAR_STATE_DISMISSED; - mMenuItems = null; - mMenuItemClickListener = null; - mFloatingToolbarToken = 0; - mSuggestedWidth = 0; - mWidthChanged = true; - resetCoords(); - mPreviousContentRect.setEmpty(); - mScreenViewPort.setEmpty(); - mPopupWindow.dismiss(); - } - - private void resetCoords() { - mCoordsOnScreen[0] = 0; - mCoordsOnScreen[1] = 0; - mCoordsOnWindow[0] = 0; - mCoordsOnWindow[1] = 0; - } - - private void runOnUiThread(Runnable runnable) { - mParent.post(runnable); - } - - private void onShow(WidgetInfo info) { - runOnUiThread(() -> { - mFloatingToolbarToken = info.getWidgetToken(); - mState = TOOLBAR_STATE_SHOWN; - updatePopupWindowContent(info); - Rect contentRect = info.getContentRect(); - mPopupWindow.setWidth(contentRect.width()); - mPopupWindow.setHeight(contentRect.height()); - final Point coords = getCoordinatesInWindow(contentRect.left, contentRect.top); - mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, coords.x, coords.y); - }); - } - - private void onWidgetUpdated(WidgetInfo info) { - runOnUiThread(() -> { - if (!isShowing()) { - Log.w(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "onWidgetUpdated(): The widget isn't showing."); - return; - } - updatePopupWindowContent(info); - Rect contentRect = info.getContentRect(); - Point coords = getCoordinatesInWindow(contentRect.left, contentRect.top); - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "PopupWindow x= " + coords.x + " y= " + coords.y + " w=" - + contentRect.width() + " h=" + contentRect.height()); - } - mPopupWindow.update(coords.x, coords.y, contentRect.width(), contentRect.height()); - }); - } - - private void onToolbarShowTimeout() { - runOnUiThread(() -> { - if (mState == TOOLBAR_STATE_DISMISSED) { - return; - } - doDismissPopupWindow(); - }); - } - - private void onMenuItemClicked(ToolbarMenuItem toolbarMenuItem) { - runOnUiThread(() -> { - if (mMenuItems == null || mMenuItemClickListener == null) { - return; - } - MenuItem item = getMenuItemByToolbarMenuItem(toolbarMenuItem); - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "SelectionToolbarCallbackImpl onMenuItemClicked. toolbarMenuItem=" - + toolbarMenuItem + " item=" + item); - } - // TODO: handle the menu item like clipboard - if (item != null) { - mMenuItemClickListener.onMenuItemClick(item); - } else { - Log.e(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "onMenuItemClicked: cannot find menu item."); - } - }); - } - - private static class SelectionToolbarCallbackImpl extends ISelectionToolbarCallback.Stub { - - private final WeakReference<RemoteFloatingToolbarPopup> mRemotePopup; - - SelectionToolbarCallbackImpl(RemoteFloatingToolbarPopup popup) { - mRemotePopup = new WeakReference<>(popup); - } - - @Override - public void onShown(WidgetInfo info) { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "SelectionToolbarCallbackImpl onShown: " + info); - } - final RemoteFloatingToolbarPopup remoteFloatingToolbarPopup = mRemotePopup.get(); - if (remoteFloatingToolbarPopup != null) { - remoteFloatingToolbarPopup.onShow(info); - } else { - Log.w(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "Lost remoteFloatingToolbarPopup reference for onShown."); - } - } - - @Override - public void onWidgetUpdated(WidgetInfo info) { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "SelectionToolbarCallbackImpl onWidgetUpdated: info = " + info); - } - final RemoteFloatingToolbarPopup remoteFloatingToolbarPopup = mRemotePopup.get(); - if (remoteFloatingToolbarPopup != null) { - remoteFloatingToolbarPopup.onWidgetUpdated(info); - } else { - Log.w(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "Lost remoteFloatingToolbarPopup reference for onWidgetUpdated."); - } - } - - @Override - public void onToolbarShowTimeout() { - final RemoteFloatingToolbarPopup remoteFloatingToolbarPopup = mRemotePopup.get(); - if (remoteFloatingToolbarPopup != null) { - remoteFloatingToolbarPopup.onToolbarShowTimeout(); - } else { - Log.w(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "Lost remoteFloatingToolbarPopup reference for onToolbarShowTimeout."); - } - } - - @Override - public void onMenuItemClicked(ToolbarMenuItem toolbarMenuItem) { - final RemoteFloatingToolbarPopup remoteFloatingToolbarPopup = mRemotePopup.get(); - if (remoteFloatingToolbarPopup != null) { - remoteFloatingToolbarPopup.onMenuItemClicked(toolbarMenuItem); - } else { - Log.w(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "Lost remoteFloatingToolbarPopup reference for onMenuItemClicked."); - } - } - - @Override - public void onError(int errorCode) { - if (DEBUG) { - Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG, - "SelectionToolbarCallbackImpl onError: " + errorCode); - } - } - } - - /** - * Represents the identity of a MenuItem that is rendered in a FloatingToolbarPopup. - */ - static final class MenuItemRepr { - - public final int mItemId; - public final int mGroupId; - @Nullable - public final String mTitle; - @Nullable private final Drawable mIcon; - - private MenuItemRepr( - int itemId, int groupId, @Nullable CharSequence title, - @Nullable Drawable icon) { - mItemId = itemId; - mGroupId = groupId; - mTitle = (title == null) ? null : title.toString(); - mIcon = icon; - } - - /** - * Creates an instance of MenuItemRepr for the specified menu item. - */ - public static MenuItemRepr of(MenuItem menuItem) { - return new MenuItemRepr( - menuItem.getItemId(), - menuItem.getGroupId(), - menuItem.getTitle(), - menuItem.getIcon()); - } - - /** - * Returns this object's hashcode. - */ - @Override - public int hashCode() { - return Objects.hash(mItemId, mGroupId, mTitle, mIcon); - } - - /** - * Returns true if this object is the same as the specified object. - */ - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof LocalFloatingToolbarPopup.MenuItemRepr)) { - return false; - } - final MenuItemRepr other = (MenuItemRepr) o; - return mItemId == other.mItemId - && mGroupId == other.mGroupId - && TextUtils.equals(mTitle, other.mTitle) - // Many Drawables (icons) do not implement equals(). Using equals() here instead - // of reference comparisons in case a Drawable subclass implements equals(). - && Objects.equals(mIcon, other.mIcon); - } - - /** - * Returns true if the two menu item collections are the same based on MenuItemRepr. - */ - public static boolean reprEquals( - Collection<MenuItem> menuItems1, Collection<MenuItem> menuItems2) { - if (menuItems1.size() != menuItems2.size()) { - return false; - } - - final Iterator<MenuItem> menuItems2Iter = menuItems2.iterator(); - for (MenuItem menuItem1 : menuItems1) { - final MenuItem menuItem2 = menuItems2Iter.next(); - if (!MenuItemRepr.of(menuItem1).equals( - MenuItemRepr.of(menuItem2))) { - return false; - } - } - return true; - } - } -} diff --git a/services/Android.bp b/services/Android.bp index 53dc06805f14..9264172974e1 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -115,7 +115,6 @@ filegroup { ":services.profcollect-sources", ":services.restrictions-sources", ":services.searchui-sources", - ":services.selectiontoolbar-sources", ":services.smartspace-sources", ":services.soundtrigger-sources", ":services.systemcaptions-sources", @@ -174,7 +173,6 @@ java_library { "services.profcollect", "services.restrictions", "services.searchui", - "services.selectiontoolbar", "services.smartspace", "services.soundtrigger", "services.systemcaptions", diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index caa434366a17..57fa12d20de5 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -354,8 +354,6 @@ public final class SystemServer implements Dumpable { "com.android.server.contentcapture.ContentCaptureManagerService"; private static final String TRANSLATION_MANAGER_SERVICE_CLASS = "com.android.server.translation.TranslationManagerService"; - private static final String SELECTION_TOOLBAR_MANAGER_SERVICE_CLASS = - "com.android.server.selectiontoolbar.SelectionToolbarManagerService"; private static final String MUSIC_RECOGNITION_MANAGER_SERVICE_CLASS = "com.android.server.musicrecognition.MusicRecognitionManagerService"; private static final String AMBIENT_CONTEXT_MANAGER_SERVICE_CLASS = @@ -2738,13 +2736,6 @@ public final class SystemServer implements Dumpable { Slog.d(TAG, "TranslationService not defined by OEM"); } - if (!isTv) { - // Selection toolbar service - t.traceBegin("StartSelectionToolbarManagerService"); - mSystemServiceManager.startService(SELECTION_TOOLBAR_MANAGER_SERVICE_CLASS); - t.traceEnd(); - } - // NOTE: ClipboardService depends on ContentCapture and Autofill t.traceBegin("StartClipboardService"); mSystemServiceManager.startService(ClipboardService.class); diff --git a/services/selectiontoolbar/Android.bp b/services/selectiontoolbar/Android.bp deleted file mode 100644 index cc6405f97bc3..000000000000 --- a/services/selectiontoolbar/Android.bp +++ /dev/null @@ -1,22 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -filegroup { - name: "services.selectiontoolbar-sources", - srcs: ["java/**/*.java"], - path: "java", - visibility: ["//frameworks/base/services"], -} - -java_library_static { - name: "services.selectiontoolbar", - defaults: ["platform_service_defaults"], - srcs: [":services.selectiontoolbar-sources"], - libs: ["services.core"], -} diff --git a/services/selectiontoolbar/OWNERS b/services/selectiontoolbar/OWNERS deleted file mode 100644 index ed9425cc26c9..000000000000 --- a/services/selectiontoolbar/OWNERS +++ /dev/null @@ -1 +0,0 @@ -include /core/java/android/view/selectiontoolbar/OWNERS diff --git a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/RemoteSelectionToolbarRenderService.java b/services/selectiontoolbar/java/com/android/server/selectiontoolbar/RemoteSelectionToolbarRenderService.java deleted file mode 100644 index ae4227bd4f23..000000000000 --- a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/RemoteSelectionToolbarRenderService.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.server.selectiontoolbar; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.os.IBinder; -import android.service.selectiontoolbar.ISelectionToolbarRenderService; -import android.service.selectiontoolbar.SelectionToolbarRenderService; -import android.util.Slog; -import android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.ShowInfo; - -import com.android.internal.infra.AbstractRemoteService; -import com.android.internal.infra.ServiceConnector; - -final class RemoteSelectionToolbarRenderService extends - ServiceConnector.Impl<ISelectionToolbarRenderService> { - private static final String TAG = "RemoteSelectionToolbarRenderService"; - - private static final long TIMEOUT_IDLE_UNBIND_MS = - AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS; - - private final ComponentName mComponentName; - private final IBinder mRemoteCallback; - - RemoteSelectionToolbarRenderService(Context context, ComponentName serviceName, int userId, - IBinder callback) { - super(context, new Intent(SelectionToolbarRenderService.SERVICE_INTERFACE).setComponent( - serviceName), 0, userId, ISelectionToolbarRenderService.Stub::asInterface); - mComponentName = serviceName; - mRemoteCallback = callback; - // Bind right away. - connect(); - } - - @Override // from AbstractRemoteService - protected long getAutoDisconnectTimeoutMs() { - return TIMEOUT_IDLE_UNBIND_MS; - } - - @Override // from ServiceConnector.Impl - protected void onServiceConnectionStatusChanged(ISelectionToolbarRenderService service, - boolean connected) { - try { - if (connected) { - service.onConnected(mRemoteCallback); - } - } catch (Exception e) { - Slog.w(TAG, "Exception calling onConnected().", e); - } - } - - public ComponentName getComponentName() { - return mComponentName; - } - - public void onShow(int callingUid, ShowInfo showInfo, ISelectionToolbarCallback callback) { - run((s) -> s.onShow(callingUid, showInfo, callback)); - } - - public void onHide(long widgetToken) { - run((s) -> s.onHide(widgetToken)); - } - - public void onDismiss(int callingUid, long widgetToken) { - run((s) -> s.onDismiss(callingUid, widgetToken)); - } -} diff --git a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarManagerService.java b/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarManagerService.java deleted file mode 100644 index 3bdf55ccb5c8..000000000000 --- a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarManagerService.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.server.selectiontoolbar; - -import android.content.Context; -import android.util.Slog; -import android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.ISelectionToolbarManager; -import android.view.selectiontoolbar.ShowInfo; - -import com.android.internal.util.DumpUtils; -import com.android.server.infra.AbstractMasterSystemService; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -/** - * Entry point service for selection toolbar management. - */ -public final class SelectionToolbarManagerService extends - AbstractMasterSystemService<SelectionToolbarManagerService, - SelectionToolbarManagerServiceImpl> { - - private static final String TAG = "SelectionToolbarManagerService"; - - @Override - public void onStart() { - publishBinderService(Context.SELECTION_TOOLBAR_SERVICE, - new SelectionToolbarManagerService.SelectionToolbarManagerServiceStub()); - } - - public SelectionToolbarManagerService(Context context) { - super(context, new SelectionToolbarServiceNameResolver(), /* disallowProperty= */ - null, PACKAGE_UPDATE_POLICY_REFRESH_EAGER); - } - - @Override - protected SelectionToolbarManagerServiceImpl newServiceLocked(int resolvedUserId, - boolean disabled) { - return new SelectionToolbarManagerServiceImpl(this, mLock, resolvedUserId); - } - - final class SelectionToolbarManagerServiceStub extends ISelectionToolbarManager.Stub { - - @Override - public void showToolbar(ShowInfo showInfo, ISelectionToolbarCallback callback, int userId) { - synchronized (mLock) { - SelectionToolbarManagerServiceImpl service = getServiceForUserLocked(userId); - if (service != null) { - service.showToolbar(showInfo, callback); - } else { - Slog.v(TAG, "showToolbar(): no service for " + userId); - } - } - } - - @Override - public void hideToolbar(long widgetToken, int userId) { - synchronized (mLock) { - SelectionToolbarManagerServiceImpl service = getServiceForUserLocked(userId); - if (service != null) { - service.hideToolbar(widgetToken); - } else { - Slog.v(TAG, "hideToolbar(): no service for " + userId); - } - } - } - - @Override - public void dismissToolbar(long widgetToken, int userId) { - synchronized (mLock) { - SelectionToolbarManagerServiceImpl service = getServiceForUserLocked(userId); - if (service != null) { - service.dismissToolbar(widgetToken); - } else { - Slog.v(TAG, "dismissToolbar(): no service for " + userId); - } - } - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; - - synchronized (mLock) { - dumpLocked("", pw); - } - } - } -} diff --git a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarManagerServiceImpl.java b/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarManagerServiceImpl.java deleted file mode 100644 index c8d153ad37a5..000000000000 --- a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarManagerServiceImpl.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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.server.selectiontoolbar; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.app.AppGlobals; -import android.content.ComponentName; -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.os.Binder; -import android.os.IBinder; -import android.os.RemoteException; -import android.service.selectiontoolbar.ISelectionToolbarRenderServiceCallback; -import android.util.Slog; -import android.view.selectiontoolbar.ISelectionToolbarCallback; -import android.view.selectiontoolbar.ShowInfo; - -import com.android.internal.annotations.GuardedBy; -import com.android.server.LocalServices; -import com.android.server.infra.AbstractPerUserSystemService; -import com.android.server.input.InputManagerInternal; - -final class SelectionToolbarManagerServiceImpl extends - AbstractPerUserSystemService<SelectionToolbarManagerServiceImpl, - SelectionToolbarManagerService> { - - private static final String TAG = "SelectionToolbarManagerServiceImpl"; - - @GuardedBy("mLock") - @Nullable - private RemoteSelectionToolbarRenderService mRemoteService; - - InputManagerInternal mInputManagerInternal; - private final SelectionToolbarRenderServiceRemoteCallback mRemoteServiceCallback = - new SelectionToolbarRenderServiceRemoteCallback(); - - protected SelectionToolbarManagerServiceImpl(@NonNull SelectionToolbarManagerService master, - @NonNull Object lock, int userId) { - super(master, lock, userId); - mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); - updateRemoteServiceLocked(); - } - - @GuardedBy("mLock") - @Override // from PerUserSystemService - protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) - throws PackageManager.NameNotFoundException { - return getServiceInfoOrThrow(serviceComponent, mUserId); - } - - @GuardedBy("mLock") - @Override // from PerUserSystemService - protected boolean updateLocked(boolean disabled) { - final boolean enabledChanged = super.updateLocked(disabled); - updateRemoteServiceLocked(); - return enabledChanged; - } - - /** - * Updates the reference to the remote service. - */ - @GuardedBy("mLock") - private void updateRemoteServiceLocked() { - if (mRemoteService != null) { - Slog.d(TAG, "updateRemoteService(): destroying old remote service"); - mRemoteService.unbind(); - mRemoteService = null; - } - } - - @GuardedBy("mLock") - void showToolbar(ShowInfo showInfo, ISelectionToolbarCallback callback) { - final RemoteSelectionToolbarRenderService remoteService = ensureRemoteServiceLocked(); - if (remoteService != null) { - remoteService.onShow(Binder.getCallingUid(), showInfo, callback); - } - } - - @GuardedBy("mLock") - void hideToolbar(long widgetToken) { - final RemoteSelectionToolbarRenderService remoteService = ensureRemoteServiceLocked(); - if (remoteService != null) { - remoteService.onHide(widgetToken); - } - } - - @GuardedBy("mLock") - void dismissToolbar(long widgetToken) { - final RemoteSelectionToolbarRenderService remoteService = ensureRemoteServiceLocked(); - if (remoteService != null) { - remoteService.onDismiss(Binder.getCallingUid(), widgetToken); - } - } - - @GuardedBy("mLock") - @Nullable - private RemoteSelectionToolbarRenderService ensureRemoteServiceLocked() { - if (mRemoteService == null) { - final String serviceName = getComponentNameLocked(); - final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); - mRemoteService = new RemoteSelectionToolbarRenderService(getContext(), serviceComponent, - mUserId, mRemoteServiceCallback); - } - return mRemoteService; - } - - private static ServiceInfo getServiceInfoOrThrow(ComponentName comp, @UserIdInt int userId) - throws PackageManager.NameNotFoundException { - int flags = PackageManager.GET_META_DATA; - - ServiceInfo si = null; - try { - si = AppGlobals.getPackageManager().getServiceInfo(comp, flags, userId); - } catch (RemoteException e) { - } - if (si == null) { - throw new PackageManager.NameNotFoundException("Could not get serviceInfo for " - + comp.flattenToShortString()); - } - return si; - } - - private void transferTouchFocus(IBinder source, IBinder target) { - mInputManagerInternal.transferTouchFocus(source, target); - } - - private final class SelectionToolbarRenderServiceRemoteCallback extends - ISelectionToolbarRenderServiceCallback.Stub { - - @Override - public void transferTouch(IBinder source, IBinder target) { - transferTouchFocus(source, target); - } - } -} diff --git a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarServiceNameResolver.java b/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarServiceNameResolver.java deleted file mode 100644 index 99b0f25c0a4e..000000000000 --- a/services/selectiontoolbar/java/com/android/server/selectiontoolbar/SelectionToolbarServiceNameResolver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.server.selectiontoolbar; - -import android.service.selectiontoolbar.DefaultSelectionToolbarRenderService; - -import com.android.server.infra.ServiceNameResolver; - -import java.io.PrintWriter; - -final class SelectionToolbarServiceNameResolver implements ServiceNameResolver { - - // TODO: move to SysUi or ExtServices - private static final String SELECTION_TOOLBAR_SERVICE_NAME = - "android/" + DefaultSelectionToolbarRenderService.class.getName(); - - @Override - public String getDefaultServiceName(int userId) { - return SELECTION_TOOLBAR_SERVICE_NAME; - } - - @Override - public void dumpShort(PrintWriter pw) { - pw.print("service="); pw.print(SELECTION_TOOLBAR_SERVICE_NAME); - } - - @Override - public void dumpShort(PrintWriter pw, int userId) { - pw.print("defaultService="); pw.print(getDefaultServiceName(userId)); - } -} |