1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/public/app/android_library_loader_hooks.h" 6 7 #include "base/android/base_jni_registrar.h" 8 #include "base/android/command_line_android.h" 9 #include "base/android/jni_android.h" 10 #include "base/android/jni_registrar.h" 11 #include "base/android/jni_string.h" 12 #include "base/at_exit.h" 13 #include "base/base_switches.h" 14 #include "base/command_line.h" 15 #include "base/debug/trace_event.h" 16 #include "base/files/file_path.h" 17 #include "base/logging.h" 18 #include "base/metrics/histogram.h" 19 #include "base/strings/string_util.h" 20 #include "base/tracked_objects.h" 21 #include "content/app/android/app_jni_registrar.h" 22 #include "content/browser/android/browser_jni_registrar.h" 23 #include "content/child/android/child_jni_registrar.h" 24 #include "content/common/android/common_jni_registrar.h" 25 #include "content/public/common/content_switches.h" 26 #include "content/public/common/result_codes.h" 27 #include "jni/LibraryLoader_jni.h" 28 #include "media/base/android/media_jni_registrar.h" 29 #include "net/android/net_jni_registrar.h" 30 #include "ui/base/android/ui_base_jni_registrar.h" 31 #include "ui/gfx/android/gfx_jni_registrar.h" 32 #include "ui/gl/android/gl_jni_registrar.h" 33 #include "ui/shell_dialogs/android/shell_dialogs_jni_registrar.h" 34 35 namespace content { 36 37 namespace { 38 base::AtExitManager* g_at_exit_manager = NULL; 39 const char* g_library_version_number = ""; 40 } 41 42 bool EnsureJniRegistered(JNIEnv* env) { 43 static bool g_jni_init_done = false; 44 45 if (!g_jni_init_done) { 46 if (!base::android::RegisterJni(env)) 47 return false; 48 49 if (!gfx::android::RegisterJni(env)) 50 return false; 51 52 if (!net::android::RegisterJni(env)) 53 return false; 54 55 if (!ui::android::RegisterJni(env)) 56 return false; 57 58 if (!ui::gl::android::RegisterJni(env)) 59 return false; 60 61 if (!ui::shell_dialogs::RegisterJni(env)) 62 return false; 63 64 if (!content::android::RegisterChildJni(env)) 65 return false; 66 67 if (!content::android::RegisterCommonJni(env)) 68 return false; 69 70 if (!content::android::RegisterBrowserJni(env)) 71 return false; 72 73 if (!content::android::RegisterAppJni(env)) 74 return false; 75 76 if (!media::RegisterJni(env)) 77 return false; 78 79 g_jni_init_done = true; 80 } 81 82 return true; 83 } 84 85 static jint LibraryLoaded(JNIEnv* env, jclass clazz, 86 jobjectArray init_command_line) { 87 base::android::InitNativeCommandLineFromJavaArray(env, init_command_line); 88 89 CommandLine* command_line = CommandLine::ForCurrentProcess(); 90 91 if (command_line->HasSwitch(switches::kTraceStartup)) { 92 base::debug::CategoryFilter category_filter( 93 command_line->GetSwitchValueASCII(switches::kTraceStartup)); 94 base::debug::TraceLog::GetInstance()->SetEnabled(category_filter, 95 base::debug::TraceLog::RECORD_UNTIL_FULL); 96 } 97 98 // Can only use event tracing after setting up the command line. 99 TRACE_EVENT0("jni", "JNI_OnLoad continuation"); 100 101 // Note: because logging is setup here right after copying the command line 102 // array from java to native up top of this method, any code that adds the 103 // --enable-dcheck switch must do so on the Java side. 104 logging::LoggingSettings settings; 105 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 106 settings.dcheck_state = 107 command_line->HasSwitch(switches::kEnableDCHECK) ? 108 logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS : 109 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; 110 logging::InitLogging(settings); 111 // To view log output with IDs and timestamps use "adb logcat -v threadtime". 112 logging::SetLogItems(false, // Process ID 113 false, // Thread ID 114 false, // Timestamp 115 false); // Tick count 116 VLOG(0) << "Chromium logging enabled: level = " << logging::GetMinLogLevel() 117 << ", default verbosity = " << logging::GetVlogVerbosity(); 118 119 if (!EnsureJniRegistered(env)) 120 return RESULT_CODE_FAILED_TO_REGISTER_JNI; 121 122 return 0; 123 } 124 125 static void RecordContentAndroidLinkerHistogram( 126 JNIEnv* env, 127 jclass clazz, 128 jboolean loaded_at_fixed_address_failed, 129 jboolean is_low_memory_device) { 130 UMA_HISTOGRAM_BOOLEAN("ContentAndroidLinker.LoadedAtFixedAddressFailed", 131 loaded_at_fixed_address_failed); 132 UMA_HISTOGRAM_BOOLEAN("ContentAndroidLinker.IsLowMemoryDevice", 133 is_low_memory_device); 134 } 135 136 void LibraryLoaderExitHook() { 137 if (g_at_exit_manager) { 138 delete g_at_exit_manager; 139 g_at_exit_manager = NULL; 140 } 141 } 142 143 bool RegisterLibraryLoaderEntryHook(JNIEnv* env) { 144 // We need the AtExitManager to be created at the very beginning. 145 g_at_exit_manager = new base::AtExitManager(); 146 147 return RegisterNativesImpl(env); 148 } 149 150 void SetVersionNumber(const char* version_number) { 151 g_library_version_number = strdup(version_number); 152 } 153 154 jstring GetVersionNumber(JNIEnv* env, jclass clazz) { 155 return env->NewStringUTF(g_library_version_number); 156 } 157 158 } // namespace content 159