| /* |
| * 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; |
| } |
| } |