/* * 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 com.example.android.sampleinputmethodaccessibilityservice; import android.content.Context; import android.graphics.PixelFormat; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; final class OverlayWindowBuilder { @NonNull private final View mContentView; private int mWidth = WindowManager.LayoutParams.WRAP_CONTENT; private int mHeight = WindowManager.LayoutParams.WRAP_CONTENT; private int mGravity = Gravity.NO_GRAVITY; private int mRelX = 0; private int mRelY = 0; private Integer mBackgroundColor = null; private boolean mShown = false; private OverlayWindowBuilder(@NonNull View contentView) { mContentView = contentView; } static OverlayWindowBuilder from(@NonNull View contentView) { return new OverlayWindowBuilder(contentView); } OverlayWindowBuilder setSize(int width, int height) { mWidth = width; mHeight = height; return this; } OverlayWindowBuilder setGravity(int gravity) { mGravity = gravity; return this; } OverlayWindowBuilder setRelativePosition(int relX, int relY) { mRelX = relX; mRelY = relY; return this; } OverlayWindowBuilder setBackgroundColor(@ColorInt int color) { mBackgroundColor = color; return this; } void show() { if (mShown) { throw new UnsupportedOperationException("show() can be called only once."); } final Context context = mContentView.getContext(); final WindowManager windowManager = context.getSystemService(WindowManager.class); final FrameLayout contentFrame = new FrameLayout(context) { @Override public boolean requestSendAccessibilityEvent(View view, AccessibilityEvent event) { return false; } @Override public void sendAccessibilityEventUnchecked(AccessibilityEvent event) { } }; if (mBackgroundColor != null) { contentFrame.setBackgroundColor(mBackgroundColor); } contentFrame.setOnTouchListener(new DragToMoveTouchListener((dx, dy) -> { final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) contentFrame.getLayoutParams(); lp.x += dx; lp.y += dy; windowManager.updateViewLayout(contentFrame, lp); })); contentFrame.addView(mContentView); final WindowManager.LayoutParams params = new WindowManager.LayoutParams( mWidth, mHeight, WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = mGravity; params.x = mRelX; params.y = mRelY; windowManager.addView(contentFrame, params); mShown = true; } }