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

Commit fa9e7c05 authored by Christopher Tate's avatar Christopher Tate
Browse files

Sketch of Native input for MessageQueue / Looper / ViewRoot

MessageQueue now uses a socket for internal signalling, and is prepared
to also handle any number of event input pipes, once the plumbing is
set up with ViewRoot / Looper to tell it about them as appropriate.

Change-Id: If9eda174a6c26887dc51b12b14b390e724e73ab3
parent ab4f3c60
Loading
Loading
Loading
Loading
+45 −15
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ public class MessageQueue {
    Message mMessages;
    private final ArrayList mIdleHandlers = new ArrayList();
    private boolean mQuiting = false;
    private int mObject = 0;    // used by native code
    boolean mQuitAllowed = true;

    /**
@@ -85,16 +86,49 @@ public class MessageQueue {
        }
    }

    // Add an input pipe to the set being selected over.  If token is
    // negative, remove 'handler's entry from the current set and forget
    // about it.
    void setInputToken(int token, int region, Handler handler) {
        if (token >= 0) nativeRegisterInputStream(token, region, handler);
        else nativeUnregisterInputStream(token);
    }

    MessageQueue() {
        nativeInit();
    }
    private native void nativeInit();

    /**
     * @param token fd of the readable end of the input stream
     * @param region fd of the ashmem region used for data transport alongside the 'token' fd
     * @param handler Handler from which to make input messages based on data read from the fd
     */
    private native void nativeRegisterInputStream(int token, int region, Handler handler);
    private native void nativeUnregisterInputStream(int token);
    private native void nativeSignal();

    /**
     * Wait until the designated time for new messages to arrive.
     *
     * @param when Timestamp in SystemClock.uptimeMillis() base of the next message in the queue.
     *    If 'when' is zero, the method will check for incoming messages without blocking.  If
     *    'when' is negative, the method will block forever waiting for the next message.
     * @return
     */
    private native int nativeWaitForNext(long when);

    final Message next() {
        boolean tryIdle = true;
        // when we start out, we'll just touch the input pipes and then go from there
        long timeToNextEventMillis = 0;

        while (true) {
            long now;
            Object[] idlers = null;

            nativeWaitForNext(timeToNextEventMillis);

            // Try to retrieve the next message, returning if found.
            synchronized (this) {
                now = SystemClock.uptimeMillis();
@@ -135,20 +169,17 @@ public class MessageQueue {

            synchronized (this) {
                // No messages, nobody to tell about it...  time to wait!
                try {
                if (mMessages != null) {
                    if (mMessages.when - now > 0) {
                        Binder.flushPendingCommands();
                            this.wait(mMessages.when-now);
                        timeToNextEventMillis = mMessages.when - now;
                    }
                } else {
                    Binder.flushPendingCommands();
                        this.wait();
                    }
                }
                catch (InterruptedException e) {
                    timeToNextEventMillis = -1;
                }
            }
            // loop to the while(true) and do the appropriate nativeWait(when)
        }
    }

@@ -190,7 +221,6 @@ public class MessageQueue {
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;
                mMessages = msg;
                this.notify();
            } else {
                Message prev = null;
                while (p != null && p.when <= when) {
@@ -199,8 +229,8 @@ public class MessageQueue {
                }
                msg.next = prev.next;
                prev.next = msg;
                this.notify();
            }
            nativeSignal();
        }
        return true;
    }
@@ -321,7 +351,7 @@ public class MessageQueue {
    void poke()
    {
        synchronized (this) {
            this.notify();
            nativeSignal();
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ public class ParcelFileDescriptor implements Parcelable {
    /**
     * An InputStream you can create on a ParcelFileDescriptor, which will
     * take care of calling {@link ParcelFileDescriptor#close
     * ParcelFileDescritor.close()} for you when the stream is closed.
     * ParcelFileDescriptor.close()} for you when the stream is closed.
     */
    public static class AutoCloseInputStream extends FileInputStream {
        private final ParcelFileDescriptor mFd;
@@ -198,7 +198,7 @@ public class ParcelFileDescriptor implements Parcelable {
    /**
     * An OutputStream you can create on a ParcelFileDescriptor, which will
     * take care of calling {@link ParcelFileDescriptor#close
     * ParcelFileDescritor.close()} for you when the stream is closed.
     * ParcelFileDescriptor.close()} for you when the stream is closed.
     */
    public static class AutoCloseOutputStream extends FileOutputStream {
        private final ParcelFileDescriptor mFd;
+14 −1
Original line number Diff line number Diff line
@@ -26,12 +26,12 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.*;
import android.os.Process;
import android.os.SystemProperties;
import android.util.AndroidRuntimeException;
import android.util.Config;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
@@ -50,6 +50,7 @@ import android.Manifest;
import android.media.AudioManager;

import java.lang.ref.WeakReference;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@@ -76,6 +77,7 @@ public final class ViewRoot extends Handler implements ViewParent,
    /** @noinspection PointlessBooleanExpression*/
    private static final boolean DEBUG_DRAW = false || LOCAL_LOGV;
    private static final boolean DEBUG_LAYOUT = false || LOCAL_LOGV;
    private static final boolean DEBUG_INPUT = true || LOCAL_LOGV;
    private static final boolean DEBUG_INPUT_RESIZE = false || LOCAL_LOGV;
    private static final boolean DEBUG_ORIENTATION = false || LOCAL_LOGV;
    private static final boolean DEBUG_TRACKBALL = false || LOCAL_LOGV;
@@ -425,6 +427,9 @@ public final class ViewRoot extends Handler implements ViewParent,
        }
    }

    // fd [0] is the receiver, [1] is the sender
    private native int[] makeInputChannel();

    /**
     * We have one child
     */
@@ -469,6 +474,14 @@ public final class ViewRoot extends Handler implements ViewParent,
                mAdded = true;
                int res; /* = WindowManagerImpl.ADD_OKAY; */

                // Set up the input event channel
                if (false) {
                int[] fds = makeInputChannel();
                if (DEBUG_INPUT) {
                    Log.v(TAG, "makeInputChannel() returned " + fds);
                }
                }

                // Schedule the first layout -before- adding to the window
                // manager, to make sure we do the relayout before receiving
                // any other events from the system.
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ LOCAL_SRC_FILES:= \
	android_os_Debug.cpp \
	android_os_FileUtils.cpp \
	android_os_MemoryFile.cpp \
	android_os_MessageQueue.cpp \
	android_os_ParcelFileDescriptor.cpp \
	android_os_Power.cpp \
	android_os_StatFs.cpp \
+2 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ extern int register_android_nio_utils(JNIEnv* env);
extern int register_android_pim_EventRecurrence(JNIEnv* env);
extern int register_android_text_format_Time(JNIEnv* env);
extern int register_android_os_Debug(JNIEnv* env);
extern int register_android_os_MessageQueue(JNIEnv* env);
extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
extern int register_android_os_Power(JNIEnv *env);
extern int register_android_os_StatFs(JNIEnv *env);
@@ -1249,6 +1250,7 @@ static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_android_os_Debug),
    REG_JNI(register_android_os_FileObserver),
    REG_JNI(register_android_os_FileUtils),
    REG_JNI(register_android_os_MessageQueue),
    REG_JNI(register_android_os_ParcelFileDescriptor),
    REG_JNI(register_android_os_Power),
    REG_JNI(register_android_os_StatFs),
Loading