summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authortorne <torne@chromium.org>2015-11-24 02:30:58 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-24 10:31:56 +0000
commit961a488f6a5d8c82b576444054f5d26b3f8a6877 (patch)
tree7aa3fdf6656de41b86f2a17bf3f58a276c2f2c54 /base
parent4bc70b49a4d47fa390b64c93a1dc1c5d99f14c0a (diff)
downloadchromium_src-961a488f6a5d8c82b576444054f5d26b3f8a6877.zip
chromium_src-961a488f6a5d8c82b576444054f5d26b3f8a6877.tar.gz
chromium_src-961a488f6a5d8c82b576444054f5d26b3f8a6877.tar.bz2
Define a Java-side global application context.
Instead of each user of base setting the native-side global app context separately, introduce a Java-side global app context, which is always in sync with the native-side one. Switch most callers to setting it on the Java side, except where this is problematic. Callers of ApplicationStatus.getApplicationContext will be updated incrementally in followup CLs once it's been verified that they only require a Context and not a BaseChromiumApplication. BUG=552419 Review URL: https://codereview.chromium.org/1407233017 Cr-Commit-Position: refs/heads/master@{#361306}
Diffstat (limited to 'base')
-rw-r--r--base/BUILD.gn3
-rw-r--r--base/android/base_jni_registrar.cc5
-rw-r--r--base/android/context_utils.cc58
-rw-r--r--base/android/context_utils.h34
-rw-r--r--base/android/java/src/org/chromium/base/ContextUtils.java56
-rw-r--r--base/android/jni_android.cc18
-rw-r--r--base/android/jni_android.h17
-rw-r--r--base/base.gyp1
-rw-r--r--base/base.gypi2
9 files changed, 161 insertions, 33 deletions
diff --git a/base/BUILD.gn b/base/BUILD.gn
index aabfe67..e9bc061 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -102,6 +102,8 @@ component("base") {
"android/command_line_android.h",
"android/content_uri_utils.cc",
"android/content_uri_utils.h",
+ "android/context_utils.cc",
+ "android/context_utils.h",
"android/cpu_features.cc",
"android/cxa_demangle_stub.cc",
"android/event_log.cc",
@@ -1613,6 +1615,7 @@ if (is_android) {
"android/java/src/org/chromium/base/BuildInfo.java",
"android/java/src/org/chromium/base/CommandLine.java",
"android/java/src/org/chromium/base/ContentUriUtils.java",
+ "android/java/src/org/chromium/base/ContextUtils.java",
"android/java/src/org/chromium/base/CpuFeatures.java",
"android/java/src/org/chromium/base/EventLog.java",
"android/java/src/org/chromium/base/FieldTrialList.java",
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index 752dcff..9ca3ce1 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -10,6 +10,7 @@
#include "base/android/build_info.h"
#include "base/android/command_line_android.h"
#include "base/android/content_uri_utils.h"
+#include "base/android/context_utils.h"
#include "base/android/cpu_features.h"
#include "base/android/event_log.h"
#include "base/android/field_trial_list.h"
@@ -39,13 +40,13 @@ namespace android {
static RegistrationMethod kBaseRegisteredMethods[] = {
{"AnimationFrameTimeHistogram",
base::android::RegisterAnimationFrameTimeHistogram},
- {"ApkAssets",
- base::android::RegisterApkAssets},
+ {"ApkAssets", base::android::RegisterApkAssets},
{"ApplicationStatusListener",
base::android::ApplicationStatusListener::RegisterBindings},
{"BuildInfo", base::android::BuildInfo::RegisterBindings},
{"CommandLine", base::android::RegisterCommandLine},
{"ContentUriUtils", base::RegisterContentUriUtils},
+ {"ContextUtils", base::android::RegisterContextUtils},
{"CpuFeatures", base::android::RegisterCpuFeatures},
{"EventLog", base::android::RegisterEventLog},
{"FieldTrialList", base::android::RegisterFieldTrialList},
diff --git a/base/android/context_utils.cc b/base/android/context_utils.cc
new file mode 100644
index 0000000..5e10f21
--- /dev/null
+++ b/base/android/context_utils.cc
@@ -0,0 +1,58 @@
+// Copyright 2015 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 "base/android/context_utils.h"
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/lazy_instance.h"
+#include "jni/ContextUtils_jni.h"
+
+using base::android::JavaRef;
+
+namespace base {
+namespace android {
+
+namespace {
+
+// Leak the global app context, as it is used from a non-joinable worker thread
+// that may still be running at shutdown. There is no harm in doing this.
+base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject>>::Leaky
+ g_application_context = LAZY_INSTANCE_INITIALIZER;
+
+void SetNativeApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
+ if (env->IsSameObject(g_application_context.Get().obj(), context.obj())) {
+ // It's safe to set the context more than once if it's the same context.
+ return;
+ }
+ DCHECK(g_application_context.Get().is_null());
+ g_application_context.Get().Reset(context);
+}
+
+} // namespace
+
+const jobject GetApplicationContext() {
+ DCHECK(!g_application_context.Get().is_null());
+ return g_application_context.Get().obj();
+}
+
+void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
+ SetNativeApplicationContext(env, context);
+ Java_ContextUtils_initJavaSideApplicationContext(env, context.obj());
+}
+
+static void InitNativeSideApplicationContext(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz,
+ const JavaParamRef<jobject>& context) {
+ SetNativeApplicationContext(env, context);
+}
+
+bool RegisterContextUtils(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/context_utils.h b/base/android/context_utils.h
new file mode 100644
index 0000000..67e6335
--- /dev/null
+++ b/base/android/context_utils.h
@@ -0,0 +1,34 @@
+// Copyright 2015 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 BASE_ANDROID_CONTEXT_UTILS_H_
+#define BASE_ANDROID_CONTEXT_UTILS_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/base_export.h"
+
+namespace base {
+namespace android {
+
+// Gets a global ref to the application context set with
+// InitApplicationContext(). Ownership is retained by the function - the caller
+// must NOT release it.
+const BASE_EXPORT jobject GetApplicationContext();
+
+// Initialize the global application context object.
+// Either this or the Java equivalent ContextUtils.initApplicationContext must
+// be called once during startup. JNI bindings must have been initialized, as
+// the context is stored on both sides.
+BASE_EXPORT void InitApplicationContext(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& context);
+
+bool RegisterContextUtils(JNIEnv* env);
+
+} // namespace android
+} // namespace base
+
+#endif // BASE_ANDROID_CONTEXT_UTILS_H_
diff --git a/base/android/java/src/org/chromium/base/ContextUtils.java b/base/android/java/src/org/chromium/base/ContextUtils.java
new file mode 100644
index 0000000..266e8eb
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/ContextUtils.java
@@ -0,0 +1,56 @@
+// Copyright 2015 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.
+
+package org.chromium.base;
+
+import android.content.Context;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * This class provides Android Context utility methods.
+ */
+@JNINamespace("base::android")
+public class ContextUtils {
+ private static Context sApplicationContext;
+
+ /**
+ * Get the Android application context.
+ *
+ * Under normal circumstances there is only one application context in a process, so it's safe
+ * to treat this as a global. In WebView it's possible for more than one app using WebView to be
+ * running in a single process, but this mechanism is rarely used and this is not the only
+ * problem in that scenario, so we don't currently forbid using it as a global.
+ *
+ * Do not downcast the context returned by this method to Application (or any subclass). It may
+ * not be an Application object; it may be wrapped in a ContextWrapper. The only assumption you
+ * may make is that it is a Context whose lifetime is the same as the lifetime of the process.
+ */
+ public static Context getApplicationContext() {
+ assert sApplicationContext != null;
+ return sApplicationContext;
+ }
+
+ /**
+ * Initialize the Android application context.
+ *
+ * Either this or the native equivalent base::android::InitApplicationContext must be called
+ * once during startup. JNI bindings must have been initialized, as the context is stored on
+ * both sides.
+ */
+ public static void initApplicationContext(Context appContext) {
+ initJavaSideApplicationContext(appContext);
+ nativeInitNativeSideApplicationContext(appContext);
+ }
+
+ @CalledByNative
+ private static void initJavaSideApplicationContext(Context appContext) {
+ assert appContext != null;
+ assert sApplicationContext == null || sApplicationContext == appContext;
+ sApplicationContext = appContext;
+ }
+
+ private static native void nativeInitNativeSideApplicationContext(Context appContext);
+}
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 3db0fc8..d836744 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -20,10 +20,6 @@ using base::android::ScopedJavaLocalRef;
bool g_disable_manual_jni_registration = false;
JavaVM* g_jvm = NULL;
-// Leak the global app context, as it is used from a non-joinable worker thread
-// that may still be running at shutdown. There is no harm in doing this.
-base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
- g_application_context = LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
g_class_loader = LAZY_INSTANCE_INITIALIZER;
jmethodID g_class_loader_load_class_method_id = 0;
@@ -78,15 +74,6 @@ bool IsVMInitialized() {
return g_jvm != NULL;
}
-void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
- if (env->IsSameObject(g_application_context.Get().obj(), context.obj())) {
- // It's safe to set the context more than once if it's the same context.
- return;
- }
- DCHECK(g_application_context.Get().is_null());
- g_application_context.Get().Reset(context);
-}
-
void InitReplacementClassLoader(JNIEnv* env,
const JavaRef<jobject>& class_loader) {
DCHECK(g_class_loader.Get().is_null());
@@ -105,11 +92,6 @@ void InitReplacementClassLoader(JNIEnv* env,
g_class_loader.Get().Reset(class_loader);
}
-const jobject GetApplicationContext() {
- DCHECK(!g_application_context.Get().is_null());
- return g_application_context.Get().obj();
-}
-
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
jclass clazz;
if (!g_class_loader.Get().is_null()) {
diff --git a/base/android/jni_android.h b/base/android/jni_android.h
index 9df9041..651005e 100644
--- a/base/android/jni_android.h
+++ b/base/android/jni_android.h
@@ -10,6 +10,9 @@
#include <string>
+// TODO(torne): remove this when callers of GetApplicationContext have been
+// fixed to include context_utils.h. http://crbug.com/552419
+#include "base/android/context_utils.h"
#include "base/android/scoped_java_ref.h"
#include "base/atomicops.h"
#include "base/base_export.h"
@@ -47,19 +50,12 @@ BASE_EXPORT JNIEnv* AttachCurrentThreadWithName(const std::string& thread_name);
// Detaches the current thread from VM if it is attached.
BASE_EXPORT void DetachFromVM();
-// Initializes the global JVM. It is not necessarily called before
-// InitApplicationContext().
+// Initializes the global JVM.
BASE_EXPORT void InitVM(JavaVM* vm);
// Returns true if the global JVM has been initialized.
BASE_EXPORT bool IsVMInitialized();
-// Initializes the global application context object. The |context| can be any
-// valid reference to the application context. Internally holds a global ref to
-// the context. InitVM and InitApplicationContext maybe called in either order.
-BASE_EXPORT void InitApplicationContext(JNIEnv* env,
- const JavaRef<jobject>& context);
-
// Initializes the global ClassLoader used by the GetClass and LazyGetClass
// methods. This is needed because JNI will use the base ClassLoader when there
// is no Java code on the stack. The base ClassLoader doesn't know about any of
@@ -69,11 +65,6 @@ BASE_EXPORT void InitReplacementClassLoader(
JNIEnv* env,
const JavaRef<jobject>& class_loader);
-// Gets a global ref to the application context set with
-// InitApplicationContext(). Ownership is retained by the function - the caller
-// must NOT release it.
-const BASE_EXPORT jobject GetApplicationContext();
-
// Finds the class named |class_name| and returns it.
// Use this method instead of invoking directly the JNI FindClass method (to
// prevent leaking local references).
diff --git a/base/base.gyp b/base/base.gyp
index 2f8738e..41cc36e 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -1396,6 +1396,7 @@
'android/java/src/org/chromium/base/BuildInfo.java',
'android/java/src/org/chromium/base/CommandLine.java',
'android/java/src/org/chromium/base/ContentUriUtils.java',
+ 'android/java/src/org/chromium/base/ContextUtils.java',
'android/java/src/org/chromium/base/CpuFeatures.java',
'android/java/src/org/chromium/base/EventLog.java',
'android/java/src/org/chromium/base/FieldTrialList.java',
diff --git a/base/base.gypi b/base/base.gypi
index bdaf4c7..4139688 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -34,6 +34,8 @@
'android/command_line_android.h',
'android/content_uri_utils.cc',
'android/content_uri_utils.h',
+ 'android/context_utils.cc',
+ 'android/context_utils.h',
'android/cpu_features.cc',
'android/cxa_demangle_stub.cc',
'android/event_log.cc',