18cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn/*
28cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn**
38cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** Copyright 2006, The Android Open Source Project
48cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn**
58cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** Licensed under the Apache License, Version 2.0 (the "License");
68cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** you may not use this file except in compliance with the License.
78cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** You may obtain a copy of the License at
88cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn**
98cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn**     http://www.apache.org/licenses/LICENSE-2.0
108cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn**
118cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** Unless required by applicable law or agreed to in writing, software
128cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** distributed under the License is distributed on an "AS IS" BASIS,
138cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** See the License for the specific language governing permissions and
158cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn** limitations under the License.
168cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn*/
178cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn
188cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn#define LOG_TAG "9patch"
198cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn#define LOG_NDEBUG 1
208cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn
21b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/ResourceTypes.h>
228cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn#include <utils/Log.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn#include "SkCanvas.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkRegion.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h"
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           const SkPaint* paint, SkRegion** outRegion);
3369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass SkNinePatchGlue {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj)
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL == obj) {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (env->GetArrayLength(obj) < (int)sizeof(Res_png_9patch)) {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jbyte* array = env->GetByteArrayElements(obj, 0);
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (array != NULL) {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Res_png_9patch* chunk =
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                reinterpret_cast<const Res_png_9patch*>(array);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int8_t wasDeserialized = chunk->wasDeserialized;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array),
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                          JNI_ABORT);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return wasDeserialized != -1;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj)
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (env->GetArrayLength(obj) < (int) (sizeof(Res_png_9patch))) {
6169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes            jniThrowRuntimeException(env, "Array too small for chunk.");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // XXX Also check that dimensions are correct.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds,
6911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                      const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
7011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                      jint destDensity, jint srcDensity)
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t chunkSize = env->GetArrayLength(chunkObj);
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void* storage = alloca(chunkSize);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetByteArrayRegion(chunkObj, 0, chunkSize,
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                reinterpret_cast<jbyte*>(storage));
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!env->ExceptionCheck()) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // need to deserialize the chunk
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assert(chunkSize == chunk->serializedSize());
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this relies on deserialization being done in place
8111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            Res_png_9patch::deserialize(chunk);
8269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
8311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            if (destDensity == srcDensity || destDensity == 0
8411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                    || srcDensity == 0) {
8571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block                ALOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)",
868cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn                        SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
878cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn                        SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom));
8811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
8911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            } else {
9011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                canvas->save();
9169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
9211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                SkScalar scale = SkFloatToScalar(destDensity / (float)srcDensity);
9311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                canvas->translate(bounds.fLeft, bounds.fTop);
9411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                canvas->scale(scale, scale);
9569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
9611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale);
9711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
9811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                bounds.fLeft = bounds.fTop = 0;
9969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
10071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block                ALOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d",
1018cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn                        SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
1028cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn                        SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom),
1038cae124af2142687a6833dbaab8a43df6dd67b43Dianne Hackborn                        srcDensity, destDensity);
10469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
10511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
10669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
10711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                canvas->restore();
10811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawF(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRectF,
11311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                      const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
11411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                      jint destDensity, jint srcDensity)
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(canvas);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(boundsRectF);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(bitmap);
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(chunkObj);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // paint is optional
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect      bounds;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrectf_to_rect(env, boundsRectF, &bounds);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void drawI(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRect,
12911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                      const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
13011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                      jint destDensity, jint srcDensity)
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(canvas);
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(boundsRect);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(bitmap);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(chunkObj);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // paint is optional
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect      bounds;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds);
14011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static jint getTransparentRegion(JNIEnv* env, jobject,
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const SkBitmap* bitmap, jbyteArray chunkObj,
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    jobject boundsRect)
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(bitmap);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(chunkObj);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkASSERT(boundsRect);
15069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SkRect      bounds;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t chunkSize = env->GetArrayLength(chunkObj);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void* storage = alloca(chunkSize);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetByteArrayRegion(chunkObj, 0, chunkSize,
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                reinterpret_cast<jbyte*>(storage));
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!env->ExceptionCheck()) {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // need to deserialize the chunk
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assert(chunkSize == chunk->serializedSize());
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this relies on deserialization being done in place
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Res_png_9patch::deserialize(chunk);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SkRegion* region = NULL;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NinePatch_Draw(NULL, bounds, *bitmap, *chunk, NULL, &region);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (jint)region;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gNinePatchMethods[] = {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "isNinePatchChunk", "([B)Z",                      (void*)SkNinePatchGlue::isNinePatchChunk   },
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "validateNinePatchChunk", "(I[B)V",               (void*)SkNinePatchGlue::validateNinePatchChunk   },
17911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    { "nativeDraw", "(ILandroid/graphics/RectF;I[BIII)V", (void*)SkNinePatchGlue::drawF   },
18011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    { "nativeDraw", "(ILandroid/graphics/Rect;I[BIII)V",  (void*)SkNinePatchGlue::drawI   },
18169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    { "nativeGetTransparentRegion", "(I[BLandroid/graphics/Rect;)I",
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        (void*)SkNinePatchGlue::getTransparentRegion   }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_NinePatch(JNIEnv* env)
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return android::AndroidRuntime::registerNativeMethods(env,
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       "android/graphics/NinePatch",
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       gNinePatchMethods,
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       SK_ARRAY_COUNT(gNinePatchMethods));
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
192