/*
 * Copyright (C) 2013 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.
 */

#define LOG_TAG "Terminal"

#include <utils/Log.h>
#include <utils/Mutex.h>
#include "android_runtime/AndroidRuntime.h"

#include "forkpty.h"
#include "jni.h"
#include "JNIHelp.h"
#include "ScopedLocalRef.h"
#include "ScopedPrimitiveArray.h"

#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <util.h>
#include <utmp.h>

#include <vterm.h>

#include <string.h>

#define USE_TEST_SHELL 0
#define DEBUG_CALLBACKS 0
#define DEBUG_IO 0
#define DEBUG_SCROLLBACK 0

namespace android {

/*
 * Callback class reference
 */
static jclass terminalCallbacksClass;

/*
 * Callback methods
 */
static jmethodID damageMethod;
static jmethodID moveRectMethod;
static jmethodID moveCursorMethod;
static jmethodID setTermPropBooleanMethod;
static jmethodID setTermPropIntMethod;
static jmethodID setTermPropStringMethod;
static jmethodID setTermPropColorMethod;
static jmethodID bellMethod;

/*
 * CellRun class
 */
static jclass cellRunClass;
static jfieldID cellRunDataField;
static jfieldID cellRunDataSizeField;
static jfieldID cellRunColSizeField;
static jfieldID cellRunFgField;
static jfieldID cellRunBgField;

typedef short unsigned int dimen_t;

class ScrollbackLine {
public:
    inline ScrollbackLine(dimen_t _cols) : cols(_cols) {
        mCells = new VTermScreenCell[cols];
    };
    inline ~ScrollbackLine() {
        delete mCells;
    }

    inline dimen_t copyFrom(dimen_t cols, const VTermScreenCell* cells) {
        dimen_t n = this->cols > cols ? cols : this->cols;
        memcpy(mCells, cells, sizeof(VTermScreenCell) * n);
        return n;
    }

    inline dimen_t copyTo(dimen_t cols, VTermScreenCell* cells) {
        dimen_t n = cols > this->cols ? this->cols : cols;
        memcpy(cells, mCells, sizeof(VTermScreenCell) * n);
        return n;
    }

    inline void getCell(dimen_t col, VTermScreenCell* cell) {
        *cell = mCells[col];
    }

    const dimen_t cols;

private:
    VTermScreenCell* mCells;
};

/*
 * Terminal session
 */
class Terminal {
public:
    Terminal(jobject callbacks, dimen_t rows, dimen_t cols);
    ~Terminal();

    status_t run();

    size_t write(const char *bytes, size_t len);

    bool dispatchCharacter(int mod, int character);
    bool dispatchKey(int mod, int key);
    bool flushInput();

    status_t resize(dimen_t rows, dimen_t cols, dimen_t scrollRows);

    status_t onPushline(dimen_t cols, const VTermScreenCell* cells);
    status_t onPopline(dimen_t cols, VTermScreenCell* cells);

    void getCellLocked(VTermPos pos, VTermScreenCell* cell);

    dimen_t getRows() const;
    dimen_t getCols() const;
    dimen_t getScrollRows() const;

    jobject getCallbacks() const;

    // Lock protecting mutations of internal libvterm state
    Mutex mLock;

private:
    int mMasterFd;
    pid_t mChildPid;
    VTerm *mVt;
    VTermScreen *mVts;

    jobject mCallbacks;

    dimen_t mRows;
    dimen_t mCols;
    bool mKilled;

    ScrollbackLine **mScroll;
    dimen_t mScrollCur;
    dimen_t mScrollSize;

};

/*
 * VTerm event handlers
 */

static int term_damage(VTermRect rect, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_damage");
#endif

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    return env->CallIntMethod(term->getCallbacks(), damageMethod, rect.start_row, rect.end_row,
            rect.start_col, rect.end_col);
}

static int term_moverect(VTermRect dest, VTermRect src, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_moverect");
#endif

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    return env->CallIntMethod(term->getCallbacks(), moveRectMethod,
            dest.start_row, dest.end_row, dest.start_col, dest.end_col,
            src.start_row, src.end_row, src.start_col, src.end_col);
}

static int term_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_movecursor");
#endif

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    return env->CallIntMethod(term->getCallbacks(), moveCursorMethod, pos.row,
            pos.col, oldpos.row, oldpos.col, visible);
}

static int term_settermprop(VTermProp prop, VTermValue *val, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_settermprop");
#endif

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    switch (vterm_get_prop_type(prop)) {
    case VTERM_VALUETYPE_BOOL:
        return env->CallIntMethod(term->getCallbacks(), setTermPropBooleanMethod,
                static_cast<jboolean>(val->boolean));
    case VTERM_VALUETYPE_INT:
        return env->CallIntMethod(term->getCallbacks(), setTermPropIntMethod, prop, val->number);
    case VTERM_VALUETYPE_STRING:
        return env->CallIntMethod(term->getCallbacks(), setTermPropStringMethod, prop,
                env->NewStringUTF(val->string));
    case VTERM_VALUETYPE_COLOR:
        return env->CallIntMethod(term->getCallbacks(), setTermPropIntMethod, prop, val->color.red,
                val->color.green, val->color.blue);
    default:
        ALOGE("unknown callback type");
        return 0;
    }
}

static int term_setmousefunc(VTermMouseFunc func, void *data, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_setmousefunc");
#endif
    return 1;
}

static int term_bell(void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_bell");
#endif

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    return env->CallIntMethod(term->getCallbacks(), bellMethod);
}

static int term_sb_pushline(int cols, const VTermScreenCell *cells, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_sb_pushline");
#endif

    return term->onPushline(cols, cells);
}

static int term_sb_popline(int cols, VTermScreenCell *cells, void *user) {
    Terminal* term = reinterpret_cast<Terminal*>(user);
#if DEBUG_CALLBACKS
    ALOGW("term_sb_popline");
#endif

    return term->onPopline(cols, cells);
}

static VTermScreenCallbacks cb = {
    .damage = term_damage,
    .moverect = term_moverect,
    .movecursor = term_movecursor,
    .settermprop = term_settermprop,
    .setmousefunc = term_setmousefunc,
    .bell = term_bell,
    // Resize requests are applied immediately, so callback is ignored
    .resize = NULL,
    .sb_pushline = term_sb_pushline,
    .sb_popline = term_sb_popline,
};

Terminal::Terminal(jobject callbacks, dimen_t rows, dimen_t cols) :
        mCallbacks(callbacks), mRows(rows), mCols(cols), mKilled(false),
        mScrollCur(0), mScrollSize(100) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    mCallbacks = env->NewGlobalRef(callbacks);

    mScroll = new ScrollbackLine*[mScrollSize];
    memset(mScroll, 0, sizeof(ScrollbackLine*) * mScrollSize);

    /* Create VTerm */
    mVt = vterm_new(rows, cols);
    vterm_parser_set_utf8(mVt, 1);

    /* Set up screen */
    mVts = vterm_obtain_screen(mVt);
    vterm_screen_enable_altscreen(mVts, 1);
    vterm_screen_set_callbacks(mVts, &cb, this);
    vterm_screen_set_damage_merge(mVts, VTERM_DAMAGE_SCROLL);
    vterm_screen_reset(mVts, 1);
}

Terminal::~Terminal() {
    close(mMasterFd);
    ::kill(mChildPid, SIGHUP);

    vterm_free(mVt);

    delete mScroll;

    JNIEnv *env = AndroidRuntime::getJNIEnv();
    env->DeleteGlobalRef(mCallbacks);
}

status_t Terminal::run() {
    struct termios termios = {
        .c_iflag = ICRNL|IXON|IUTF8,
        .c_oflag = OPOST|ONLCR|NL0|CR0|TAB0|BS0|VT0|FF0,
        .c_cflag = CS8|CREAD,
        .c_lflag = ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK,
        /* c_cc later */
    };

    cfsetispeed(&termios, B38400);
    cfsetospeed(&termios, B38400);

    termios.c_cc[VINTR]    = 0x1f & 'C';
    termios.c_cc[VQUIT]    = 0x1f & '\\';
    termios.c_cc[VERASE]   = 0x7f;
    termios.c_cc[VKILL]    = 0x1f & 'U';
    termios.c_cc[VEOF]     = 0x1f & 'D';
    termios.c_cc[VSTART]   = 0x1f & 'Q';
    termios.c_cc[VSTOP]    = 0x1f & 'S';
    termios.c_cc[VSUSP]    = 0x1f & 'Z';
    termios.c_cc[VREPRINT] = 0x1f & 'R';
    termios.c_cc[VWERASE]  = 0x1f & 'W';
    termios.c_cc[VLNEXT]   = 0x1f & 'V';
    termios.c_cc[VMIN]     = 1;
    termios.c_cc[VTIME]    = 0;

    struct winsize size = { mRows, mCols, 0, 0 };

    int stderr_save_fd = dup(2);
    if (stderr_save_fd < 0) {
        ALOGE("failed to dup stderr - %s", strerror(errno));
    }

    mChildPid = forkpty(&mMasterFd, NULL, &termios, &size);
    if (mChildPid == 0) {
        /* Restore the ISIG signals back to defaults */
        signal(SIGINT, SIG_DFL);
        signal(SIGQUIT, SIG_DFL);
        signal(SIGSTOP, SIG_DFL);
        signal(SIGCONT, SIG_DFL);

        FILE *stderr_save = fdopen(stderr_save_fd, "a");

        if (!stderr_save) {
            ALOGE("failed to open stderr - %s", strerror(errno));
        }

        char *shell = "/system/bin/sh"; //getenv("SHELL");
#if USE_TEST_SHELL
        char *args[4] = {shell, "-c", "x=1; c=0; while true; do echo -e \"stop \e[00;3${c}mechoing\e[00m yourself! ($x)\"; x=$(( $x + 1 )); c=$((($c+1)%7)); if [ $x -gt 110 ]; then sleep 0.5; fi; done", NULL};
#else
        char *args[2] = {shell, NULL};
#endif

        execvp(shell, args);
        fprintf(stderr_save, "Cannot exec(%s) - %s\n", shell, strerror(errno));
        _exit(1);
    }

    ALOGD("entering read() loop");
    while (1) {
        char buffer[4096];
        ssize_t bytes = ::read(mMasterFd, buffer, sizeof buffer);
#if DEBUG_IO
        ALOGD("read() returned %d bytes", bytes);
#endif

        if (mKilled) {
            ALOGD("kill() requested");
            break;
        }
        if (bytes == 0) {
            ALOGD("read() found EOF");
            break;
        }
        if (bytes == -1) {
            ALOGE("read() failed: %s", strerror(errno));
            return 1;
        }

        {
            Mutex::Autolock lock(mLock);
            vterm_push_bytes(mVt, buffer, bytes);
            vterm_screen_flush_damage(mVts);
        }
    }

    return 0;
}

size_t Terminal::write(const char *bytes, size_t len) {
    return ::write(mMasterFd, bytes, len);
}

bool Terminal::dispatchCharacter(int mod, int character) {
    Mutex::Autolock lock(mLock);
    vterm_input_push_char(mVt, static_cast<VTermModifier>(mod), character);
    return flushInput();
}

bool Terminal::dispatchKey(int mod, int key) {
    Mutex::Autolock lock(mLock);
    vterm_input_push_key(mVt, static_cast<VTermModifier>(mod), static_cast<VTermKey>(key));
    return flushInput();
}

bool Terminal::flushInput() {
    size_t len = vterm_output_get_buffer_current(mVt);
    if (len) {
        char buf[len];
        len = vterm_output_bufferread(mVt, buf, len);
        return len == write(buf, len);
    }
    return true;
}

status_t Terminal::resize(dimen_t rows, dimen_t cols, dimen_t scrollRows) {
    Mutex::Autolock lock(mLock);

    ALOGD("resize(%d, %d, %d)", rows, cols, scrollRows);

    mRows = rows;
    mCols = cols;
    // TODO: resize scrollback

    struct winsize size = { rows, cols, 0, 0 };
    ioctl(mMasterFd, TIOCSWINSZ, &size);

    vterm_set_size(mVt, rows, cols);
    vterm_screen_flush_damage(mVts);

    return 0;
}

status_t Terminal::onPushline(dimen_t cols, const VTermScreenCell* cells) {
    ScrollbackLine* line = NULL;
    if (mScrollCur == mScrollSize) {
        /* Recycle old row if it's the right size */
        if (mScroll[mScrollCur - 1]->cols == cols) {
            line = mScroll[mScrollCur - 1];
        } else {
            delete mScroll[mScrollCur - 1];
        }

        memmove(mScroll + 1, mScroll, sizeof(ScrollbackLine*) * (mScrollCur - 1));
    } else if (mScrollCur > 0) {
        memmove(mScroll + 1, mScroll, sizeof(ScrollbackLine*) * mScrollCur);
    }

    if (line == NULL) {
        line = new ScrollbackLine(cols);
    }

    mScroll[0] = line;

    if (mScrollCur < mScrollSize) {
        mScrollCur++;
    }

    line->copyFrom(cols, cells);
    return 1;
}

status_t Terminal::onPopline(dimen_t cols, VTermScreenCell* cells) {
    if (mScrollCur == 0) {
        return 0;
    }

    ScrollbackLine* line = mScroll[0];
    mScrollCur--;
    memmove(mScroll, mScroll + 1, sizeof(ScrollbackLine*) * mScrollCur);

    dimen_t n = line->copyTo(cols, cells);
    for (dimen_t col = n; col < cols; col++) {
        cells[col].chars[0] = 0;
        cells[col].width = 1;
    }

    delete line;
    return 1;
}

void Terminal::getCellLocked(VTermPos pos, VTermScreenCell* cell) {
    // The UI may be asking for cell data while the model is changing
    // underneath it, so we always fill with meaningful data.

    if (pos.row < 0) {
        size_t scrollRow = -pos.row;
        if (scrollRow > mScrollCur) {
            // Invalid region above current scrollback
            cell->width = 1;
#if DEBUG_SCROLLBACK
            cell->bg.red = 255;
#endif
            return;
        }

        ScrollbackLine* line = mScroll[scrollRow - 1];
        if ((size_t) pos.col < line->cols) {
            // Valid scrollback cell
            line->getCell(pos.col, cell);
            cell->width = 1;
#if DEBUG_SCROLLBACK
            cell->bg.blue = 255;
#endif
            return;
        } else {
            // Extend last scrollback cell into invalid region
            line->getCell(line->cols - 1, cell);
            cell->width = 1;
            cell->chars[0] = ' ';
#if DEBUG_SCROLLBACK
            cell->bg.green = 255;
#endif
            return;
        }
    }

    if ((size_t) pos.row >= mRows) {
        // Invalid region below screen
        cell->width = 1;
#if DEBUG_SCROLLBACK
        cell->bg.red = 128;
#endif
        return;
    }

    // Valid screen cell
    vterm_screen_get_cell(mVts, pos, cell);
}

dimen_t Terminal::getRows() const {
    return mRows;
}

dimen_t Terminal::getCols() const {
    return mCols;
}

dimen_t Terminal::getScrollRows() const {
    return mScrollSize;
}

jobject Terminal::getCallbacks() const {
    return mCallbacks;
}

/*
 * JNI glue
 */

static jint com_android_terminal_Terminal_nativeInit(JNIEnv* env, jclass clazz, jobject callbacks,
        jint rows, jint cols) {
    return reinterpret_cast<jint>(new Terminal(callbacks, rows, cols));
}

static jint com_android_terminal_Terminal_nativeDestroy(JNIEnv* env, jclass clazz, jint ptr) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    delete term;
    return 0;
}

static jint com_android_terminal_Terminal_nativeRun(JNIEnv* env, jclass clazz, jint ptr) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->run();
}

static jint com_android_terminal_Terminal_nativeResize(JNIEnv* env,
        jclass clazz, jint ptr, jint rows, jint cols, jint scrollRows) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->resize(rows, cols, scrollRows);
}

static inline int toArgb(const VTermColor& color) {
    return (0xff << 24 | color.red << 16 | color.green << 8 | color.blue);
}

static inline bool isCellStyleEqual(const VTermScreenCell& a, const VTermScreenCell& b) {
    if (toArgb(a.fg) != toArgb(b.fg)) return false;
    if (toArgb(a.bg) != toArgb(b.bg)) return false;

    if (a.attrs.bold != b.attrs.bold) return false;
    if (a.attrs.underline != b.attrs.underline) return false;
    if (a.attrs.italic != b.attrs.italic) return false;
    if (a.attrs.blink != b.attrs.blink) return false;
    if (a.attrs.reverse != b.attrs.reverse) return false;
    if (a.attrs.strike != b.attrs.strike) return false;
    if (a.attrs.font != b.attrs.font) return false;

    return true;
}

static jint com_android_terminal_Terminal_nativeGetCellRun(JNIEnv* env,
        jclass clazz, jint ptr, jint row, jint col, jobject run) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    Mutex::Autolock lock(term->mLock);

    jcharArray dataArray = (jcharArray) env->GetObjectField(run, cellRunDataField);
    ScopedCharArrayRW data(env, dataArray);
    if (data.get() == NULL) {
        return -1;
    }

    VTermScreenCell firstCell, cell;

    VTermPos pos = {
        .row = row,
        .col = col,
    };

    size_t dataSize = 0;
    size_t colSize = 0;
    while ((size_t) pos.col < term->getCols()) {
        memset(&cell, 0, sizeof(VTermScreenCell));
        term->getCellLocked(pos, &cell);

        if (colSize == 0) {
            env->SetIntField(run, cellRunFgField, toArgb(cell.fg));
            env->SetIntField(run, cellRunBgField, toArgb(cell.bg));
            memcpy(&firstCell, &cell, sizeof(VTermScreenCell));
        } else {
            if (!isCellStyleEqual(cell, firstCell)) {
                break;
            }
        }

        // Only include cell chars if they fit into run
        uint32_t rawCell = cell.chars[0];
        size_t size = (rawCell < 0x10000) ? 1 : 2;
        if (dataSize + size <= data.size()) {
            if (rawCell < 0x10000) {
                data[dataSize++] = rawCell;
            } else {
                data[dataSize++] = (((rawCell - 0x10000) >> 10) & 0x3ff) + 0xd800;
                data[dataSize++] = ((rawCell - 0x10000) & 0x3ff) + 0xdc00;
            }

            for (int i = 1; i < cell.width; i++) {
                data[dataSize++] = ' ';
            }

            colSize += cell.width;
            pos.col += cell.width;
        } else {
            break;
        }
    }

    env->SetIntField(run, cellRunDataSizeField, dataSize);
    env->SetIntField(run, cellRunColSizeField, colSize);

    return 0;
}

static jint com_android_terminal_Terminal_nativeGetRows(JNIEnv* env, jclass clazz, jint ptr) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->getRows();
}

static jint com_android_terminal_Terminal_nativeGetCols(JNIEnv* env, jclass clazz, jint ptr) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->getCols();
}

static jint com_android_terminal_Terminal_nativeGetScrollRows(JNIEnv* env, jclass clazz, jint ptr) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->getScrollRows();
}

static jboolean com_android_terminal_Terminal_nativeDispatchCharacter(JNIEnv *env, jclass clazz,
        jint ptr, jint mod, jint c) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->dispatchCharacter(mod, c);
}

static jboolean com_android_terminal_Terminal_nativeDispatchKey(JNIEnv *env, jclass clazz,
        jint ptr, jint mod, jint c) {
    Terminal* term = reinterpret_cast<Terminal*>(ptr);
    return term->dispatchKey(mod, c);
}

static JNINativeMethod gMethods[] = {
    { "nativeInit", "(Lcom/android/terminal/TerminalCallbacks;II)I", (void*)com_android_terminal_Terminal_nativeInit },
    { "nativeDestroy", "(I)I", (void*)com_android_terminal_Terminal_nativeDestroy },
    { "nativeRun", "(I)I", (void*)com_android_terminal_Terminal_nativeRun },
    { "nativeResize", "(IIII)I", (void*)com_android_terminal_Terminal_nativeResize },
    { "nativeGetCellRun", "(IIILcom/android/terminal/Terminal$CellRun;)I", (void*)com_android_terminal_Terminal_nativeGetCellRun },
    { "nativeGetRows", "(I)I", (void*)com_android_terminal_Terminal_nativeGetRows },
    { "nativeGetCols", "(I)I", (void*)com_android_terminal_Terminal_nativeGetCols },
    { "nativeGetScrollRows", "(I)I", (void*)com_android_terminal_Terminal_nativeGetScrollRows },
    { "nativeDispatchCharacter", "(III)Z", (void*)com_android_terminal_Terminal_nativeDispatchCharacter},
    { "nativeDispatchKey", "(III)Z", (void*)com_android_terminal_Terminal_nativeDispatchKey },
};

int register_com_android_terminal_Terminal(JNIEnv* env) {
    ScopedLocalRef<jclass> localClass(env,
            env->FindClass("com/android/terminal/TerminalCallbacks"));

    android::terminalCallbacksClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));

    android::damageMethod = env->GetMethodID(terminalCallbacksClass, "damage", "(IIII)I");
    android::moveRectMethod = env->GetMethodID(terminalCallbacksClass, "moveRect", "(IIIIIIII)I");
    android::moveCursorMethod = env->GetMethodID(terminalCallbacksClass, "moveCursor",
            "(IIIII)I");
    android::setTermPropBooleanMethod = env->GetMethodID(terminalCallbacksClass,
            "setTermPropBoolean", "(IZ)I");
    android::setTermPropIntMethod = env->GetMethodID(terminalCallbacksClass, "setTermPropInt",
            "(II)I");
    android::setTermPropStringMethod = env->GetMethodID(terminalCallbacksClass, "setTermPropString",
            "(ILjava/lang/String;)I");
    android::setTermPropColorMethod = env->GetMethodID(terminalCallbacksClass, "setTermPropColor",
            "(IIII)I");
    android::bellMethod = env->GetMethodID(terminalCallbacksClass, "bell", "()I");

    ScopedLocalRef<jclass> cellRunLocal(env,
            env->FindClass("com/android/terminal/Terminal$CellRun"));
    cellRunClass = reinterpret_cast<jclass>(env->NewGlobalRef(cellRunLocal.get()));
    cellRunDataField = env->GetFieldID(cellRunClass, "data", "[C");
    cellRunDataSizeField = env->GetFieldID(cellRunClass, "dataSize", "I");
    cellRunColSizeField = env->GetFieldID(cellRunClass, "colSize", "I");
    cellRunFgField = env->GetFieldID(cellRunClass, "fg", "I");
    cellRunBgField = env->GetFieldID(cellRunClass, "bg", "I");

    return jniRegisterNativeMethods(env, "com/android/terminal/Terminal",
            gMethods, NELEM(gMethods));
}

} /* namespace android */
