Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdio.h>
     18 
     19 #include "android_util_Binder.h"
     20 
     21 #include <surfaceflinger/SurfaceComposerClient.h>
     22 #include <ui/Region.h>
     23 #include <ui/Rect.h>
     24 
     25 #include <SkCanvas.h>
     26 #include <SkBitmap.h>
     27 #include <SkRegion.h>
     28 
     29 #include "jni.h"
     30 #include <android_runtime/AndroidRuntime.h>
     31 #include <utils/misc.h>
     32 
     33 
     34 // ----------------------------------------------------------------------------
     35 
     36 namespace android {
     37 
     38 enum {
     39     // should match Parcelable.java
     40     PARCELABLE_WRITE_RETURN_VALUE = 0x0001
     41 };
     42 
     43 // ----------------------------------------------------------------------------
     44 
     45 static const char* const OutOfResourcesException =
     46     "android/view/Surface$OutOfResourcesException";
     47 
     48 struct sso_t {
     49     jfieldID client;
     50 };
     51 static sso_t sso;
     52 
     53 struct so_t {
     54     jfieldID surfaceControl;
     55     jfieldID surface;
     56     jfieldID saveCount;
     57     jfieldID canvas;
     58 };
     59 static so_t so;
     60 
     61 struct ro_t {
     62     jfieldID l;
     63     jfieldID t;
     64     jfieldID r;
     65     jfieldID b;
     66 };
     67 static ro_t ro;
     68 
     69 struct po_t {
     70     jfieldID x;
     71     jfieldID y;
     72 };
     73 static po_t po;
     74 
     75 struct co_t {
     76     jfieldID surfaceFormat;
     77 };
     78 static co_t co;
     79 
     80 struct no_t {
     81     jfieldID native_canvas;
     82     jfieldID native_region;
     83     jfieldID native_parcel;
     84 };
     85 static no_t no;
     86 
     87 
     88 static __attribute__((noinline))
     89 void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
     90 {
     91     if (!env->ExceptionOccurred()) {
     92         jclass npeClazz = env->FindClass(exc);
     93         env->ThrowNew(npeClazz, msg);
     94     }
     95 }
     96 
     97 // ----------------------------------------------------------------------------
     98 // ----------------------------------------------------------------------------
     99 // ----------------------------------------------------------------------------
    100 
    101 static void SurfaceSession_init(JNIEnv* env, jobject clazz)
    102 {
    103     sp<SurfaceComposerClient> client = new SurfaceComposerClient;
    104     client->incStrong(clazz);
    105     env->SetIntField(clazz, sso.client, (int)client.get());
    106 }
    107 
    108 static void SurfaceSession_destroy(JNIEnv* env, jobject clazz)
    109 {
    110     SurfaceComposerClient* client =
    111             (SurfaceComposerClient*)env->GetIntField(clazz, sso.client);
    112     if (client != 0) {
    113         client->decStrong(clazz);
    114         env->SetIntField(clazz, sso.client, 0);
    115     }
    116 }
    117 
    118 static void SurfaceSession_kill(JNIEnv* env, jobject clazz)
    119 {
    120     SurfaceComposerClient* client =
    121             (SurfaceComposerClient*)env->GetIntField(clazz, sso.client);
    122     if (client != 0) {
    123         client->dispose();
    124         client->decStrong(clazz);
    125         env->SetIntField(clazz, sso.client, 0);
    126     }
    127 }
    128 
    129 // ----------------------------------------------------------------------------
    130 
    131 static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz)
    132 {
    133     SurfaceControl* const p =
    134         (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
    135     return sp<SurfaceControl>(p);
    136 }
    137 
    138 static void setSurfaceControl(JNIEnv* env, jobject clazz,
    139         const sp<SurfaceControl>& surface)
    140 {
    141     SurfaceControl* const p =
    142         (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
    143     if (surface.get()) {
    144         surface->incStrong(clazz);
    145     }
    146     if (p) {
    147         p->decStrong(clazz);
    148     }
    149     env->SetIntField(clazz, so.surfaceControl, (int)surface.get());
    150 }
    151 
    152 static sp<Surface> getSurface(JNIEnv* env, jobject clazz)
    153 {
    154     sp<Surface> result((Surface*)env->GetIntField(clazz, so.surface));
    155     if (result == 0) {
    156         /*
    157          * if this method is called from the WindowManager's process, it means
    158          * the client is is not remote, and therefore is allowed to have
    159          * a Surface (data), so we create it here.
    160          * If we don't have a SurfaceControl, it means we're in a different
    161          * process.
    162          */
    163 
    164         SurfaceControl* const control =
    165             (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
    166         if (control) {
    167             result = control->getSurface();
    168             if (result != 0) {
    169                 result->incStrong(clazz);
    170                 env->SetIntField(clazz, so.surface, (int)result.get());
    171             }
    172         }
    173     }
    174     return result;
    175 }
    176 
    177 static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface)
    178 {
    179     Surface* const p = (Surface*)env->GetIntField(clazz, so.surface);
    180     if (surface.get()) {
    181         surface->incStrong(clazz);
    182     }
    183     if (p) {
    184         p->decStrong(clazz);
    185     }
    186     env->SetIntField(clazz, so.surface, (int)surface.get());
    187 }
    188 
    189 // ----------------------------------------------------------------------------
    190 
    191 static void Surface_init(
    192         JNIEnv* env, jobject clazz,
    193         jobject session,
    194         jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
    195 {
    196     if (session == NULL) {
    197         doThrow(env, "java/lang/NullPointerException");
    198         return;
    199     }
    200 
    201     SurfaceComposerClient* client =
    202             (SurfaceComposerClient*)env->GetIntField(session, sso.client);
    203 
    204     sp<SurfaceControl> surface;
    205     if (jname == NULL) {
    206         surface = client->createSurface(pid, dpy, w, h, format, flags);
    207     } else {
    208         const jchar* str = env->GetStringCritical(jname, 0);
    209         const String8 name(str, env->GetStringLength(jname));
    210         env->ReleaseStringCritical(jname, str);
    211         surface = client->createSurface(pid, name, dpy, w, h, format, flags);
    212     }
    213 
    214     if (surface == 0) {
    215         doThrow(env, OutOfResourcesException);
    216         return;
    217     }
    218     setSurfaceControl(env, clazz, surface);
    219 }
    220 
    221 static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel)
    222 {
    223     Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel);
    224     if (parcel == NULL) {
    225         doThrow(env, "java/lang/NullPointerException", NULL);
    226         return;
    227     }
    228     sp<Surface> rhs = new Surface(*parcel);
    229     setSurface(env, clazz, rhs);
    230 }
    231 
    232 static jint Surface_getIdentity(JNIEnv* env, jobject clazz)
    233 {
    234     const sp<SurfaceControl>& control(getSurfaceControl(env, clazz));
    235     if (control != 0) return (jint) control->getIdentity();
    236     const sp<Surface>& surface(getSurface(env, clazz));
    237     if (surface != 0) return (jint) surface->getIdentity();
    238     return -1;
    239 }
    240 
    241 static void Surface_destroy(JNIEnv* env, jobject clazz, uintptr_t *ostack)
    242 {
    243     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    244     if (SurfaceControl::isValid(surface)) {
    245         surface->clear();
    246     }
    247     setSurfaceControl(env, clazz, 0);
    248     setSurface(env, clazz, 0);
    249 }
    250 
    251 static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack)
    252 {
    253     setSurfaceControl(env, clazz, 0);
    254     setSurface(env, clazz, 0);
    255 }
    256 
    257 static jboolean Surface_isValid(JNIEnv* env, jobject clazz)
    258 {
    259     const sp<SurfaceControl>& surfaceControl(getSurfaceControl(env, clazz));
    260     if (surfaceControl != 0) {
    261         return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE;
    262     }
    263     const sp<Surface>& surface(getSurface(env, clazz));
    264     return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE;
    265 }
    266 
    267 static inline SkBitmap::Config convertPixelFormat(PixelFormat format)
    268 {
    269     /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
    270         we can map to SkBitmap::kARGB_8888_Config, and optionally call
    271         bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
    272     */
    273     switch (format) {
    274     case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
    275     case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
    276     case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
    277     case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
    278     case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
    279     default:                        return SkBitmap::kNo_Config;
    280     }
    281 }
    282 
    283 static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
    284 {
    285     const sp<Surface>& surface(getSurface(env, clazz));
    286     if (!Surface::isValid(surface))
    287         return 0;
    288 
    289     // get dirty region
    290     Region dirtyRegion;
    291     if (dirtyRect) {
    292         Rect dirty;
    293         dirty.left  = env->GetIntField(dirtyRect, ro.l);
    294         dirty.top   = env->GetIntField(dirtyRect, ro.t);
    295         dirty.right = env->GetIntField(dirtyRect, ro.r);
    296         dirty.bottom= env->GetIntField(dirtyRect, ro.b);
    297         if (!dirty.isEmpty()) {
    298             dirtyRegion.set(dirty);
    299         }
    300     } else {
    301         dirtyRegion.set(Rect(0x3FFF,0x3FFF));
    302     }
    303 
    304     Surface::SurfaceInfo info;
    305     status_t err = surface->lock(&info, &dirtyRegion);
    306     if (err < 0) {
    307         const char* const exception = (err == NO_MEMORY) ?
    308             OutOfResourcesException :
    309             "java/lang/IllegalArgumentException";
    310         doThrow(env, exception, NULL);
    311         return 0;
    312     }
    313 
    314     // Associate a SkCanvas object to this surface
    315     jobject canvas = env->GetObjectField(clazz, so.canvas);
    316     env->SetIntField(canvas, co.surfaceFormat, info.format);
    317 
    318     SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
    319     SkBitmap bitmap;
    320     ssize_t bpr = info.s * bytesPerPixel(info.format);
    321     bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
    322     if (info.format == PIXEL_FORMAT_RGBX_8888) {
    323         bitmap.setIsOpaque(true);
    324     }
    325     if (info.w > 0 && info.h > 0) {
    326         bitmap.setPixels(info.bits);
    327     } else {
    328         // be safe with an empty bitmap.
    329         bitmap.setPixels(NULL);
    330     }
    331     nativeCanvas->setBitmapDevice(bitmap);
    332 
    333     SkRegion clipReg;
    334     if (dirtyRegion.isRect()) { // very common case
    335         const Rect& b(dirtyRegion.getBounds());
    336         clipReg.setRect(b.left, b.top, b.right, b.bottom);
    337     } else {
    338         size_t count;
    339         Rect const* r = dirtyRegion.getArray(&count);
    340         while (count) {
    341             clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op);
    342             r++, count--;
    343         }
    344     }
    345 
    346     nativeCanvas->clipRegion(clipReg);
    347 
    348     int saveCount = nativeCanvas->save();
    349     env->SetIntField(clazz, so.saveCount, saveCount);
    350 
    351     if (dirtyRect) {
    352         const Rect& bounds(dirtyRegion.getBounds());
    353         env->SetIntField(dirtyRect, ro.l, bounds.left);
    354         env->SetIntField(dirtyRect, ro.t, bounds.top);
    355         env->SetIntField(dirtyRect, ro.r, bounds.right);
    356         env->SetIntField(dirtyRect, ro.b, bounds.bottom);
    357     }
    358 
    359     return canvas;
    360 }
    361 
    362 static void Surface_unlockCanvasAndPost(
    363         JNIEnv* env, jobject clazz, jobject argCanvas)
    364 {
    365     jobject canvas = env->GetObjectField(clazz, so.canvas);
    366     if (canvas != argCanvas) {
    367         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    368         return;
    369     }
    370 
    371     const sp<Surface>& surface(getSurface(env, clazz));
    372     if (!Surface::isValid(surface))
    373         return;
    374 
    375     // detach the canvas from the surface
    376     SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
    377     int saveCount = env->GetIntField(clazz, so.saveCount);
    378     nativeCanvas->restoreToCount(saveCount);
    379     nativeCanvas->setBitmapDevice(SkBitmap());
    380     env->SetIntField(clazz, so.saveCount, 0);
    381 
    382     // unlock surface
    383     status_t err = surface->unlockAndPost();
    384     if (err < 0) {
    385         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    386     }
    387 }
    388 
    389 static void Surface_unlockCanvas(
    390         JNIEnv* env, jobject clazz, jobject argCanvas)
    391 {
    392     // XXX: this API has been removed
    393     doThrow(env, "java/lang/IllegalArgumentException", NULL);
    394 }
    395 
    396 static void Surface_openTransaction(
    397         JNIEnv* env, jobject clazz)
    398 {
    399     SurfaceComposerClient::openGlobalTransaction();
    400 }
    401 
    402 static void Surface_closeTransaction(
    403         JNIEnv* env, jobject clazz)
    404 {
    405     SurfaceComposerClient::closeGlobalTransaction();
    406 }
    407 
    408 static void Surface_setOrientation(
    409         JNIEnv* env, jobject clazz, jint display, jint orientation, jint flags)
    410 {
    411     int err = SurfaceComposerClient::setOrientation(display, orientation, flags);
    412     if (err < 0) {
    413         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    414     }
    415 }
    416 
    417 static void Surface_freezeDisplay(
    418         JNIEnv* env, jobject clazz, jint display)
    419 {
    420     int err = SurfaceComposerClient::freezeDisplay(display, 0);
    421     if (err < 0) {
    422         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    423     }
    424 }
    425 
    426 static void Surface_unfreezeDisplay(
    427         JNIEnv* env, jobject clazz, jint display)
    428 {
    429     int err = SurfaceComposerClient::unfreezeDisplay(display, 0);
    430     if (err < 0) {
    431         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    432     }
    433 }
    434 
    435 static void Surface_setLayer(
    436         JNIEnv* env, jobject clazz, jint zorder)
    437 {
    438     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    439     if (surface == 0) return;
    440     status_t err = surface->setLayer(zorder);
    441     if (err<0 && err!=NO_INIT)
    442         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    443 }
    444 
    445 static void Surface_setPosition(
    446         JNIEnv* env, jobject clazz, jint x, jint y)
    447 {
    448     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    449     if (surface == 0) return;
    450     status_t err = surface->setPosition(x, y);
    451     if (err<0 && err!=NO_INIT)
    452         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    453 }
    454 
    455 static void Surface_setSize(
    456         JNIEnv* env, jobject clazz, jint w, jint h)
    457 {
    458     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    459     if (surface == 0) return;
    460     status_t err = surface->setSize(w, h);
    461     if (err<0 && err!=NO_INIT)
    462         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    463 }
    464 
    465 static void Surface_hide(
    466         JNIEnv* env, jobject clazz)
    467 {
    468     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    469     if (surface == 0) return;
    470     status_t err = surface->hide();
    471     if (err<0 && err!=NO_INIT)
    472         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    473 }
    474 
    475 static void Surface_show(
    476         JNIEnv* env, jobject clazz)
    477 {
    478     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    479     if (surface == 0) return;
    480     status_t err = surface->show();
    481     if (err<0 && err!=NO_INIT)
    482         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    483 }
    484 
    485 static void Surface_freeze(
    486         JNIEnv* env, jobject clazz)
    487 {
    488     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    489     if (surface == 0) return;
    490     status_t err = surface->freeze();
    491     if (err<0 && err!=NO_INIT)
    492         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    493 }
    494 
    495 static void Surface_unfreeze(
    496         JNIEnv* env, jobject clazz)
    497 {
    498     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    499     if (surface == 0) return;
    500     status_t err = surface->unfreeze();
    501     if (err<0 && err!=NO_INIT)
    502         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    503 }
    504 
    505 static void Surface_setFlags(
    506         JNIEnv* env, jobject clazz, jint flags, jint mask)
    507 {
    508     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    509     if (surface == 0) return;
    510     status_t err = surface->setFlags(flags, mask);
    511     if (err<0 && err!=NO_INIT)
    512         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    513 }
    514 
    515 static void Surface_setTransparentRegion(
    516         JNIEnv* env, jobject clazz, jobject argRegion)
    517 {
    518     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    519     if (surface == 0) return;
    520     SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region);
    521 
    522     const SkIRect& b(nativeRegion->getBounds());
    523     Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
    524     if (nativeRegion->isComplex()) {
    525         SkRegion::Iterator it(*nativeRegion);
    526         while (!it.done()) {
    527             const SkIRect& r(it.rect());
    528             reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
    529             it.next();
    530         }
    531     }
    532 
    533     status_t err = surface->setTransparentRegionHint(reg);
    534     if (err<0 && err!=NO_INIT)
    535         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    536 }
    537 
    538 static void Surface_setAlpha(
    539         JNIEnv* env, jobject clazz, jfloat alpha)
    540 {
    541     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    542     if (surface == 0) return;
    543     status_t err = surface->setAlpha(alpha);
    544     if (err<0 && err!=NO_INIT)
    545         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    546 }
    547 
    548 static void Surface_setMatrix(
    549         JNIEnv* env, jobject clazz,
    550         jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy)
    551 {
    552     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    553     if (surface == 0) return;
    554     status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy);
    555     if (err<0 && err!=NO_INIT)
    556         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    557 }
    558 
    559 static void Surface_setFreezeTint(
    560         JNIEnv* env, jobject clazz,
    561         jint tint)
    562 {
    563     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    564     if (surface == 0) return;
    565     status_t err = surface->setFreezeTint(tint);
    566     if (err<0 && err!=NO_INIT)
    567         doThrow(env, "java/lang/IllegalArgumentException", NULL);
    568 }
    569 
    570 // ----------------------------------------------------------------------------
    571 
    572 static void Surface_copyFrom(
    573         JNIEnv* env, jobject clazz, jobject other)
    574 {
    575     if (clazz == other)
    576         return;
    577 
    578     if (other == NULL) {
    579         doThrow(env, "java/lang/NullPointerException", NULL);
    580         return;
    581     }
    582 
    583     /*
    584      * This is used by the WindowManagerService just after constructing
    585      * a Surface and is necessary for returning the Surface reference to
    586      * the caller. At this point, we should only have a SurfaceControl.
    587      */
    588 
    589     const sp<SurfaceControl>& surface = getSurfaceControl(env, clazz);
    590     const sp<SurfaceControl>& rhs = getSurfaceControl(env, other);
    591     if (!SurfaceControl::isSameSurface(surface, rhs)) {
    592         // we reassign the surface only if it's a different one
    593         // otherwise we would loose our client-side state.
    594         setSurfaceControl(env, clazz, rhs);
    595     }
    596 }
    597 
    598 static void Surface_readFromParcel(
    599         JNIEnv* env, jobject clazz, jobject argParcel)
    600 {
    601     Parcel* parcel = (Parcel*)env->GetIntField( argParcel, no.native_parcel);
    602     if (parcel == NULL) {
    603         doThrow(env, "java/lang/NullPointerException", NULL);
    604         return;
    605     }
    606 
    607     const sp<Surface>& control(getSurface(env, clazz));
    608     sp<Surface> rhs = new Surface(*parcel);
    609     if (!Surface::isSameSurface(control, rhs)) {
    610         // we reassign the surface only if it's a different one
    611         // otherwise we would loose our client-side state.
    612         setSurface(env, clazz, rhs);
    613     }
    614 }
    615 
    616 static void Surface_writeToParcel(
    617         JNIEnv* env, jobject clazz, jobject argParcel, jint flags)
    618 {
    619     Parcel* parcel = (Parcel*)env->GetIntField(
    620             argParcel, no.native_parcel);
    621 
    622     if (parcel == NULL) {
    623         doThrow(env, "java/lang/NullPointerException", NULL);
    624         return;
    625     }
    626 
    627     const sp<SurfaceControl>& control(getSurfaceControl(env, clazz));
    628     SurfaceControl::writeSurfaceToParcel(control, parcel);
    629     if (flags & PARCELABLE_WRITE_RETURN_VALUE) {
    630         setSurfaceControl(env, clazz, 0);
    631     }
    632 }
    633 
    634 // ----------------------------------------------------------------------------
    635 // ----------------------------------------------------------------------------
    636 // ----------------------------------------------------------------------------
    637 
    638 const char* const kSurfaceSessionClassPathName = "android/view/SurfaceSession";
    639 const char* const kSurfaceClassPathName = "android/view/Surface";
    640 static void nativeClassInit(JNIEnv* env, jclass clazz);
    641 
    642 static JNINativeMethod gSurfaceSessionMethods[] = {
    643     {"init",     "()V",  (void*)SurfaceSession_init },
    644     {"destroy",  "()V",  (void*)SurfaceSession_destroy },
    645     {"kill",     "()V",  (void*)SurfaceSession_kill },
    646 };
    647 
    648 static JNINativeMethod gSurfaceMethods[] = {
    649     {"nativeClassInit",     "()V",  (void*)nativeClassInit },
    650     {"init",                "(Landroid/view/SurfaceSession;ILjava/lang/String;IIIII)V",  (void*)Surface_init },
    651     {"init",                "(Landroid/os/Parcel;)V",  (void*)Surface_initParcel },
    652     {"getIdentity",         "()I",  (void*)Surface_getIdentity },
    653     {"destroy",             "()V",  (void*)Surface_destroy },
    654     {"release",             "()V",  (void*)Surface_release },
    655     {"copyFrom",            "(Landroid/view/Surface;)V",  (void*)Surface_copyFrom },
    656     {"isValid",             "()Z",  (void*)Surface_isValid },
    657     {"lockCanvasNative",    "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",  (void*)Surface_lockCanvas },
    658     {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost },
    659     {"unlockCanvas",        "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas },
    660     {"openTransaction",     "()V",  (void*)Surface_openTransaction },
    661     {"closeTransaction",    "()V",  (void*)Surface_closeTransaction },
    662     {"setOrientation",      "(III)V", (void*)Surface_setOrientation },
    663     {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },
    664     {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },
    665     {"setLayer",            "(I)V", (void*)Surface_setLayer },
    666     {"setPosition",         "(II)V",(void*)Surface_setPosition },
    667     {"setSize",             "(II)V",(void*)Surface_setSize },
    668     {"hide",                "()V",  (void*)Surface_hide },
    669     {"show",                "()V",  (void*)Surface_show },
    670     {"freeze",              "()V",  (void*)Surface_freeze },
    671     {"unfreeze",            "()V",  (void*)Surface_unfreeze },
    672     {"setFlags",            "(II)V",(void*)Surface_setFlags },
    673     {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion },
    674     {"setAlpha",            "(F)V", (void*)Surface_setAlpha },
    675     {"setMatrix",           "(FFFF)V",  (void*)Surface_setMatrix },
    676     {"setFreezeTint",       "(I)V",  (void*)Surface_setFreezeTint },
    677     {"readFromParcel",      "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel },
    678     {"writeToParcel",       "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
    679 };
    680 
    681 void nativeClassInit(JNIEnv* env, jclass clazz)
    682 {
    683     so.surface = env->GetFieldID(clazz, "mSurface", "I");
    684     so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I");
    685     so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I");
    686     so.canvas    = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;");
    687 
    688     jclass surfaceSession = env->FindClass("android/view/SurfaceSession");
    689     sso.client = env->GetFieldID(surfaceSession, "mClient", "I");
    690 
    691     jclass canvas = env->FindClass("android/graphics/Canvas");
    692     no.native_canvas = env->GetFieldID(canvas, "mNativeCanvas", "I");
    693     co.surfaceFormat = env->GetFieldID(canvas, "mSurfaceFormat", "I");
    694 
    695     jclass region = env->FindClass("android/graphics/Region");
    696     no.native_region = env->GetFieldID(region, "mNativeRegion", "I");
    697 
    698     jclass parcel = env->FindClass("android/os/Parcel");
    699     no.native_parcel = env->GetFieldID(parcel, "mObject", "I");
    700 
    701     jclass rect = env->FindClass("android/graphics/Rect");
    702     ro.l = env->GetFieldID(rect, "left", "I");
    703     ro.t = env->GetFieldID(rect, "top", "I");
    704     ro.r = env->GetFieldID(rect, "right", "I");
    705     ro.b = env->GetFieldID(rect, "bottom", "I");
    706 
    707     jclass point = env->FindClass("android/graphics/Point");
    708     po.x = env->GetFieldID(point, "x", "I");
    709     po.y = env->GetFieldID(point, "y", "I");
    710 }
    711 
    712 int register_android_view_Surface(JNIEnv* env)
    713 {
    714     int err;
    715     err = AndroidRuntime::registerNativeMethods(env, kSurfaceSessionClassPathName,
    716             gSurfaceSessionMethods, NELEM(gSurfaceSessionMethods));
    717 
    718     err |= AndroidRuntime::registerNativeMethods(env, kSurfaceClassPathName,
    719             gSurfaceMethods, NELEM(gSurfaceMethods));
    720     return err;
    721 }
    722 
    723 };
    724 
    725