| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 "base/android/library_loader/library_loader_hooks.h" | |
| 6 | |
| 7 #include "base/android/command_line_android.h" | |
| 8 #include "base/android/jni_string.h" | |
| 9 #include "base/android/library_loader/library_load_from_apk_status_codes.h" | |
| 10 #include "base/android/library_loader/library_prefetcher.h" | |
| 11 #include "base/at_exit.h" | |
| 12 #include "base/metrics/histogram.h" | |
| 13 #include "jni/LibraryLoader_jni.h" | |
| 14 | |
| 15 namespace base { | |
| 16 namespace android { | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 base::AtExitManager* g_at_exit_manager = NULL; | |
| 21 const char* g_library_version_number = ""; | |
| 22 LibraryLoadedHook* g_registration_callback = NULL; | |
| 23 | |
| 24 enum RendererHistogramCode { | |
| 25 // Renderer load at fixed address success, fail, or not attempted. | |
| 26 // Renderers do not attempt to load at at fixed address if on a | |
| 27 // low-memory device on which browser load at fixed address has already | |
| 28 // failed. | |
| 29 LFA_SUCCESS = 0, | |
| 30 LFA_BACKOFF_USED = 1, | |
| 31 LFA_NOT_ATTEMPTED = 2, | |
| 32 | |
| 33 // End sentinel, also used as nothing-pending indicator. | |
| 34 MAX_RENDERER_HISTOGRAM_CODE = 3, | |
| 35 NO_PENDING_HISTOGRAM_CODE = MAX_RENDERER_HISTOGRAM_CODE | |
| 36 }; | |
| 37 | |
| 38 enum BrowserHistogramCode { | |
| 39 // Non-low-memory random address browser loads. | |
| 40 NORMAL_LRA_SUCCESS = 0, | |
| 41 | |
| 42 // Low-memory browser loads at fixed address, success or fail. | |
| 43 LOW_MEMORY_LFA_SUCCESS = 1, | |
| 44 LOW_MEMORY_LFA_BACKOFF_USED = 2, | |
| 45 | |
| 46 MAX_BROWSER_HISTOGRAM_CODE = 3, | |
| 47 }; | |
| 48 | |
| 49 RendererHistogramCode g_renderer_histogram_code = NO_PENDING_HISTOGRAM_CODE; | |
| 50 | |
| 51 // The amount of time, in milliseconds, that it took to load the shared | |
| 52 // libraries in the renderer. Set in | |
| 53 // RegisterChromiumAndroidLinkerRendererHistogram. | |
| 54 long g_renderer_library_load_time_ms = 0; | |
| 55 | |
| 56 } // namespace | |
| 57 | |
| 58 static void RegisterChromiumAndroidLinkerRendererHistogram( | |
| 59 JNIEnv* env, | |
| 60 jobject jcaller, | |
| 61 jboolean requested_shared_relro, | |
| 62 jboolean load_at_fixed_address_failed, | |
| 63 jlong library_load_time_ms) { | |
| 64 // Note a pending histogram value for later recording. | |
| 65 if (requested_shared_relro) { | |
| 66 g_renderer_histogram_code = load_at_fixed_address_failed | |
| 67 ? LFA_BACKOFF_USED : LFA_SUCCESS; | |
| 68 } else { | |
| 69 g_renderer_histogram_code = LFA_NOT_ATTEMPTED; | |
| 70 } | |
| 71 | |
| 72 g_renderer_library_load_time_ms = library_load_time_ms; | |
| 73 } | |
| 74 | |
| 75 void RecordChromiumAndroidLinkerRendererHistogram() { | |
| 76 if (g_renderer_histogram_code == NO_PENDING_HISTOGRAM_CODE) | |
| 77 return; | |
| 78 // Record and release the pending histogram value. | |
| 79 UMA_HISTOGRAM_ENUMERATION("ChromiumAndroidLinker.RendererStates", | |
| 80 g_renderer_histogram_code, | |
| 81 MAX_RENDERER_HISTOGRAM_CODE); | |
| 82 g_renderer_histogram_code = NO_PENDING_HISTOGRAM_CODE; | |
| 83 | |
| 84 // Record how long it took to load the shared libraries. | |
| 85 UMA_HISTOGRAM_TIMES( | |
| 86 "ChromiumAndroidLinker.RendererLoadTime", | |
| 87 base::TimeDelta::FromMilliseconds(g_renderer_library_load_time_ms)); | |
| 88 } | |
| 89 | |
| 90 static void RecordChromiumAndroidLinkerBrowserHistogram( | |
| 91 JNIEnv* env, | |
| 92 jobject jcaller, | |
| 93 jboolean is_using_browser_shared_relros, | |
| 94 jboolean load_at_fixed_address_failed, | |
| 95 jint library_load_from_apk_status, | |
| 96 jlong library_load_time_ms) { | |
| 97 // For low-memory devices, record whether or not we successfully loaded the | |
| 98 // browser at a fixed address. Otherwise just record a normal invocation. | |
| 99 BrowserHistogramCode histogram_code; | |
| 100 if (is_using_browser_shared_relros) { | |
| 101 histogram_code = load_at_fixed_address_failed | |
| 102 ? LOW_MEMORY_LFA_BACKOFF_USED : LOW_MEMORY_LFA_SUCCESS; | |
| 103 } else { | |
| 104 histogram_code = NORMAL_LRA_SUCCESS; | |
| 105 } | |
| 106 UMA_HISTOGRAM_ENUMERATION("ChromiumAndroidLinker.BrowserStates", | |
| 107 histogram_code, | |
| 108 MAX_BROWSER_HISTOGRAM_CODE); | |
| 109 | |
| 110 // Record the device support for loading a library directly from the APK file. | |
| 111 UMA_HISTOGRAM_ENUMERATION("ChromiumAndroidLinker.LibraryLoadFromApkStatus", | |
| 112 library_load_from_apk_status, | |
| 113 LIBRARY_LOAD_FROM_APK_STATUS_CODES_MAX); | |
| 114 | |
| 115 // Record how long it took to load the shared libraries. | |
| 116 UMA_HISTOGRAM_TIMES("ChromiumAndroidLinker.BrowserLoadTime", | |
| 117 base::TimeDelta::FromMilliseconds(library_load_time_ms)); | |
| 118 } | |
| 119 | |
| 120 void SetLibraryLoadedHook(LibraryLoadedHook* func) { | |
| 121 g_registration_callback = func; | |
| 122 } | |
| 123 | |
| 124 static void InitCommandLine(JNIEnv* env, | |
| 125 jobject jcaller, | |
| 126 jobjectArray init_command_line) { | |
| 127 InitNativeCommandLineFromJavaArray(env, init_command_line); | |
| 128 } | |
| 129 | |
| 130 static jboolean LibraryLoaded(JNIEnv* env, jobject jcaller) { | |
| 131 if (g_registration_callback == NULL) { | |
| 132 return true; | |
| 133 } | |
| 134 return g_registration_callback(env, NULL); | |
| 135 } | |
| 136 | |
| 137 void LibraryLoaderExitHook() { | |
| 138 if (g_at_exit_manager) { | |
| 139 delete g_at_exit_manager; | |
| 140 g_at_exit_manager = NULL; | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 static jboolean ForkAndPrefetchNativeLibrary(JNIEnv* env, jclass clazz) { | |
| 145 return NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary(); | |
| 146 } | |
| 147 | |
| 148 bool RegisterLibraryLoaderEntryHook(JNIEnv* env) { | |
| 149 return RegisterNativesImpl(env); | |
| 150 } | |
| 151 | |
| 152 void SetVersionNumber(const char* version_number) { | |
| 153 g_library_version_number = strdup(version_number); | |
| 154 } | |
| 155 | |
| 156 jstring GetVersionNumber(JNIEnv* env, jobject jcaller) { | |
| 157 return ConvertUTF8ToJavaString(env, g_library_version_number).Release(); | |
| 158 } | |
| 159 | |
| 160 LibraryProcessType GetLibraryProcessType(JNIEnv* env) { | |
| 161 return static_cast<LibraryProcessType>( | |
| 162 Java_LibraryLoader_getLibraryProcessType(env)); | |
| 163 } | |
| 164 | |
| 165 void InitAtExitManager() { | |
| 166 g_at_exit_manager = new base::AtExitManager(); | |
| 167 } | |
| 168 | |
| 169 } // namespace android | |
| 170 } // namespace base | |
| OLD | NEW |