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

Commit 722f9dea authored by Garfield Tan's avatar Garfield Tan
Browse files

Use new create/removeInputChannel().

This way we can restrict server channel in InputFlinger.

Also always use std::move() to move ownership when creating Java object
for InputChannel.

Bug: 167947395
Test: Touch events are still dispatched.
Test: WmTests:DisplayPolicyTests#testUpdateHideNavInputEventReceiver
Change-Id: I7033caf1015ec4bae65beab2c65bdeb4070f4775
parent bea4e46f
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public final class InputChannel implements Parcelable {
     *
     *  @hide
     */
    public void setNativeInputChannel(long nativeChannel) {
    private void setNativeInputChannel(long nativeChannel) {
        if (nativeChannel == 0) {
            throw new IllegalArgumentException("Attempting to set native input channel to null.");
        }
@@ -148,12 +148,11 @@ public final class InputChannel implements Parcelable {
    }

    /**
     * Transfers ownership of the internal state of the input channel to another
     * instance and invalidates this instance.  This is used to pass an input channel
     * Creates a copy of this instance to the outParameter. This is used to pass an input channel
     * as an out parameter in a binder call.
     * @param other The other input channel instance.
     */
    public void transferTo(InputChannel outParameter) {
    public void copyTo(InputChannel outParameter) {
        if (outParameter == null) {
            throw new IllegalArgumentException("outParameter must not be null");
        }
+38 −9
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ namespace android {
static struct {
    jclass clazz;

    jmethodID mCtor;
    jmethodID mSetNativeInputChannel;

    jfieldID mPtr;   // native object attached to the DVM InputChannel
} gInputChannelClassInfo;

@@ -43,7 +46,7 @@ static struct {

class NativeInputChannel {
public:
    explicit NativeInputChannel(const std::shared_ptr<InputChannel>& inputChannel);
    explicit NativeInputChannel(std::unique_ptr<InputChannel> inputChannel);
    ~NativeInputChannel();

    inline std::shared_ptr<InputChannel> getInputChannel() { return mInputChannel; }
@@ -59,8 +62,8 @@ private:

// ----------------------------------------------------------------------------

NativeInputChannel::NativeInputChannel(const std::shared_ptr<InputChannel>& inputChannel)
      : mInputChannel(inputChannel), mDisposeCallback(nullptr) {}
NativeInputChannel::NativeInputChannel(std::unique_ptr<InputChannel> inputChannel)
      : mInputChannel(std::move(inputChannel)), mDisposeCallback(nullptr) {}

NativeInputChannel::~NativeInputChannel() {
}
@@ -110,13 +113,33 @@ void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChan
}

static jlong android_view_InputChannel_createInputChannel(
        JNIEnv* env, std::shared_ptr<InputChannel> inputChannel) {
        JNIEnv* env, std::unique_ptr<InputChannel> inputChannel) {
    std::unique_ptr<NativeInputChannel> nativeInputChannel =
            std::make_unique<NativeInputChannel>(inputChannel);
            std::make_unique<NativeInputChannel>(std::move(inputChannel));

    return reinterpret_cast<jlong>(nativeInputChannel.release());
}

jobject android_view_InputChannel_createJavaObject(JNIEnv* env,
                                                   std::unique_ptr<InputChannel> inputChannel) {
    std::string name = inputChannel->getName();
    jlong ptr = android_view_InputChannel_createInputChannel(env, std::move(inputChannel));
    jobject javaInputChannel =
            env->NewObject(gInputChannelClassInfo.clazz, gInputChannelClassInfo.mCtor);
    if (!javaInputChannel) {
        ALOGE("Failed to create a Java InputChannel for channel %s.", name.c_str());
        return nullptr;
    }

    env->CallVoidMethod(javaInputChannel, gInputChannelClassInfo.mSetNativeInputChannel, ptr);
    if (env->ExceptionOccurred()) {
        ALOGE("Failed to set native ptr to the Java InputChannel for channel %s.",
              inputChannel->getName().c_str());
        return nullptr;
    }
    return javaInputChannel;
}

static jlongArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env,
        jclass clazz, jstring nameObj) {
    ScopedUtfChars nameChars(env, nameObj);
@@ -180,9 +203,10 @@ static jlong android_view_InputChannel_nativeReadFromParcel(JNIEnv* env, jobject
    if (parcel) {
        bool isInitialized = parcel->readInt32();
        if (isInitialized) {
            std::shared_ptr<InputChannel> inputChannel = std::make_shared<InputChannel>();
            std::unique_ptr<InputChannel> inputChannel = std::make_unique<InputChannel>();
            inputChannel->readFromParcel(parcel);
            NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel);
            NativeInputChannel* nativeInputChannel =
                    new NativeInputChannel(std::move(inputChannel));
            return reinterpret_cast<jlong>(nativeInputChannel);
        }
    }
@@ -233,13 +257,13 @@ static jlong android_view_InputChannel_nativeDup(JNIEnv* env, jobject obj, jlong
        return 0;
    }

    std::shared_ptr<InputChannel> dupInputChannel = inputChannel->dup();
    std::unique_ptr<InputChannel> dupInputChannel = inputChannel->dup();
    if (dupInputChannel == nullptr) {
        std::string message = android::base::StringPrintf(
                "Could not duplicate input channel %s", inputChannel->getName().c_str());
        jniThrowRuntimeException(env, message.c_str());
    }
    return reinterpret_cast<jlong>(new NativeInputChannel(dupInputChannel));
    return reinterpret_cast<jlong>(new NativeInputChannel(std::move(dupInputChannel)));
}

static jobject android_view_InputChannel_nativeGetToken(JNIEnv* env, jobject obj, jlong channel) {
@@ -281,6 +305,11 @@ int register_android_view_InputChannel(JNIEnv* env) {
    jclass clazz = FindClassOrDie(env, "android/view/InputChannel");
    gInputChannelClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);

    gInputChannelClassInfo.mCtor =
            GetMethodIDOrDie(env, gInputChannelClassInfo.clazz, "<init>", "()V");
    gInputChannelClassInfo.mSetNativeInputChannel =
            GetMethodIDOrDie(env, gInputChannelClassInfo.clazz, "setNativeInputChannel", "(J)V");

    gInputChannelClassInfo.mPtr = GetFieldIDOrDie(env, gInputChannelClassInfo.clazz, "mPtr", "J");

    return res;
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ extern std::shared_ptr<InputChannel> android_view_InputChannel_getInputChannel(
extern void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj,
        InputChannelObjDisposeCallback callback, void* data = NULL);

extern jobject android_view_InputChannel_createJavaObject(
        JNIEnv* env, std::unique_ptr<InputChannel> inputChannel);
} // namespace android

#endif // _ANDROID_OS_INPUTCHANNEL_H
+19 −27
Original line number Diff line number Diff line
@@ -219,10 +219,10 @@ public class InputManagerService extends IInputManager.Stub
            int deviceId, int sourceMask, int sw);
    private static native boolean nativeHasKeys(long ptr,
            int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
    private static native void nativeRegisterInputChannel(long ptr, InputChannel inputChannel);
    private static native void nativeRegisterInputMonitor(long ptr, InputChannel inputChannel,
            int displayId, boolean isGestureMonitor);
    private static native void nativeUnregisterInputChannel(long ptr, IBinder connectionToken);
    private static native InputChannel nativeCreateInputChannel(long ptr, String name);
    private static native InputChannel nativeCreateInputMonitor(long ptr, int displayId,
            boolean isGestureMonitor, String name);
    private static native void nativeRemoveInputChannel(long ptr, IBinder connectionToken);
    private static native void nativePilferPointers(long ptr, IBinder token);
    private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
    private static native void nativeSetInTouchMode(long ptr, boolean inTouchMode);
@@ -522,10 +522,8 @@ public class InputManagerService extends IInputManager.Stub
            throw new IllegalArgumentException("displayId must >= 0.");
        }

        InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
        nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId, false /*isGestureMonitor*/);
        inputChannels[0].dispose(); // don't need to retain the Java object reference
        return inputChannels[1];
        return nativeCreateInputMonitor(mPtr, displayId, false /* isGestureMonitor */,
                inputChannelName);
    }

    /**
@@ -552,38 +550,32 @@ public class InputManagerService extends IInputManager.Stub

        final long ident = Binder.clearCallingIdentity();
        try {
            InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
            InputMonitorHost host = new InputMonitorHost(inputChannels[0]);
            nativeRegisterInputMonitor(
                    mPtr, inputChannels[0], displayId, true /*isGestureMonitor*/);
            InputChannel inputChannel = nativeCreateInputMonitor(
                    mPtr, displayId, true /*isGestureMonitor*/, inputChannelName);
            InputMonitorHost host = new InputMonitorHost(inputChannel);
            synchronized (mGestureMonitorPidsLock) {
                mGestureMonitorPidsByToken.put(inputChannels[1].getToken(), pid);
                mGestureMonitorPidsByToken.put(inputChannel.getToken(), pid);
            }
            return new InputMonitor(inputChannels[1], host);
            return new InputMonitor(inputChannel, host);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    /**
     * Registers an input channel so that it can be used as an input event target. The channel is
     * registered with a generated token.
     * Creates an input channel to be used as an input event target.
     *
     * @param inputChannel The input channel to register.
     * @param name The name of this input channel
     */
    public void registerInputChannel(InputChannel inputChannel) {
        if (inputChannel == null) {
            throw new IllegalArgumentException("inputChannel must not be null.");
        }

        nativeRegisterInputChannel(mPtr, inputChannel);
    public InputChannel createInputChannel(String name) {
        return nativeCreateInputChannel(mPtr, name);
    }

    /**
     * Unregisters an input channel.
     * Removes an input channel.
     * @param connectionToken The input channel to unregister.
     */
    public void unregisterInputChannel(IBinder connectionToken) {
    public void removeInputChannel(IBinder connectionToken) {
        if (connectionToken == null) {
            throw new IllegalArgumentException("connectionToken must not be null.");
        }
@@ -591,7 +583,7 @@ public class InputManagerService extends IInputManager.Stub
            mGestureMonitorPidsByToken.remove(connectionToken);
        }

        nativeUnregisterInputChannel(mPtr, connectionToken);
        nativeRemoveInputChannel(mPtr, connectionToken);
    }

    /**
@@ -2455,7 +2447,7 @@ public class InputManagerService extends IInputManager.Stub

        @Override
        public void dispose() {
            nativeUnregisterInputChannel(mPtr, mInputChannel.getToken());
            nativeRemoveInputChannel(mPtr, mInputChannel.getToken());
            mInputChannel.dispose();
        }
    }
+5 −10
Original line number Diff line number Diff line
@@ -258,16 +258,13 @@ class DragState {
    }

    class InputInterceptor {
        InputChannel mServerChannel, mClientChannel;
        InputChannel mClientChannel;
        DragInputEventReceiver mInputEventReceiver;
        InputApplicationHandle mDragApplicationHandle;
        InputWindowHandle mDragWindowHandle;

        InputInterceptor(Display display) {
            InputChannel[] channels = InputChannel.openInputChannelPair("drag");
            mServerChannel = channels[0];
            mClientChannel = channels[1];
            mService.mInputManager.registerInputChannel(mServerChannel);
            mClientChannel = mService.mInputManager.createInputChannel("drag");
            mInputEventReceiver = new DragInputEventReceiver(mClientChannel,
                    mService.mH.getLooper(), mDragDropController);

@@ -278,7 +275,7 @@ class DragState {
            mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle,
                    display.getDisplayId());
            mDragWindowHandle.name = "drag";
            mDragWindowHandle.token = mServerChannel.getToken();
            mDragWindowHandle.token = mClientChannel.getToken();
            mDragWindowHandle.layoutParamsFlags = 0;
            mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
            mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -308,13 +305,11 @@ class DragState {
        }

        void tearDown() {
            mService.mInputManager.unregisterInputChannel(mServerChannel.getToken());
            mService.mInputManager.removeInputChannel(mClientChannel.getToken());
            mInputEventReceiver.dispose();
            mInputEventReceiver = null;
            mClientChannel.dispose();
            mServerChannel.dispose();
            mClientChannel = null;
            mServerChannel = null;

            mDragWindowHandle = null;
            mDragApplicationHandle = null;
@@ -326,7 +321,7 @@ class DragState {
    }

    InputChannel getInputChannel() {
        return mInputInterceptor == null ? null : mInputInterceptor.mServerChannel;
        return mInputInterceptor == null ? null : mInputInterceptor.mClientChannel;
    }

    InputWindowHandle getInputWindowHandle() {
Loading