diff options
author | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-10 01:50:47 +0000 |
---|---|---|
committer | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-10 01:50:47 +0000 |
commit | e08255671738c597992f5067bc52eccf75f1afa1 (patch) | |
tree | 53e9a332ca7a1b619dfce059a131361746339414 /content/browser/android | |
parent | 6465bc3aea8a62f0598d5ea16e5efe8272f24dbf (diff) | |
download | chromium_src-e08255671738c597992f5067bc52eccf75f1afa1.zip chromium_src-e08255671738c597992f5067bc52eccf75f1afa1.tar.gz chromium_src-e08255671738c597992f5067bc52eccf75f1afa1.tar.bz2 |
Android content shell bringup.
Build media java files (we weren't).
Fix adb_install_content_shell for cases where the app was stuck.
Add upstream staging gyp var / #define.
Be more consistent about jar output files (all in lib.java).
Upstream a bunch of random files (e.g. ppapi).
Upstream a bunch of java and native code hit as part of shlib init.
Properly package jar files in content shell.
BUG=
TEST=
Review URL: https://chromiumcodereview.appspot.com/10377059
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136219 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/android')
-rw-r--r-- | content/browser/android/command_line.cc | 78 | ||||
-rw-r--r-- | content/browser/android/command_line.h | 18 | ||||
-rw-r--r-- | content/browser/android/content_jni_registrar.cc | 26 | ||||
-rw-r--r-- | content/browser/android/content_jni_registrar.h | 19 | ||||
-rw-r--r-- | content/browser/android/jni_helper.cc | 158 | ||||
-rw-r--r-- | content/browser/android/jni_helper.h | 92 | ||||
-rw-r--r-- | content/browser/android/library_loader_hooks.cc | 30 | ||||
-rw-r--r-- | content/browser/android/trace_event_binding.cc | 93 | ||||
-rw-r--r-- | content/browser/android/trace_event_binding.h | 13 |
9 files changed, 521 insertions, 6 deletions
diff --git a/content/browser/android/command_line.cc b/content/browser/android/command_line.cc new file mode 100644 index 0000000..1883b07f --- /dev/null +++ b/content/browser/android/command_line.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/command_line.h" + +#include "base/android/jni_string.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "jni/command_line_jni.h" +#include "content/browser/android/jni_helper.h" + +using base::android::ConvertJavaStringToUTF8; + +namespace { + +void AppendJavaStringArrayToCommandLine(JNIEnv* env, + jobjectArray array, + bool includes_program) { + CommandLine::StringVector vec; + if (array) + ConvertJavaArrayOfStringsToVectorOfStrings(env, array, &vec); + if (!includes_program) + vec.insert(vec.begin(), ""); + CommandLine extra_command_line(vec); + CommandLine::ForCurrentProcess()->AppendArguments(extra_command_line, + includes_program); +} + +} // namespace + +static void Reset(JNIEnv* env, jclass clazz) { + CommandLine::Reset(); +} + +static jboolean HasSwitch(JNIEnv* env, jclass clazz, jstring jswitch) { + std::string switch_string(ConvertJavaStringToUTF8(env, jswitch)); + return CommandLine::ForCurrentProcess()->HasSwitch(switch_string); +} + +static jstring GetSwitchValue(JNIEnv* env, jclass clazz, jstring jswitch) { + std::string switch_string(ConvertJavaStringToUTF8(env, jswitch)); + std::string value(CommandLine::ForCurrentProcess()->GetSwitchValueNative( + switch_string)); + if (value.empty()) + return 0; + // OK to release, JNI binding. + return base::android::ConvertUTF8ToJavaString(env, value).Release(); +} + +static void AppendSwitch(JNIEnv* env, jclass clazz, jstring jswitch) { + std::string switch_string(ConvertJavaStringToUTF8(env, jswitch)); + CommandLine::ForCurrentProcess()->AppendSwitch(switch_string); +} + +static void AppendSwitchWithValue(JNIEnv* env, jclass clazz, + jstring jswitch, jstring jvalue) { + std::string switch_string(ConvertJavaStringToUTF8(env, jswitch)); + std::string value_string (ConvertJavaStringToUTF8(env, jvalue)); + CommandLine::ForCurrentProcess()->AppendSwitchASCII(switch_string, + value_string); +} + +static void AppendSwitchesAndArguments(JNIEnv* env, jclass clazz, + jobjectArray array) { + AppendJavaStringArrayToCommandLine(env, array, false); +} + +void InitNativeCommandLineFromJavaArray(JNIEnv* env, jobjectArray array) { + // TODO(port): Make an overload of Init() that takes StringVector rather than + // have to round-trip via AppendArguments. + CommandLine::Init(0, NULL); + AppendJavaStringArrayToCommandLine(env, array, true); +} + +bool RegisterCommandLine(JNIEnv* env) { + return RegisterNativesImpl(env); +} diff --git a/content/browser/android/command_line.h b/content/browser/android/command_line.h new file mode 100644 index 0000000..5e44080 --- /dev/null +++ b/content/browser/android/command_line.h @@ -0,0 +1,18 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_COMMAND_LINE_H_ +#define CONTENT_BROWSER_ANDROID_COMMAND_LINE_H_ +#pragma once + +#include <jni.h> + +// Appends all strings in the given array as flags to the Chrome command line. +void InitNativeCommandLineFromJavaArray(JNIEnv* env, + jobjectArray init_command_line); + +// JNI registration boilerplate. +bool RegisterCommandLine(JNIEnv* env); + +#endif // CONTENT_BROWSER_ANDROID_COMMAND_LINE_H_ diff --git a/content/browser/android/content_jni_registrar.cc b/content/browser/android/content_jni_registrar.cc new file mode 100644 index 0000000..c32cc50 --- /dev/null +++ b/content/browser/android/content_jni_registrar.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/content_jni_registrar.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_registrar.h" +#include "content/browser/android/command_line.h" +#include "content/browser/android/trace_event_binding.h" + +namespace content { +namespace android { + +base::android::RegistrationMethod kContentRegisteredMethods[] = { + { "CommandLine", RegisterCommandLine }, + { "TraceEvent", RegisterTraceEvent }, +}; + +bool RegisterJni(JNIEnv* env) { + return RegisterNativeMethods(env, kContentRegisteredMethods, + arraysize(kContentRegisteredMethods)); +} + +} // namespace android +} // namespace content diff --git a/content/browser/android/content_jni_registrar.h b/content/browser/android/content_jni_registrar.h new file mode 100644 index 0000000..ce41c63 --- /dev/null +++ b/content/browser/android/content_jni_registrar.h @@ -0,0 +1,19 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_CONTENT_JNI_REGISTRAR_H_ +#define CONTENT_BROWSER_ANDROID_CONTENT_JNI_REGISTRAR_H_ + +#include <jni.h> + +namespace content { +namespace android { + +// Register all JNI bindings necessary for content. +bool RegisterJni(JNIEnv* env); + +} // namespace android +} // namespace content + +#endif // CONTENT_BROWSER_ANDROID_CONTENT_JNI_REGISTRAR_H_ diff --git a/content/browser/android/jni_helper.cc b/content/browser/android/jni_helper.cc new file mode 100644 index 0000000..bd7bce6 --- /dev/null +++ b/content/browser/android/jni_helper.cc @@ -0,0 +1,158 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/jni_helper.h" + +#include <android/bitmap.h> +#include <vector> + +#include "base/android/jni_android.h" +#include "base/android/jni_helper.h" +#include "base/android/jni_string.h" +#include "base/debug/trace_event.h" +#include "base/logging.h" +#include "jni/jni_helper_jni.h" +#include "third_party/skia/include/core/SkBitmap.h" + +using base::android::AttachCurrentThread; +using base::android::CheckException; +using base::android::GetStaticMethodID; +using base::android::GetClass; +using base::android::GetMethodID; +using base::android::ScopedJavaLocalRef; + +AutoLocalFrame::AutoLocalFrame(int capacity) { + AttachCurrentThread()->PushLocalFrame(capacity); +} + +AutoLocalFrame::~AutoLocalFrame() { + AttachCurrentThread()->PopLocalFrame(NULL); +} + +AutoLockJavaBitmap::AutoLockJavaBitmap(jobject bitmap) : + bitmap_(bitmap), + pixels_(NULL) { + int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_); + DCHECK(!err); + DCHECK(pixels_); +} + +AutoLockJavaBitmap::~AutoLockJavaBitmap() { + // TODO(aelias): Add AndroidBitmap_notifyPixelsChanged() call here + // once it's added to the NDK. Using hardware bitmaps will + // be broken until this is fixed. + int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_); + DCHECK(!err); +} + +gfx::Size AutoLockJavaBitmap::size() const { + AndroidBitmapInfo info; + int err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); + DCHECK(!err); + return gfx::Size(info.width, info.height); +} + +int AutoLockJavaBitmap::format() const { + AndroidBitmapInfo info; + int err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); + DCHECK(!err); + return info.format; +} + +uint32_t AutoLockJavaBitmap::stride() const { + AndroidBitmapInfo info; + int err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); + DCHECK(!err); + return info.stride; +} + +void PrintJavaStackTrace() { + JNIEnv* env = AttachCurrentThread(); + + ScopedJavaLocalRef<jclass> throwable_clazz = + GetClass(env, "java/lang/Throwable"); + jmethodID throwable_constructor = + GetMethodID(env, throwable_clazz, "<init>", "()V"); + + ScopedJavaLocalRef<jobject> throwable_object(env, + env->NewObject(throwable_clazz.obj(), throwable_constructor)); + DCHECK(!throwable_object.is_null()); + jmethodID printstacktrace = + GetMethodID(env, throwable_clazz, "printStackTrace", "()V"); + + env->CallVoidMethod(throwable_object.obj(), printstacktrace); + CheckException(env); +} + +void ConvertJavaArrayOfStringsToVectorOfStrings( + JNIEnv* env, + jobjectArray jstrings, + std::vector<std::string>* vec) { + vec->clear(); + jsize length = env->GetArrayLength(jstrings); + for (jsize i = 0; i < length; ++i) { + jstring item = static_cast<jstring>( + env->GetObjectArrayElement(jstrings, i)); + vec->push_back(base::android::ConvertJavaStringToUTF8(env, item)); + env->DeleteLocalRef(item); + } +} + +ScopedJavaLocalRef<jobject> CreateJavaBitmap(const gfx::Size& size, bool keep) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> bitmap = + Java_JNIHelper_createJavaBitmap(env, size.width(), size.height(), keep); + CheckException(env); + return bitmap; +} + +void DeleteJavaBitmap(jobject bitmap) { + JNIEnv* env = AttachCurrentThread(); + Java_JNIHelper_deleteJavaBitmap(env, bitmap); + CheckException(env); +} + +void PaintJavaBitmapToJavaBitmap(jobject source_bitmap, + const gfx::Rect& source_rect, + jobject dest_bitmap, + const gfx::Rect& dest_rect) { + TRACE_EVENT0("jni", "PaintJavaBitmapToJavaBitmap"); + JNIEnv* env = AttachCurrentThread(); + + Java_JNIHelper_paintJavaBitmapToJavaBitmap(env, + source_bitmap, + source_rect.x(), + source_rect.y(), + source_rect.right(), + source_rect.bottom(), + dest_bitmap, + dest_rect.x(), + dest_rect.y(), + dest_rect.right(), + dest_rect.bottom()); + CheckException(env); +} + +ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) { + TRACE_EVENT0("jni", "ConvertToJavaBitmap"); + DCHECK(skbitmap); + DCHECK_EQ(skbitmap->bytesPerPixel(), 4); + + // Create a temporary java bitmap. + ScopedJavaLocalRef<jobject> jbitmap = + CreateJavaBitmap(gfx::Size(skbitmap->width(), skbitmap->height()), false); + + // Lock and copy the pixels from the skbitmap. + SkAutoLockPixels src_lock(*skbitmap); + AutoLockJavaBitmap dst_lock(jbitmap.obj()); + void* src_pixels = skbitmap->getPixels(); + void* dst_pixels = dst_lock.pixels(); + memcpy(dst_pixels, src_pixels, skbitmap->getSize()); + + return jbitmap; +} + +bool RegisterJniHelper(JNIEnv* env) { + return RegisterNativesImpl(env); +} diff --git a/content/browser/android/jni_helper.h b/content/browser/android/jni_helper.h new file mode 100644 index 0000000..c7fa569 --- /dev/null +++ b/content/browser/android/jni_helper.h @@ -0,0 +1,92 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_JNI_HELPER_H_ +#define CONTENT_BROWSER_ANDROID_JNI_HELPER_H_ + +#include <jni.h> +#include <string> +#include <vector> + +#include "base/android/scoped_java_ref.h" +#include "base/string16.h" +#include "ui/gfx/rect.h" + +class SkBitmap; +namespace gfx { +class Size; +} + +// Auto creator/destructor for a JNI frame for local references. This allows +// safely having more than 16 local references, and avoids calls to +// DeleteLocalRef. +// This should be created on the stack. +class AutoLocalFrame { + public: + AutoLocalFrame(int capacity); + ~AutoLocalFrame(); + + private: + DISALLOW_COPY_AND_ASSIGN(AutoLocalFrame); +}; + +// Create this object on the stack to obtain the pixels of a Java Bitmap and +// automatically release them on destruction. +// Similar to SkAutoLockPixels, except that it operates on a Java Bitmap +// object via the Android NDK. +class AutoLockJavaBitmap { + public: + AutoLockJavaBitmap(jobject bitmap); + ~AutoLockJavaBitmap(); + + void* pixels() const { return pixels_; } + gfx::Size size() const; + // Formats are in android/bitmap.h; e.g. ANDROID_BITMAP_FORMAT_RGBA_8888 */ + int format() const; + uint32_t stride() const; + + private: + jobject bitmap_; + void* pixels_; + + DISALLOW_COPY_AND_ASSIGN(AutoLockJavaBitmap); +}; + +// Tell Java to write its current stack trace into Android logs. Note that the +// trace will stop at the entry point into C++ code. +void PrintJavaStackTrace(); + +// Fills in the given vector<string> from a java String[]. +void ConvertJavaArrayOfStringsToVectorOfStrings( + JNIEnv* env, + jobjectArray jstrings, + std::vector<std::string>* vec); + +// Helper method to create an Android Java Bitmap object. You can use the +// AutoLockJavaBitmap class to manipulate its pixels, and pass it back up +// to Java code for drawing. Returns a JNI local reference to the bitmap. +// If 'keep' is true, then a reference will be kept in a static Java data +// structure to prevent GC. In that case, you must call DeleteJavaBitmap() to +// garbage collect it. +base::android::ScopedJavaLocalRef<jobject> CreateJavaBitmap( + const gfx::Size& size, bool keep); +void DeleteJavaBitmap(jobject bitmap); + +// Paint one java bitmap into another. Scale if needed. +void PaintJavaBitmapToJavaBitmap(jobject sourceBitmap, + const gfx::Rect& sourceRect, + jobject destBitmap, + const gfx::Rect& destRect); + +// Copy the Chromium Skia bitmap into a new Java bitmap. Useful for small UI +// bitmaps originating from WebKit that we want to manipulate in Java (such as +// favicons). Due to the extra copy, should be avoided for large or frequently +// used bitmaps. Returns a local reference to the new bitmap. +base::android::ScopedJavaLocalRef<jobject> ConvertToJavaBitmap( + const SkBitmap* skbitmap); + +// Registers our JNI methods. +bool RegisterJniHelper(JNIEnv* env); + +#endif // CONTENT_BROWSER_ANDROID_JNI_HELPER_H_ diff --git a/content/browser/android/library_loader_hooks.cc b/content/browser/android/library_loader_hooks.cc index 3f2315e..17ebbd4 100644 --- a/content/browser/android/library_loader_hooks.cc +++ b/content/browser/android/library_loader_hooks.cc @@ -5,8 +5,10 @@ #include "content/public/browser/android_library_loader_hooks.h" #include "base/android/base_jni_registrar.h" +#include "base/android/jni_registrar.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" +#include "base/at_exit.h" #include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/file_path.h" @@ -16,14 +18,21 @@ #include "base/string_util.h" #include "base/tracked_objects.h" #include "content/public/common/content_switches.h" +#include "content/browser/android/command_line.h" +#include "content/browser/android/content_jni_registrar.h" #include "media/base/android/media_jni_registrar.h" #include "net/android/net_jni_registrar.h" +namespace { +base::AtExitManager* g_at_exit_manager = NULL; +} + jboolean LibraryLoaderEntryHook(JNIEnv* env, jclass clazz, jobjectArray init_command_line) { - - // TODO(tedchoc): Initialize the native command line from the java array - // passed in. + // We need the Chrome AtExitManager to be created before we do any tracing or + // logging. + g_at_exit_manager = new base::AtExitManager(); + InitNativeCommandLineFromJavaArray(env, init_command_line); CommandLine* command_line = CommandLine::ForCurrentProcess(); @@ -54,12 +63,22 @@ jboolean LibraryLoaderEntryHook(JNIEnv* env, jclass clazz, if (!net::android::RegisterJni(env)) return JNI_FALSE; + if (!content::android::RegisterJni(env)) + return JNI_FALSE; + if (!media::RegisterJni(env)) return JNI_FALSE; return JNI_TRUE; } +void LibraryLoaderExitHook() { + if (g_at_exit_manager) { + delete g_at_exit_manager; + g_at_exit_manager = NULL; + } +} + bool RegisterLibraryLoaderEntryHook(JNIEnv* env) { // TODO(bulach): use the jni generator once we move jni_helper methods here. const JNINativeMethod kMethods[] = { @@ -67,9 +86,8 @@ bool RegisterLibraryLoaderEntryHook(JNIEnv* env) { reinterpret_cast<void*>(LibraryLoaderEntryHook) }, }; const int kMethodsSize = arraysize(kMethods); - // TODO(tedchoc): Upstream LibraryLoader.java and replace path to make this - // work. - const char kLibraryLoaderPath[] = ""; + const char kLibraryLoaderPath[] = + "org/chromium/content/browser/LibraryLoader"; base::android::ScopedJavaLocalRef<jclass> clazz = base::android::GetClass(env, kLibraryLoaderPath); diff --git a/content/browser/android/trace_event_binding.cc b/content/browser/android/trace_event_binding.cc new file mode 100644 index 0000000..7129946 --- /dev/null +++ b/content/browser/android/trace_event_binding.cc @@ -0,0 +1,93 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/trace_event_binding.h" + +#include <jni.h> + +#include <set> + +#include "base/debug/trace_event.h" +#include "base/lazy_instance.h" +#include "jni/trace_event_jni.h" + +namespace { + +const char kJavaCategory[] = "Java"; + +// Boilerplate for safely converting Java data to TRACE_EVENT data. +class TraceEventDataConverter { + public: + TraceEventDataConverter(JNIEnv* env, + jstring jname, + jstring jarg) + : env_(env), + jname_(jname), + jarg_(jarg), + name_(env->GetStringUTFChars(jname, NULL)), + arg_(jarg ? env->GetStringUTFChars(jarg, NULL) : NULL) { + } + ~TraceEventDataConverter() { + env_->ReleaseStringUTFChars(jname_, name_); + if (jarg_) + env_->ReleaseStringUTFChars(jarg_, arg_); + } + + // Return saves values to pass to TRACE_EVENT macros. + const char* name() { return name_; } + const char* arg_name() { return arg_ ? "arg" : NULL; } + const char* arg() { return arg_; } + + private: + JNIEnv* env_; + jstring jname_; + jstring jarg_; + const char* name_; + const char* arg_; + + DISALLOW_COPY_AND_ASSIGN(TraceEventDataConverter); +}; + +} // namespace + +static jboolean TraceEnabled(JNIEnv* env, jclass clazz) { + return base::debug::TraceLog::GetInstance()->IsEnabled(); +} + +static void Instant(JNIEnv* env, jclass clazz, + jstring jname, jstring jarg) { + TraceEventDataConverter converter(env, jname, jarg); + if (converter.arg()) { + TRACE_EVENT_COPY_INSTANT1(kJavaCategory, converter.name(), + converter.arg_name(), converter.arg()); + } else { + TRACE_EVENT_COPY_INSTANT0(kJavaCategory, converter.name()); + } +} + +static void Begin(JNIEnv* env, jclass clazz, + jstring jname, jstring jarg) { + TraceEventDataConverter converter(env, jname, jarg); + if (converter.arg()) { + TRACE_EVENT_COPY_BEGIN1(kJavaCategory, converter.name(), + converter.arg_name(), converter.arg()); + } else { + TRACE_EVENT_COPY_BEGIN0(kJavaCategory, converter.name()); + } +} + +static void End(JNIEnv* env, jclass clazz, + jstring jname, jstring jarg) { + TraceEventDataConverter converter(env, jname, jarg); + if (converter.arg()) { + TRACE_EVENT_COPY_END1(kJavaCategory, converter.name(), + converter.arg_name(), converter.arg()); + } else { + TRACE_EVENT_COPY_END0(kJavaCategory, converter.name()); + } +} + +bool RegisterTraceEvent(JNIEnv* env) { + return RegisterNativesImpl(env); +} diff --git a/content/browser/android/trace_event_binding.h b/content/browser/android/trace_event_binding.h new file mode 100644 index 0000000..3d54e92 --- /dev/null +++ b/content/browser/android/trace_event_binding.h @@ -0,0 +1,13 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_TRACE_EVENT_H_ +#define CONTENT_BROWSER_ANDROID_TRACE_EVENT_H_ +#pragma once + +#include <jni.h> + +extern bool RegisterTraceEvent(JNIEnv* env); + +#endif // CONTENT_BROWSER_ANDROID_TRACE_EVENT_H_ |