OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/android/library_loader/library_loader_hooks.h" | 5 #include "base/android/library_loader/library_loader_hooks.h" |
6 | 6 |
7 #include "base/android/command_line_android.h" | 7 #include "base/android/command_line_android.h" |
8 #include "base/android/jni_string.h" | 8 #include "base/android/jni_string.h" |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "jni/LibraryLoader_jni.h" | 11 #include "jni/LibraryLoader_jni.h" |
12 | 12 |
13 namespace base { | 13 namespace base { |
14 namespace android { | 14 namespace android { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 base::AtExitManager* g_at_exit_manager = NULL; | 18 base::AtExitManager* g_at_exit_manager = NULL; |
19 const char* g_library_version_number = ""; | 19 const char* g_library_version_number = ""; |
20 LibraryLoadedHook* g_registration_callback = NULL; | 20 LibraryLoadedHook* g_registration_callback = NULL; |
21 | 21 |
| 22 enum RendererHistogramCode { |
| 23 // Renderer load at fixed address success, fail, or not attempted. |
| 24 // Renderers do not attempt to load at at fixed address if on a |
| 25 // low-memory device on which browser load at fixed address has already |
| 26 // failed. |
| 27 LFA_SUCCESS = 0, |
| 28 LFA_BACKOFF_USED = 1, |
| 29 LFA_NOT_ATTEMPTED = 2, |
| 30 |
| 31 // End sentinel, also used as nothing-pending indicator. |
| 32 MAX_RENDERER_HISTOGRAM_CODE = 3, |
| 33 NO_PENDING_HISTOGRAM_CODE = MAX_RENDERER_HISTOGRAM_CODE |
| 34 }; |
| 35 |
| 36 enum BrowserHistogramCode { |
| 37 // Non-low-memory random address browser loads. |
| 38 NORMAL_LRA_SUCCESS = 0, |
| 39 |
| 40 // Low-memory browser loads at fixed address, success or fail. |
| 41 LOW_MEMORY_LFA_SUCCESS = 1, |
| 42 LOW_MEMORY_LFA_BACKOFF_USED = 2, |
| 43 |
| 44 MAX_BROWSER_HISTOGRAM_CODE = 3, |
| 45 }; |
| 46 |
| 47 RendererHistogramCode g_renderer_histogram_code = NO_PENDING_HISTOGRAM_CODE; |
| 48 |
22 } // namespace | 49 } // namespace |
23 | 50 |
| 51 static void RegisterChromiumAndroidLinkerRendererHistogram( |
| 52 JNIEnv* env, |
| 53 jclass clazz, |
| 54 jboolean requested_shared_relro, |
| 55 jboolean load_at_fixed_address_failed) { |
| 56 // Note a pending histogram value for later recording. |
| 57 if (requested_shared_relro) { |
| 58 g_renderer_histogram_code = load_at_fixed_address_failed |
| 59 ? LFA_BACKOFF_USED : LFA_SUCCESS; |
| 60 } else { |
| 61 g_renderer_histogram_code = LFA_NOT_ATTEMPTED; |
| 62 } |
| 63 } |
| 64 |
| 65 void RecordChromiumAndroidLinkerRendererHistogram() { |
| 66 if (g_renderer_histogram_code == NO_PENDING_HISTOGRAM_CODE) |
| 67 return; |
| 68 // Record and release the pending histogram value. |
| 69 UMA_HISTOGRAM_ENUMERATION("ChromiumAndroidLinker.RendererStates", |
| 70 g_renderer_histogram_code, |
| 71 MAX_RENDERER_HISTOGRAM_CODE); |
| 72 g_renderer_histogram_code = NO_PENDING_HISTOGRAM_CODE; |
| 73 } |
| 74 |
| 75 static void RecordChromiumAndroidLinkerBrowserHistogram( |
| 76 JNIEnv* env, |
| 77 jclass clazz, |
| 78 jboolean is_using_browser_shared_relros, |
| 79 jboolean load_at_fixed_address_failed) { |
| 80 // For low-memory devices, record whether or not we successfully loaded the |
| 81 // browser at a fixed address. Otherwise just record a normal invocation. |
| 82 BrowserHistogramCode histogram_code; |
| 83 if (is_using_browser_shared_relros) { |
| 84 histogram_code = load_at_fixed_address_failed |
| 85 ? LOW_MEMORY_LFA_BACKOFF_USED : LOW_MEMORY_LFA_SUCCESS; |
| 86 } else { |
| 87 histogram_code = NORMAL_LRA_SUCCESS; |
| 88 } |
| 89 UMA_HISTOGRAM_ENUMERATION("ChromiumAndroidLinker.BrowserStates", |
| 90 histogram_code, |
| 91 MAX_BROWSER_HISTOGRAM_CODE); |
| 92 } |
| 93 |
24 void SetLibraryLoadedHook(LibraryLoadedHook* func) { | 94 void SetLibraryLoadedHook(LibraryLoadedHook* func) { |
25 g_registration_callback = func; | 95 g_registration_callback = func; |
26 } | 96 } |
27 | 97 |
28 static void InitCommandLine(JNIEnv* env, jclass clazz, | 98 static void InitCommandLine(JNIEnv* env, jclass clazz, |
29 jobjectArray init_command_line) { | 99 jobjectArray init_command_line) { |
30 InitNativeCommandLineFromJavaArray(env, init_command_line); | 100 InitNativeCommandLineFromJavaArray(env, init_command_line); |
31 } | 101 } |
32 | 102 |
33 static jboolean LibraryLoaded(JNIEnv* env, jclass clazz) { | 103 static jboolean LibraryLoaded(JNIEnv* env, jclass clazz) { |
34 if(g_registration_callback == NULL) { | 104 if (g_registration_callback == NULL) { |
35 return true; | 105 return true; |
36 } | 106 } |
37 return g_registration_callback(env, clazz); | 107 return g_registration_callback(env, clazz); |
38 } | 108 } |
39 | 109 |
40 static void RecordChromiumAndroidLinkerHistogram( | |
41 JNIEnv* env, | |
42 jclass clazz, | |
43 jboolean loaded_at_fixed_address_failed, | |
44 jboolean is_low_memory_device) { | |
45 UMA_HISTOGRAM_BOOLEAN("ChromiumAndroidLinker.LoadedAtFixedAddressFailed", | |
46 loaded_at_fixed_address_failed); | |
47 UMA_HISTOGRAM_BOOLEAN("ChromiumAndroidLinker.IsLowMemoryDevice", | |
48 is_low_memory_device); | |
49 } | |
50 | |
51 void LibraryLoaderExitHook() { | 110 void LibraryLoaderExitHook() { |
52 if (g_at_exit_manager) { | 111 if (g_at_exit_manager) { |
53 delete g_at_exit_manager; | 112 delete g_at_exit_manager; |
54 g_at_exit_manager = NULL; | 113 g_at_exit_manager = NULL; |
55 } | 114 } |
56 } | 115 } |
57 | 116 |
58 bool RegisterLibraryLoaderEntryHook(JNIEnv* env) { | 117 bool RegisterLibraryLoaderEntryHook(JNIEnv* env) { |
59 // We need the AtExitManager to be created at the very beginning. | 118 // We need the AtExitManager to be created at the very beginning. |
60 g_at_exit_manager = new base::AtExitManager(); | 119 g_at_exit_manager = new base::AtExitManager(); |
61 | 120 |
62 return RegisterNativesImpl(env); | 121 return RegisterNativesImpl(env); |
63 } | 122 } |
64 | 123 |
65 void SetVersionNumber(const char* version_number) { | 124 void SetVersionNumber(const char* version_number) { |
66 g_library_version_number = strdup(version_number); | 125 g_library_version_number = strdup(version_number); |
67 } | 126 } |
68 | 127 |
69 jstring GetVersionNumber(JNIEnv* env, jclass clazz) { | 128 jstring GetVersionNumber(JNIEnv* env, jclass clazz) { |
70 return ConvertUTF8ToJavaString(env, g_library_version_number).Release(); | 129 return ConvertUTF8ToJavaString(env, g_library_version_number).Release(); |
71 } | 130 } |
72 | 131 |
73 static void RecordNativeLibraryHack(JNIEnv*, jclass, jboolean usedHack) { | 132 static void RecordNativeLibraryHack(JNIEnv*, jclass, jboolean usedHack) { |
74 UMA_HISTOGRAM_BOOLEAN("LibraryLoader.NativeLibraryHack", usedHack); | 133 UMA_HISTOGRAM_BOOLEAN("LibraryLoader.NativeLibraryHack", usedHack); |
75 } | 134 } |
76 | 135 |
77 } // namespace android | 136 } // namespace android |
78 } // namespace base | 137 } // namespace base |
OLD | NEW |