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