blob: abc5667251ea413f4e47979baf6114094ac02aae [file] [log] [blame]
/*
* Copyright (C) 2017 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.systemui.pip.phone;
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.BatchedInputEventReceiver;
import android.view.Choreographer;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.IWindowManager;
import android.view.MotionEvent;
import com.android.systemui.recents.misc.Utilities;
import java.io.PrintWriter;
/**
* Manages the input consumer that allows the SystemUI to control the PiP.
*/
public class InputConsumerController {
private static final String TAG = InputConsumerController.class.getSimpleName();
/**
* Listener interface for callers to subscribe to touch events.
*/
public interface TouchListener {
boolean onTouchEvent(MotionEvent ev);
}
/**
* Listener interface for callers to learn when this class is registered or unregistered with
* window manager
*/
public interface RegistrationListener {
void onRegistrationChanged(boolean isRegistered);
}
/**
* Input handler used for the PiP input consumer. Input events are batched and consumed with the
* SurfaceFlinger vsync.
*/
private final class PipInputEventReceiver extends BatchedInputEventReceiver {
public PipInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper, Choreographer.getSfInstance());
}
@Override
public void onInputEvent(InputEvent event, int displayId) {
boolean handled = true;
try {
// To be implemented for input handling over Pip windows
if (mListener != null && event instanceof MotionEvent) {
MotionEvent ev = (MotionEvent) event;
handled = mListener.onTouchEvent(ev);
}
} finally {
finishInputEvent(event, handled);
}
}
}
private IWindowManager mWindowManager;
private PipInputEventReceiver mInputEventReceiver;
private TouchListener mListener;
private RegistrationListener mRegistrationListener;
public InputConsumerController(IWindowManager windowManager) {
mWindowManager = windowManager;
registerInputConsumer();
}
/**
* Sets the touch listener.
*/
public void setTouchListener(TouchListener listener) {
mListener = listener;
}
/**
* Sets the registration listener.
*/
public void setRegistrationListener(RegistrationListener listener) {
mRegistrationListener = listener;
if (mRegistrationListener != null) {
mRegistrationListener.onRegistrationChanged(mInputEventReceiver != null);
}
}
/**
* Check if the InputConsumer is currently registered with WindowManager
*
* @return {@code true} if registered, {@code false} if not.
*/
public boolean isRegistered() {
return mInputEventReceiver != null;
}
/**
* Registers the input consumer.
*/
public void registerInputConsumer() {
if (mInputEventReceiver == null) {
final InputChannel inputChannel = new InputChannel();
try {
mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
mWindowManager.createInputConsumer(INPUT_CONSUMER_PIP, inputChannel);
} catch (RemoteException e) {
Log.e(TAG, "Failed to create PIP input consumer", e);
}
mInputEventReceiver = new PipInputEventReceiver(inputChannel, Looper.myLooper());
if (mRegistrationListener != null) {
mRegistrationListener.onRegistrationChanged(true /* isRegistered */);
}
}
}
/**
* Unregisters the input consumer.
*/
public void unregisterInputConsumer() {
if (mInputEventReceiver != null) {
try {
mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
} catch (RemoteException e) {
Log.e(TAG, "Failed to destroy PIP input consumer", e);
}
mInputEventReceiver.dispose();
mInputEventReceiver = null;
if (mRegistrationListener != null) {
mRegistrationListener.onRegistrationChanged(false /* isRegistered */);
}
}
}
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
pw.println(innerPrefix + "registered=" + (mInputEventReceiver != null));
}
}