Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51b45930 authored by Leonardo Blanger's avatar Leonardo Blanger Committed by Android (Google) Code Review
Browse files

Merge "Expose listener interface for display IME changes" into main

parents 65ef41fb 09c8bd30
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -846,8 +846,10 @@ public abstract class WMShellBaseModule {
    static ShellController provideShellController(Context context,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
            DisplayInsetsController displayInsetsController,
            @ShellMainThread ShellExecutor mainExecutor) {
        return new ShellController(context, shellInit, shellCommandHandler, mainExecutor);
        return new ShellController(context, shellInit, shellCommandHandler,
                displayInsetsController, mainExecutor);
    }

    //
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.wm.shell.sysui;

import android.graphics.Rect;

/**
 * Callbacks for when the Display IME changes.
 */
public interface DisplayImeChangeListener {
    /**
     * Called when the ime bounds change.
     */
    default void onImeBoundsChanged(int displayId, Rect bounds) {}

    /**
     * Called when the IME visibility change.
     */
    default void onImeVisibilityChanged(int displayId, boolean isShowing) {}
}
+75 −0
Original line number Diff line number Diff line
@@ -30,21 +30,28 @@ import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.ArrayMap;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.SurfaceControlRegistry;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ExternalThread;

import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

/**
@@ -57,6 +64,7 @@ public class ShellController {
    private final ShellInit mShellInit;
    private final ShellCommandHandler mShellCommandHandler;
    private final ShellExecutor mMainExecutor;
    private final DisplayInsetsController mDisplayInsetsController;
    private final ShellInterfaceImpl mImpl = new ShellInterfaceImpl();

    private final CopyOnWriteArrayList<ConfigurationChangeListener> mConfigChangeListeners =
@@ -65,6 +73,8 @@ public class ShellController {
            new CopyOnWriteArrayList<>();
    private final CopyOnWriteArrayList<UserChangeListener> mUserChangeListeners =
            new CopyOnWriteArrayList<>();
    private final ConcurrentHashMap<DisplayImeChangeListener, Executor> mDisplayImeChangeListeners =
            new ConcurrentHashMap<>();

    private ArrayMap<String, Supplier<ExternalInterfaceBinder>> mExternalInterfaceSuppliers =
            new ArrayMap<>();
@@ -73,20 +83,53 @@ public class ShellController {

    private Configuration mLastConfiguration;

    private OnInsetsChangedListener mInsetsChangeListener = new OnInsetsChangedListener() {
        private InsetsState mInsetsState = new InsetsState();

        @Override
        public void insetsChanged(InsetsState insetsState) {
            if (mInsetsState == insetsState) {
                return;
            }

            InsetsSource oldSource = mInsetsState.peekSource(InsetsSource.ID_IME);
            boolean wasVisible = (oldSource != null && oldSource.isVisible());
            Rect oldFrame = wasVisible ? oldSource.getFrame() : null;

            InsetsSource newSource = insetsState.peekSource(InsetsSource.ID_IME);
            boolean isVisible = (newSource != null && newSource.isVisible());
            Rect newFrame = isVisible ? newSource.getFrame() : null;

            if (wasVisible != isVisible) {
                onImeVisibilityChanged(isVisible);
            }

            if (newFrame != null && !newFrame.equals(oldFrame)) {
                onImeBoundsChanged(newFrame);
            }

            mInsetsState = insetsState;
        }
    };


    public ShellController(Context context,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
            DisplayInsetsController displayInsetsController,
            ShellExecutor mainExecutor) {
        mContext = context;
        mShellInit = shellInit;
        mShellCommandHandler = shellCommandHandler;
        mDisplayInsetsController = displayInsetsController;
        mMainExecutor = mainExecutor;
        shellInit.addInitCallback(this::onInit, this);
    }

    private void onInit() {
        mShellCommandHandler.addDumpCallback(this::dump, this);
        mDisplayInsetsController.addInsetsChangedListener(
                mContext.getDisplayId(), mInsetsChangeListener);
    }

    /**
@@ -259,6 +302,25 @@ public class ShellController {
        }
    }

    @VisibleForTesting
    void onImeBoundsChanged(Rect bounds) {
        ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "Display Ime bounds changed");
        mDisplayImeChangeListeners.forEach(
                (DisplayImeChangeListener listener, Executor executor) ->
                executor.execute(() -> listener.onImeBoundsChanged(
                    mContext.getDisplayId(), bounds)));
    }

    @VisibleForTesting
    void onImeVisibilityChanged(boolean isShowing) {
        ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "Display Ime visibility changed: isShowing=%b",
                isShowing);
        mDisplayImeChangeListeners.forEach(
                (DisplayImeChangeListener listener, Executor executor) ->
                executor.execute(() -> listener.onImeVisibilityChanged(
                    mContext.getDisplayId(), isShowing)));
    }

    private void handleInit() {
        SurfaceControlRegistry.createProcessInstance(mContext);
        mShellInit.init();
@@ -328,6 +390,19 @@ public class ShellController {
                    ShellController.this.onUserProfilesChanged(profiles));
        }

        @Override
        public void addDisplayImeChangeListener(DisplayImeChangeListener listener,
                Executor executor) {
            ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "Adding new DisplayImeChangeListener");
            mDisplayImeChangeListeners.put(listener, executor);
        }

        @Override
        public void removeDisplayImeChangeListener(DisplayImeChangeListener listener) {
            ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "Removing DisplayImeChangeListener");
            mDisplayImeChangeListeners.remove(listener);
        }

        @Override
        public boolean handleCommand(String[] args, PrintWriter pw) {
            try {
+13 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import androidx.annotation.NonNull;

import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * General interface for notifying the Shell of common SysUI events like configuration or keyguard
@@ -64,6 +65,18 @@ public interface ShellInterface {
     */
    default void onUserProfilesChanged(@NonNull List<UserInfo> profiles) {}

    /**
     * Registers a DisplayImeChangeListener to monitor for changes on Ime
     * position and visibility.
     */
    default void addDisplayImeChangeListener(DisplayImeChangeListener listener,
            Executor executor) {}

    /**
     * Removes a registered DisplayImeChangeListener.
     */
    default void removeDisplayImeChangeListener(DisplayImeChangeListener listener) {}

    /**
     * Handles a shell command.
     */
+3 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.wm.shell.WindowManagerShellWrapper
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView
import com.android.wm.shell.bubbles.properties.BubbleProperties
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayInsetsController
import com.android.wm.shell.common.FloatingContentCoordinator
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
@@ -94,7 +95,8 @@ class BubbleViewInfoTest : ShellTestCase() {
        val windowManager = context.getSystemService(WindowManager::class.java)
        val shellInit = ShellInit(mainExecutor)
        val shellCommandHandler = ShellCommandHandler()
        val shellController = ShellController(context, shellInit, shellCommandHandler, mainExecutor)
        val shellController = ShellController(context, shellInit, shellCommandHandler,
					      mock<DisplayInsetsController>(), mainExecutor)
        bubblePositioner = BubblePositioner(context, windowManager)
        val bubbleData =
            BubbleData(
Loading