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