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