Commit 7aa9ce99 authored by Eric Stevenson's avatar Eric Stevenson Committed by Commit Bot

Android: Convert //base JNI to use @NativeMethods.

Conversion performed via.
  * cd base
  * android/jni_generator/jni_refactorer.py -R --nonstatic
  * Remove unused Java "this" parameters
  * android/jni_generator/jni_refactorer.py -R
  * Fix base natives callers outside //base

See docs linked to from crbug.com/898261 for more info on the project.

Bug: 929661
Change-Id: I68049badf63ca5a307f5dc8304e20fb469ef29b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1695855
Commit-Queue: Eric Stevenson <estevenson@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682705}
parent 42777381
......@@ -3428,6 +3428,7 @@ if (is_android) {
"test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java",
"test/android/javatests/src/org/chromium/base/test/util/parameter/SkipCommandLineParameterization.java",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
android_library("base_java_process_launcher_test_support") {
......
......@@ -16,6 +16,7 @@ import android.view.Window;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
......@@ -579,7 +580,7 @@ public class ApplicationStatus {
sNativeApplicationStateListener = new ApplicationStateListener() {
@Override
public void onApplicationStateChange(int newState) {
nativeOnApplicationStateChange(newState);
ApplicationStatusJni.get().onApplicationStateChange(newState);
}
};
registerApplicationStateListener(sNativeApplicationStateListener);
......@@ -619,7 +620,10 @@ public class ApplicationStatus {
return ApplicationState.HAS_DESTROYED_ACTIVITIES;
}
// Called to notify the native side of state changes.
// IMPORTANT: This is always called on the main thread!
private static native void nativeOnApplicationStateChange(@ApplicationState int newState);
@NativeMethods
interface Natives {
// Called to notify the native side of state changes.
// IMPORTANT: This is always called on the main thread!
void onApplicationStateChange(@ApplicationState int newState);
}
}
......@@ -9,6 +9,7 @@ import android.text.TextUtils;
import android.util.Log;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import java.io.File;
import java.io.FileReader;
......@@ -333,32 +334,32 @@ public abstract class CommandLine {
private static class NativeCommandLine extends CommandLine {
public NativeCommandLine(@Nullable String[] args) {
nativeInit(args);
CommandLineJni.get().init(args);
}
@Override
public boolean hasSwitch(String switchString) {
return nativeHasSwitch(switchString);
return CommandLineJni.get().hasSwitch(switchString);
}
@Override
public String getSwitchValue(String switchString) {
return nativeGetSwitchValue(switchString);
return CommandLineJni.get().getSwitchValue(switchString);
}
@Override
public void appendSwitch(String switchString) {
nativeAppendSwitch(switchString);
CommandLineJni.get().appendSwitch(switchString);
}
@Override
public void appendSwitchWithValue(String switchString, String value) {
nativeAppendSwitchWithValue(switchString, value);
CommandLineJni.get().appendSwitchWithValue(switchString, value);
}
@Override
public void appendSwitchesAndArguments(String[] array) {
nativeAppendSwitchesAndArguments(array);
CommandLineJni.get().appendSwitchesAndArguments(array);
}
@Override
......@@ -380,10 +381,13 @@ public abstract class CommandLine {
}
}
private static native void nativeInit(String[] args);
private static native boolean nativeHasSwitch(String switchString);
private static native String nativeGetSwitchValue(String switchString);
private static native void nativeAppendSwitch(String switchString);
private static native void nativeAppendSwitchWithValue(String switchString, String value);
private static native void nativeAppendSwitchesAndArguments(String[] array);
@NativeMethods
interface Natives {
void init(String[] args);
boolean hasSwitch(String switchString);
String getSwitchValue(String switchString);
void appendSwitch(String switchString);
void appendSwitchWithValue(String switchString, String value);
void appendSwitchesAndArguments(String[] array);
}
}
......@@ -5,6 +5,7 @@
package org.chromium.base;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
// The only purpose of this class is to allow sending CPU properties
// from the browser process to sandboxed renderer processes. This is
......@@ -25,7 +26,7 @@ public abstract class CpuFeatures {
* Return the number of CPU Cores on the device.
*/
public static int getCount() {
return nativeGetCoreCount();
return CpuFeaturesJni.get().getCoreCount();
}
/**
......@@ -34,9 +35,12 @@ public abstract class CpuFeatures {
* The value comes directly from android_getCpuFeatures().
*/
public static long getMask() {
return nativeGetCpuFeatures();
return CpuFeaturesJni.get().getCpuFeatures();
}
private static native int nativeGetCoreCount();
private static native long nativeGetCpuFeatures();
@NativeMethods
interface Natives {
int getCoreCount();
long getCpuFeatures();
}
}
......@@ -13,6 +13,7 @@ import android.os.SystemClock;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import java.io.File;
import java.util.ArrayList;
......@@ -313,7 +314,7 @@ public class EarlyTraceEvent {
private static void dumpEvents(List<Event> events) {
long offsetNanos = getOffsetNanos();
for (Event e : events) {
nativeRecordEarlyEvent(e.mName, e.mBeginTimeNanos + offsetNanos,
EarlyTraceEventJni.get().recordEarlyEvent(e.mName, e.mBeginTimeNanos + offsetNanos,
e.mEndTimeNanos + offsetNanos, e.mThreadId,
e.mEndThreadTimeMillis - e.mBeginThreadTimeMillis);
}
......@@ -322,15 +323,17 @@ public class EarlyTraceEvent {
long offsetNanos = getOffsetNanos();
for (AsyncEvent e : events) {
if (e.mIsStart) {
nativeRecordEarlyStartAsyncEvent(e.mName, e.mId, e.mTimestampNanos + offsetNanos);
EarlyTraceEventJni.get().recordEarlyStartAsyncEvent(
e.mName, e.mId, e.mTimestampNanos + offsetNanos);
} else {
nativeRecordEarlyFinishAsyncEvent(e.mName, e.mId, e.mTimestampNanos + offsetNanos);
EarlyTraceEventJni.get().recordEarlyFinishAsyncEvent(
e.mName, e.mId, e.mTimestampNanos + offsetNanos);
}
}
}
private static long getOffsetNanos() {
long nativeNowNanos = TimeUtils.nativeGetTimeTicksNowUs() * 1000;
long nativeNowNanos = TimeUtilsJni.get().getTimeTicksNowUs() * 1000;
long javaNowNanos = Event.elapsedRealtimeNanos();
return nativeNowNanos - javaNowNanos;
}
......@@ -345,10 +348,11 @@ public class EarlyTraceEvent {
return name + "@" + Process.myTid();
}
private static native void nativeRecordEarlyEvent(String name, long beginTimNanos,
long endTimeNanos, int threadId, long threadDurationMillis);
private static native void nativeRecordEarlyStartAsyncEvent(
String name, long id, long timestamp);
private static native void nativeRecordEarlyFinishAsyncEvent(
String name, long id, long timestamp);
@NativeMethods
interface Natives {
void recordEarlyEvent(String name, long beginTimNanos, long endTimeNanos, int threadId,
long threadDurationMillis);
void recordEarlyStartAsyncEvent(String name, long id, long timestamp);
void recordEarlyFinishAsyncEvent(String name, long id, long timestamp);
}
}
......@@ -5,6 +5,7 @@
package org.chromium.base;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
/**
* Helper to get field trial information.
......@@ -20,7 +21,7 @@ public class FieldTrialList {
* not exist.
*/
public static String findFullName(String trialName) {
return nativeFindFullName(trialName);
return FieldTrialListJni.get().findFullName(trialName);
}
/**
......@@ -28,7 +29,7 @@ public class FieldTrialList {
* @return Whether the trial exists or not.
*/
public static boolean trialExists(String trialName) {
return nativeTrialExists(trialName);
return FieldTrialListJni.get().trialExists(trialName);
}
/**
......@@ -37,7 +38,7 @@ public class FieldTrialList {
* @return The value of the parameter or an empty string if not found.
*/
public static String getVariationParameter(String trialName, String parameterKey) {
return nativeGetVariationParameter(trialName, parameterKey);
return FieldTrialListJni.get().getVariationParameter(trialName, parameterKey);
}
/**
......@@ -45,11 +46,14 @@ public class FieldTrialList {
* prtinting new trials as they become active. This should be called at most once.
*/
public static void logActiveTrials() {
nativeLogActiveTrials();
FieldTrialListJni.get().logActiveTrials();
}
private static native String nativeFindFullName(String trialName);
private static native boolean nativeTrialExists(String trialName);
private static native String nativeGetVariationParameter(String trialName, String parameterKey);
private static native void nativeLogActiveTrials();
@NativeMethods
interface Natives {
String findFullName(String trialName);
boolean trialExists(String trialName);
String getVariationParameter(String trialName, String parameterKey);
void logActiveTrials();
}
}
......@@ -5,6 +5,7 @@
package org.chromium.base;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* This class provides an interface to the native class for writing
......@@ -23,9 +24,11 @@ public class ImportantFileWriterAndroid {
* @return true if the data was written to the file, false if not.
*/
public static boolean writeFileAtomically(String fileName, byte[] data) {
return nativeWriteFileAtomically(fileName, data);
return ImportantFileWriterAndroidJni.get().writeFileAtomically(fileName, data);
}
private static native boolean nativeWriteFileAtomically(
String fileName, byte[] data);
@NativeMethods
interface Natives {
boolean writeFileAtomically(String fileName, byte[] data);
}
}
......@@ -9,6 +9,7 @@ import android.support.annotation.UiThread;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
/**
* This UncaughtExceptionHandler will create a breakpad minidump when there is an uncaught
......@@ -34,7 +35,7 @@ public class JavaExceptionReporter implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
if (!mHandlingException) {
mHandlingException = true;
nativeReportJavaException(mCrashAfterReport, e);
JavaExceptionReporterJni.get().reportJavaException(mCrashAfterReport, e);
}
if (mParent != null) {
mParent.uncaughtException(t, e);
......@@ -51,7 +52,8 @@ public class JavaExceptionReporter implements Thread.UncaughtExceptionHandler {
@UiThread
public static void reportStackTrace(String stackTrace) {
assert ThreadUtils.runningOnUiThread();
nativeReportJavaStackTrace(PiiElider.sanitizeStacktrace(stackTrace));
JavaExceptionReporterJni.get().reportJavaStackTrace(
PiiElider.sanitizeStacktrace(stackTrace));
}
@CalledByNative
......@@ -60,6 +62,9 @@ public class JavaExceptionReporter implements Thread.UncaughtExceptionHandler {
Thread.getDefaultUncaughtExceptionHandler(), crashAfterReport));
}
private static native void nativeReportJavaException(boolean crashAfterReport, Throwable e);
private static native void nativeReportJavaStackTrace(String stackTrace);
@NativeMethods
interface Natives {
void reportJavaException(boolean crashAfterReport, Throwable e);
void reportJavaStackTrace(String stackTrace);
}
}
......@@ -12,6 +12,7 @@ import android.os.Looper;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import java.lang.Thread.UncaughtExceptionHandler;
......@@ -54,7 +55,7 @@ public class JavaHandlerThread {
new Handler(mThread.getLooper()).post(new Runnable() {
@Override
public void run() {
nativeInitializeThread(nativeThread, nativeEvent);
JavaHandlerThreadJni.get().initializeThread(nativeThread, nativeEvent);
}
});
}
......@@ -66,7 +67,7 @@ public class JavaHandlerThread {
@Override
public void run() {
mThread.quit();
nativeOnLooperStopped(nativeThread);
JavaHandlerThreadJni.get().onLooperStopped(nativeThread);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
......@@ -114,6 +115,9 @@ public class JavaHandlerThread {
return mUnhandledException;
}
private native void nativeInitializeThread(long nativeJavaHandlerThread, long nativeEvent);
private native void nativeOnLooperStopped(long nativeJavaHandlerThread);
@NativeMethods
interface Natives {
void initializeThread(long nativeJavaHandlerThread, long nativeEvent);
void onLooperStopped(long nativeJavaHandlerThread);
}
}
......@@ -9,6 +9,7 @@ import android.content.ComponentCallbacks2;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.memory.MemoryPressureCallback;
/**
......@@ -59,7 +60,7 @@ public class MemoryPressureListener {
*/
@CalledByNative
private static void addNativeCallback() {
addCallback(MemoryPressureListener::nativeOnMemoryPressure);
addCallback(MemoryPressureListenerJni.get()::onMemoryPressure);
}
/**
......@@ -126,5 +127,8 @@ public class MemoryPressureListener {
activity.onTrimMemory(level);
}
private static native void nativeOnMemoryPressure(@MemoryPressureLevel int pressure);
@NativeMethods
interface Natives {
void onMemoryPressure(@MemoryPressureLevel int pressure);
}
}
......@@ -5,6 +5,7 @@
package org.chromium.base;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* This class provides java side access to the native PathService.
......@@ -19,8 +20,11 @@ public abstract class PathService {
private PathService() {}
public static void override(int what, String path) {
nativeOverride(what, path);
PathServiceJni.get().override(what, path);
}
private static native void nativeOverride(int what, String path);
@NativeMethods
interface Natives {
void override(int what, String path);
}
}
......@@ -12,6 +12,7 @@ import android.os.BatteryManager;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* Integrates native PowerMonitor with the java side.
......@@ -63,7 +64,7 @@ public class PowerMonitor {
// If we're not plugged, assume we're running on battery power.
sInstance.mIsBatteryPower = chargePlug != BatteryManager.BATTERY_PLUGGED_USB
&& chargePlug != BatteryManager.BATTERY_PLUGGED_AC;
nativeOnBatteryChargingChanged();
PowerMonitorJni.get().onBatteryChargingChanged();
}
@CalledByNative
......@@ -76,5 +77,8 @@ public class PowerMonitor {
return sInstance.mIsBatteryPower;
}
private static native void nativeOnBatteryChargingChanged();
@NativeMethods
interface Natives {
void onBatteryChargingChanged();
}
}
......@@ -16,6 +16,7 @@ import android.util.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.metrics.CachedMetrics;
import java.io.BufferedReader;
......@@ -200,11 +201,9 @@ public class SysUtils {
* enabled.
*/
public static void logPageFaultCountToTracing() {
nativeLogPageFaultCountToTracing();
SysUtilsJni.get().logPageFaultCountToTracing();
}
private static native void nativeLogPageFaultCountToTracing();
/**
* @return Whether or not this device should be considered a high end device from a disk
* capacity point of view.
......@@ -226,4 +225,9 @@ public class SysUtils {
}
return false;
}
@NativeMethods
interface Natives {
void logPageFaultCountToTracing();
}
}
......@@ -6,6 +6,7 @@ package org.chromium.base;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
/** Time-related utilities. */
@JNINamespace("base::android")
......@@ -17,8 +18,13 @@ public class TimeUtils {
public static final int NANOSECONDS_PER_MILLISECOND = 1000000;
public static final int SECONDS_PER_MINUTE = 60;
public static final int SECONDS_PER_HOUR = 3600; // 60 sec * 60 min
public static final int SECONDS_PER_DAY = 86400; // 60 sec * 60 min * 24 h
public static final int SECONDS_PER_DAY = 86400;
/** Returns TimeTicks::Now() in microseconds. */
public static native long nativeGetTimeTicksNowUs();
@NativeMethods
public interface Natives {
// 60 sec * 60 min * 24 h
/** Returns TimeTicks::Now() in microseconds. */
long getTimeTicksNowUs();
}
}
......@@ -13,6 +13,7 @@ import android.util.Printer;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
/**
* Java mirror of Chrome trace event API. See base/trace_event/trace_event.h.
*
......@@ -57,7 +58,7 @@ public class TraceEvent implements AutoCloseable {
if (sEnabled || earlyTracingActive) {
mCurrentTarget = getTraceEventName(line);
if (sEnabled) {
nativeBeginToplevel(mCurrentTarget);
TraceEventJni.get().beginToplevel(mCurrentTarget);
} else {
EarlyTraceEvent.begin(mCurrentTarget);
}
......@@ -68,7 +69,7 @@ public class TraceEvent implements AutoCloseable {
boolean earlyTracingActive = EarlyTraceEvent.isActive();
if ((sEnabled || earlyTracingActive) && mCurrentTarget != null) {
if (sEnabled) {
nativeEndToplevel(mCurrentTarget);
TraceEventJni.get().endToplevel(mCurrentTarget);
} else {
EarlyTraceEvent.end(mCurrentTarget);
}
......@@ -270,7 +271,7 @@ public class TraceEvent implements AutoCloseable {
* Register an enabled observer, such that java traces are always enabled with native.
*/
public static void registerNativeEnabledObserver() {
nativeRegisterEnabledObserver();
TraceEventJni.get().registerEnabledObserver();
}
/**
......@@ -314,11 +315,11 @@ public class TraceEvent implements AutoCloseable {
if (enabled) {
// Calls TraceEvent.setEnabled(true) via
// TraceLog::EnabledStateObserver::OnTraceLogEnabled
nativeStartATrace();
TraceEventJni.get().startATrace();
} else {
// Calls TraceEvent.setEnabled(false) via
// TraceLog::EnabledStateObserver::OnTraceLogDisabled
nativeStopATrace();
TraceEventJni.get().stopATrace();
}
}
......@@ -336,7 +337,7 @@ public class TraceEvent implements AutoCloseable {
* @param name The name of the event.
*/
public static void instant(String name) {
if (sEnabled) nativeInstant(name, null);
if (sEnabled) TraceEventJni.get().instant(name, null);
}
/**
......@@ -345,7 +346,7 @@ public class TraceEvent implements AutoCloseable {
* @param arg The arguments of the event.
*/
public static void instant(String name, String arg) {
if (sEnabled) nativeInstant(name, arg);
if (sEnabled) TraceEventJni.get().instant(name, arg);
}
/**
......@@ -355,7 +356,7 @@ public class TraceEvent implements AutoCloseable {
*/
public static void startAsync(String name, long id) {
EarlyTraceEvent.startAsync(name, id);
if (sEnabled) nativeStartAsync(name, id);
if (sEnabled) TraceEventJni.get().startAsync(name, id);
}
/**
......@@ -365,7 +366,7 @@ public class TraceEvent implements AutoCloseable {
*/
public static void finishAsync(String name, long id) {
EarlyTraceEvent.finishAsync(name, id);
if (sEnabled) nativeFinishAsync(name, id);
if (sEnabled) TraceEventJni.get().finishAsync(name, id);
}
/**
......@@ -383,7 +384,7 @@ public class TraceEvent implements AutoCloseable {
*/
public static void begin(String name, String arg) {
EarlyTraceEvent.begin(name);
if (sEnabled) nativeBegin(name, arg);
if (sEnabled) TraceEventJni.get().begin(name, arg);
}
/**
......@@ -401,17 +402,20 @@ public class TraceEvent implements AutoCloseable {
*/
public static void end(String name, String arg) {
EarlyTraceEvent.end(name);
if (sEnabled) nativeEnd(name, arg);
if (sEnabled) TraceEventJni.get().end(name, arg);
}
private static native void nativeRegisterEnabledObserver();
private static native void nativeStartATrace();
private static native void nativeStopATrace();
private static native void nativeInstant(String name, String arg);
private static native void nativeBegin(String name, String arg);
private static native void nativeEnd(String name, String arg);
private static native void nativeBeginToplevel(String target);
private static native void nativeEndToplevel(String target);
private static native void nativeStartAsync(String name, long id);
private static native void nativeFinishAsync(String name, long id);
@NativeMethods
interface Natives {
void registerEnabledObserver();
void startATrace();
void stopATrace();
void instant(String name, String arg);
void begin(String name, String arg);
void end(String name, String arg);
void beginToplevel(String target);
void endToplevel(String target);
void startAsync(String name, long id);
void finishAsync(String name, long id);
}
}
......@@ -28,6 +28,7 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.compat.ApiHelperForM;
import org.chromium.base.metrics.CachedMetrics;
import org.chromium.base.metrics.RecordHistogram;
......@@ -89,7 +90,7 @@ public class LibraryLoader {
private static LibraryLoader sInstance = new LibraryLoader();
// One-way switch becomes true when the libraries are initialized (
// by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in
// by calling LibraryLoaderJni.get().libraryLoaded, which forwards to LibraryLoaded(...) in
// library_loader_hooks.cc).
// Note that this member should remain a one-way switch, since it accessed from multiple
// threads without a lock.
......@@ -513,16 +514,17 @@ public class LibraryLoader {
ensureCommandLineSwitchedAlreadyLocked();
if (!nativeLibraryLoaded(mLibraryProcessType)) {
Log.e(TAG, "error calling nativeLibraryLoaded");
if (!LibraryLoaderJni.get().libraryLoaded(mLibraryProcessType)) {
Log.e(TAG, "error calling LibraryLoaderJni.get().libraryLoaded");
throw new ProcessInitException(LoaderErrors.LOADER_ERROR_FAILED_TO_REGISTER_JNI);
}
// Check that the version of the library we have loaded matches the version we expect
Log.i(TAG, String.format("Expected native library version number \"%s\", "
+ "actual native library version number \"%s\"",
NativeLibraries.sVersionNumber, nativeGetVersionNumber()));
if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) {
Log.i(TAG,
String.format("Expected native library version number \"%s\", "
+ "actual native library version number \"%s\"",
NativeLibraries.sVersionNumber, LibraryLoaderJni.get().getVersionNumber()));
if (!NativeLibraries.sVersionNumber.equals(LibraryLoaderJni.get().getVersionNumber())) {
throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_WRONG_VERSION);
}
......@@ -584,7 +586,7 @@ public class LibraryLoader {
public void registerRendererProcessHistogram() {
synchronized (mLock) {
if (useChromiumLinker()) {
nativeRecordRendererLibraryLoadTime(mLibraryLoadTimeMs);
LibraryLoaderJni.get().recordRendererLibraryLoadTime(mLibraryLoadTimeMs);
}
}
}
......@@ -685,18 +687,21 @@ public class LibraryLoader {
ContextCompat.getCodeCacheDir(ContextUtils.getApplicationContext()), LIBRARY_DIR);
}
// Only methods needed before or during normal JNI registration are during System.OnLoad.
// nativeLibraryLoaded is then called to register everything else. This process is called
// "initialization". This method will be mapped (by generated code) to the LibraryLoaded
// definition in base/android/library_loader/library_loader_hooks.cc.
//
// Return true on success and false on failure.
private native boolean nativeLibraryLoaded(@LibraryProcessType int processType);
@NativeMethods
interface Natives {
// Only methods needed before or during normal JNI registration are during System.OnLoad.
// nativeLibraryLoaded is then called to register everything else. This process is called
// "initialization". This method will be mapped (by generated code) to the LibraryLoaded
// definition in base/android/library_loader/library_loader_hooks.cc.
//
// Return true on success and false on failure.
boolean libraryLoaded(@LibraryProcessType int processType);
// Records the number of milliseconds it took to load the libraries in the renderer.
private native void nativeRecordRendererLibraryLoadTime(long libraryLoadTime);
// Records the number of milliseconds it took to load the libraries in the renderer.
void recordRendererLibraryLoadTime(long libraryLoadTime);
// Get the version of the native library. This is needed so that we can check we
// have the right version before initializing the (rest of the) JNI.
private native String nativeGetVersionNumber();
// Get the version of the native library. This is needed so that we can check we
// have the right version before initializing the (rest of the) JNI.
String getVersionNumber();
}
}
......@@ -15,6 +15,7 @@ import org.chromium.base.TraceEvent;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
......@@ -35,7 +36,7 @@ public class LibraryPrefetcher {
/**
* Used to pass ordered code info back from native.
*/
private final static class OrderedCodeInfo {
final static class OrderedCodeInfo {
public final String filename;
public final long startOffset;
public final long length;
......@@ -77,21 +78,21 @@ public class LibraryPrefetcher {
// to be simultaneous with it. Also, don't prefetch in this case, as this would
// skew the results.
if (coldStart && CommandLine.getInstance().hasSwitch("log-native-library-residency")) {
// nativePeriodicallyCollectResidency() sleeps, run it on another thread,
// and not on the thread pool.
new Thread(LibraryPrefetcher::nativePeriodicallyCollectResidency).start();
// LibraryPrefetcherJni.get().periodicallyCollectResidency() sleeps, run it on another
// thread, and not on the thread pool.
new Thread(LibraryPrefetcherJni.get()::periodicallyCollectResidency).start();
return;
}
PostTask.postTask(TaskTraits.USER_BLOCKING, () -> {
int percentage = nativePercentageOfResidentNativeLibraryCode();
int percentage = LibraryPrefetcherJni.get().percentageOfResidentNativeLibraryCode();
try (TraceEvent e =
TraceEvent.scoped("LibraryPrefetcher.asyncPrefetchLibrariesToMemory",
Integer.toString(percentage))) {
// Arbitrary percentage threshold. If most of the native library is already
// resident (likely with monochrome), don't bother creating a prefetch process.
boolean prefetch = coldStart && percentage < 90;
if (prefetch) nativeForkAndPrefetchNativeLibrary();
if (prefetch) LibraryPrefetcherJni.get().forkAndPrefetchNativeLibrary();
if (percentage != -1) {
String histogram = "LibraryLoader.PercentageOfResidentCodeBeforePrefetch"
+ (coldStart ? ".ColdStartup" : ".WarmStartup");
......@@ -107,7 +108,7 @@ public class LibraryPrefetcher {
@SuppressLint("WrongConstant")
public static void maybePinOrderedCodeInMemory() {
try (TraceEvent e = TraceEvent.scoped("LibraryPrefetcher::maybePinOrderedCodeInMemory")) {
OrderedCodeInfo info = nativeGetOrderedCodeInfo();
OrderedCodeInfo info = LibraryPrefetcherJni.get().getOrderedCodeInfo();
if (info == null) return;
TraceEvent.instant("pinOrderedCodeInMemory", info.toString());
......@@ -137,19 +138,22 @@ public class LibraryPrefetcher {
}
}
// Finds the ranges corresponding to the native library pages, forks a new
// process to prefetch these pages and waits for it. The new process then
// terminates. This is blocking.
private static native void nativeForkAndPrefetchNativeLibrary();
@NativeMethods
interface Natives {
// Finds the ranges corresponding to the native library pages, forks a new
// process to prefetch these pages and waits for it. The new process then
// terminates. This is blocking.
void forkAndPrefetchNativeLibrary();
// Returns the percentage of the native library code page that are currently reseident in
// memory.
private static native int nativePercentageOfResidentNativeLibraryCode();
// Returns the percentage of the native library code page that are currently reseident in
// memory.
int percentageOfResidentNativeLibraryCode();
// Periodically logs native library residency from this thread.
private static native void nativePeriodicallyCollectResidency();
// Periodically logs native library residency from this thread.
void periodicallyCollectResidency();
// Returns the range within a file of the ordered code section, or null if this is not
// available.
private static native OrderedCodeInfo nativeGetOrderedCodeInfo();
// Returns the range within a file of the ordered code section, or null if this is not
// available.
OrderedCodeInfo getOrderedCodeInfo();
}
}
......@@ -9,6 +9,7 @@ import android.text.format.DateUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import java.util.Collections;
import java.util.HashMap;
......@@ -66,7 +67,7 @@ public class RecordHistogram {
public static void recordBooleanHistogram(String name, boolean sample) {
if (sDisabledBy != null) return;
long key = getCachedHistogramKey(name);
long result = nativeRecordBooleanHistogram(name, key, sample);
long result = RecordHistogramJni.get().recordBooleanHistogram(name, key, sample);
if (result != key) sCache.put(name, result);
}
......@@ -82,7 +83,8 @@ public class RecordHistogram {
public static void recordEnumeratedHistogram(String name, int sample, int boundary) {
if (sDisabledBy != null) return;
long key = getCachedHistogramKey(name);
long result = nativeRecordEnumeratedHistogram(name, key, sample, boundary);
long result =
RecordHistogramJni.get().recordEnumeratedHistogram(name, key, sample, boundary);
if (result != key) sCache.put(name, result);
}
......@@ -129,7 +131,8 @@ public class RecordHistogram {
String name, int sample, int min, int max, int numBuckets) {
if (sDisabledBy != null) return;
long key = getCachedHistogramKey(name);
long result = nativeRecordCustomCountHistogram(name, key, sample, min, max, numBuckets);
long result = RecordHistogramJni.get().recordCustomCountHistogram(
name, key, sample, min, max, numBuckets);
if (result != key) sCache.put(name, result);
}
......@@ -146,7 +149,8 @@ public class RecordHistogram {
String name, int sample, int min, int max, int numBuckets) {
if (sDisabledBy != null) return;
long key = getCachedHistogramKey(name);
long result = nativeRecordLinearCountHistogram(name, key, sample, min, max, numBuckets);
long result = RecordHistogramJni.get().recordLinearCountHistogram(
name, key, sample, min, max, numBuckets);
if (result != key) sCache.put(name, result);
}
......@@ -159,7 +163,7 @@ public class RecordHistogram {
public static void recordPercentageHistogram(String name, int sample) {
if (sDisabledBy != null) return;
long key = getCachedHistogramKey(name);
long result = nativeRecordEnumeratedHistogram(name, key, sample, 101);
long result = RecordHistogramJni.get().recordEnumeratedHistogram(name, key, sample, 101);
if (result != key) sCache.put(name, result);
}
......@@ -172,7 +176,7 @@ public class RecordHistogram {
public static void recordSparseHistogram(String name, int sample) {
if (sDisabledBy != null) return;
long key = getCachedHistogramKey(name);
long result = nativeRecordSparseHistogram(name, key, sample);
long result = RecordHistogramJni.get().recordSparseHistogram(name, key, sample);
if (result != key) sCache.put(name, result);
}
......@@ -267,7 +271,7 @@ public class RecordHistogram {
// the types returned by TimeUnit and System.currentTimeMillis() APIs, from which these
// values come.
assert max == clampToInt(max);
long result = nativeRecordCustomTimesHistogramMilliseconds(
long result = RecordHistogramJni.get().recordCustomTimesHistogramMilliseconds(
name, key, clampToInt(duration), clampToInt(min), clampToInt(max), numBuckets);
if (result != key) sCache.put(name, result);
}
......@@ -279,7 +283,7 @@ public class RecordHistogram {
*/
@VisibleForTesting
public static int getHistogramValueCountForTesting(String name, int sample) {
return nativeGetHistogramValueCountForTesting(name, sample);
return RecordHistogramJni.get().getHistogramValueCountForTesting(name, sample);
}
/**
......@@ -288,21 +292,21 @@ public class RecordHistogram {
*/
@VisibleForTesting
public static int getHistogramTotalCountForTesting(String name) {
return nativeGetHistogramTotalCountForTesting(name);
return RecordHistogramJni.get().getHistogramTotalCountForTesting(name);
}
private static native long nativeRecordCustomTimesHistogramMilliseconds(
String name, long key, int duration, int min, int max, int numBuckets);
private static native long nativeRecordBooleanHistogram(String name, long key, boolean sample);
private static native long nativeRecordEnumeratedHistogram(
String name, long key, int sample, int boundary);
private static native long nativeRecordCustomCountHistogram(
String name, long key, int sample, int min, int max, int numBuckets);
private static native long nativeRecordLinearCountHistogram(
String name, long key, int sample, int min, int max, int numBuckets);
private static native long nativeRecordSparseHistogram(String name, long key, int sample);
private static native int nativeGetHistogramValueCountForTesting(String name, int sample);
private static native int nativeGetHistogramTotalCountForTesting(String name);
@NativeMethods
public interface Natives {
long recordCustomTimesHistogramMilliseconds(
String name, long key, int duration, int min, int max, int numBuckets);
long recordBooleanHistogram(String name, long key, boolean sample);
long recordEnumeratedHistogram(String name, long key, int sample, int boundary);
long recordCustomCountHistogram(
String name, long key, int sample, int min, int max, int numBuckets);
long recordLinearCountHistogram(
String name, long key, int sample, int min, int max, int numBuckets);
long recordSparseHistogram(String name, long key, int sample);
int getHistogramValueCountForTesting(String name, int sample);
int getHistogramTotalCountForTesting(String name);
}
}
......@@ -8,6 +8,7 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* Java API for recording UMA actions.
......@@ -38,14 +39,14 @@ public class RecordUserAction {
if (sDisabledBy != null) return;
if (ThreadUtils.runningOnUiThread()) {
nativeRecordUserAction(action);
RecordUserActionJni.get().recordUserAction(action);
return;
}
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
nativeRecordUserAction(action);
RecordUserActionJni.get().recordUserAction(action);
}
});
}
......@@ -67,7 +68,7 @@ public class RecordUserAction {
*/
public static void setActionCallbackForTesting(UserActionCallback callback) {
assert sNativeActionCallback == 0;
sNativeActionCallback = nativeAddActionCallbackForTesting(callback);
sNativeActionCallback = RecordUserActionJni.get().addActionCallbackForTesting(callback);
}
/**
......@@ -75,11 +76,14 @@ public class RecordUserAction {
*/
public static void removeActionCallbackForTesting() {
assert sNativeActionCallback != 0;
nativeRemoveActionCallbackForTesting(sNativeActionCallback);
RecordUserActionJni.get().removeActionCallbackForTesting(sNativeActionCallback);
sNativeActionCallback = 0;
}
private static native void nativeRecordUserAction(String action);
private static native long nativeAddActionCallbackForTesting(UserActionCallback callback);
private static native void nativeRemoveActionCallbackForTesting(long callbackId);
@NativeMethods
interface Natives {
void recordUserAction(String action);
long addActionCallbackForTesting(UserActionCallback callback);
void removeActionCallbackForTesting(long callbackId);
}
}
......@@ -5,6 +5,7 @@
package org.chromium.base.metrics;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* Java API which exposes the registered histograms on the native side as
......@@ -20,8 +21,11 @@ public final class StatisticsRecorderAndroid {
* @return All the registered histograms as JSON text.
*/
public static String toJson(@JSONVerbosityLevel int verbosityLevel) {
return nativeToJson(verbosityLevel);
return StatisticsRecorderAndroidJni.get().toJson(verbosityLevel);
}
private static native String nativeToJson(@JSONVerbosityLevel int verbosityLevel);
@NativeMethods
interface Natives {
String toJson(@JSONVerbosityLevel int verbosityLevel);
}
}
\ No newline at end of file
......@@ -24,6 +24,7 @@ import org.chromium.base.MemoryPressureLevel;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.memory.MemoryPressureMonitor;
import java.util.List;
......@@ -172,7 +173,7 @@ public abstract class ChildProcessService extends Service {
return;
}
}
nativeDumpProcessStack();
ChildProcessServiceJni.get().dumpProcessStack();
}
};
......@@ -253,7 +254,8 @@ public abstract class ChildProcessService extends Service {
regionOffsets[i] = fdInfo.offset;
regionSizes[i] = fdInfo.size;
}
nativeRegisterFileDescriptors(keys, fileIds, fds, regionOffsets, regionSizes);
ChildProcessServiceJni.get().registerFileDescriptors(
keys, fileIds, fds, regionOffsets, regionSizes);
mDelegate.onBeforeMain();
mDelegate.runMain();
......@@ -262,7 +264,7 @@ public abstract class ChildProcessService extends Service {
} catch (RemoteException e) {
Log.e(TAG, "Failed to call clean exit callback.", e);
}
nativeExitChildProcess();
ChildProcessServiceJni.get().exitChildProcess();
} catch (InterruptedException e) {
Log.w(TAG, "%s startup failed: %s", MAIN_THREAD_NAME, e);
}
......@@ -331,22 +333,24 @@ public abstract class ChildProcessService extends Service {
}
}
/**
* Helper for registering FileDescriptorInfo objects with GlobalFileDescriptors or
* FileDescriptorStore.
* This includes the IPC channel, the crash dump signals and resource related
* files.
*/
private static native void nativeRegisterFileDescriptors(
String[] keys, int[] id, int[] fd, long[] offset, long[] size);
/**
* Force the child process to exit.
*/
private static native void nativeExitChildProcess();
/**
* Dumps the child process stack without crashing it.
*/
private static native void nativeDumpProcessStack();
@NativeMethods
interface Natives {
/**
* Helper for registering FileDescriptorInfo objects with GlobalFileDescriptors or
* FileDescriptorStore.
* This includes the IPC channel, the crash dump signals and resource related
* files.
*/
void registerFileDescriptors(String[] keys, int[] id, int[] fd, long[] offset, long[] size);
/**
* Force the child process to exit.
*/
void exitChildProcess();
/**
* Dumps the child process stack without crashing it.
*/
void dumpProcessStack();
}
}
......@@ -6,6 +6,7 @@ package org.chromium.base.task;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import java.util.Collections;
import java.util.Set;
......@@ -85,9 +86,9 @@ public class PostTask {
if (sPreNativeTaskRunners != null || taskTraits.mIsChoreographerFrame) {
getTaskExecutorForTraits(taskTraits).postDelayedTask(taskTraits, task, delay);
} else {
nativePostDelayedTask(taskTraits.mPrioritySetExplicitly, taskTraits.mPriority,
taskTraits.mMayBlock, taskTraits.mUseThreadPool, taskTraits.mExtensionId,
taskTraits.mExtensionData, task, delay);
PostTaskJni.get().postDelayedTask(taskTraits.mPrioritySetExplicitly,
taskTraits.mPriority, taskTraits.mMayBlock, taskTraits.mUseThreadPool,
taskTraits.mExtensionId, taskTraits.mExtensionData, task, delay);
}
}
}
......@@ -256,7 +257,10 @@ public class PostTask {
}
}
private static native void nativePostDelayedTask(boolean prioritySetExplicitly, int priority,
boolean mayBlock, boolean useThreadPool, byte extensionId, byte[] extensionData,
Runnable task, long delay);
@NativeMethods
interface Natives {
void postDelayedTask(boolean prioritySetExplicitly, int priority, boolean mayBlock,
boolean useThreadPool, byte extensionId, byte[] extensionData, Runnable task,
long delay);
}
}
......@@ -47,7 +47,7 @@ public class SingleThreadTaskRunnerImpl extends TaskRunnerImpl implements Single
public boolean belongsToCurrentThread() {
synchronized (mLock) {
if (mNativeTaskRunnerAndroid != 0)
return nativeBelongsToCurrentThread(mNativeTaskRunnerAndroid);
return TaskRunnerImplJni.get().belongsToCurrentThread(mNativeTaskRunnerAndroid);
}
if (mHandler != null) return mHandler.getLooper().getThread() == Thread.currentThread();
assert (false);
......
......@@ -11,6 +11,7 @@ import android.util.Pair;
import org.chromium.base.LifetimeAssert;
import org.chromium.base.TraceEvent;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import java.util.ArrayList;
import java.util.LinkedList;
......@@ -72,7 +73,8 @@ public class TaskRunnerImpl implements TaskRunner {
@GuardedBy("mLock")
protected void destroyInternal() {
if (mNativeTaskRunnerAndroid != 0) nativeDestroy(mNativeTaskRunnerAndroid);
if (mNativeTaskRunnerAndroid != 0)
TaskRunnerImplJni.get().destroy(mNativeTaskRunnerAndroid);
mNativeTaskRunnerAndroid = 0;
}
......@@ -158,7 +160,7 @@ public class TaskRunnerImpl implements TaskRunner {
@GuardedBy("mLock")
protected void initNativeTaskRunnerInternal() {
if (mNativeTaskRunnerAndroid == 0) {
mNativeTaskRunnerAndroid = nativeInit(mTaskRunnerType,
mNativeTaskRunnerAndroid = TaskRunnerImplJni.get().init(mTaskRunnerType,
mTaskTraits.mPrioritySetExplicitly, mTaskTraits.mPriority,
mTaskTraits.mMayBlock, mTaskTraits.mUseThreadPool, mTaskTraits.mExtensionId,
mTaskTraits.mExtensionData);
......@@ -181,15 +183,17 @@ public class TaskRunnerImpl implements TaskRunner {
@GuardedBy("mLock")
protected void postDelayedTaskToNative(Runnable r, long delay) {
nativePostDelayedTask(mNativeTaskRunnerAndroid, r, delay);
TaskRunnerImplJni.get().postDelayedTask(mNativeTaskRunnerAndroid, r, delay);
}
// NB due to Proguard obfuscation it's easiest to pass the traits via arguments.
private native long nativeInit(@TaskRunnerType int taskRunnerType,
boolean prioritySetExplicitly, int priority, boolean mayBlock, boolean useThreadPool,
byte extensionId, byte[] extensionData);
private native void nativeDestroy(long nativeTaskRunnerAndroid);
private native void nativePostDelayedTask(
long nativeTaskRunnerAndroid, Runnable task, long delay);
protected native boolean nativeBelongsToCurrentThread(long nativeTaskRunnerAndroid);
@NativeMethods
interface Natives {
// NB due to Proguard obfuscation it's easiest to pass the traits via arguments.
long init(@TaskRunnerType int taskRunnerType, boolean prioritySetExplicitly, int priority,
boolean mayBlock, boolean useThreadPool, byte extensionId, byte[] extensionData);
void destroy(long nativeTaskRunnerAndroid);
void postDelayedTask(long nativeTaskRunnerAndroid, Runnable task, long delay);
boolean belongsToCurrentThread(long nativeTaskRunnerAndroid);
}
}
......@@ -81,7 +81,6 @@ void JavaHandlerThread::Stop() {
}
void JavaHandlerThread::InitializeThread(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong event) {
base::ThreadIdNameManager::GetInstance()->RegisterThread(
base::PlatformThread::CurrentHandle().platform_handle(),
......@@ -95,8 +94,7 @@ void JavaHandlerThread::InitializeThread(JNIEnv* env,
reinterpret_cast<base::WaitableEvent*>(event)->Signal();
}
void JavaHandlerThread::OnLooperStopped(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
void JavaHandlerThread::OnLooperStopped(JNIEnv* env) {
DCHECK(task_runner()->BelongsToCurrentThread());
task_environment_.reset();
......
......@@ -54,10 +54,9 @@ class BASE_EXPORT JavaHandlerThread {
// Called from java on the newly created thread.
// Start() will not return before this methods has finished.
void InitializeThread(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong event);
// Called from java on this thread.
void OnLooperStopped(JNIEnv* env, const JavaParamRef<jobject>& obj);
void OnLooperStopped(JNIEnv* env);
// Called from this thread.
void StopSequenceManagerForTesting();
......
......@@ -49,7 +49,6 @@ bool IsUsingOrderfileOptimization() {
static void JNI_LibraryLoader_RecordRendererLibraryLoadTime(
JNIEnv* env,
const JavaParamRef<jobject>& jcaller,
jlong library_load_time_ms) {
g_renderer_library_load_time_ms = library_load_time_ms;
}
......@@ -75,7 +74,6 @@ void SetLibraryLoadedHook(LibraryLoadedHook* func) {
static jboolean JNI_LibraryLoader_LibraryLoaded(
JNIEnv* env,
const JavaParamRef<jobject>& jcaller,
jint library_process_type) {
#if BUILDFLAG(ORDERFILE_INSTRUMENTATION)
orderfile::StartDelayedDump();
......@@ -114,9 +112,7 @@ void SetVersionNumber(const char* version_number) {
g_library_version_number = strdup(version_number);
}
ScopedJavaLocalRef<jstring> JNI_LibraryLoader_GetVersionNumber(
JNIEnv* env,
const JavaParamRef<jobject>& jcaller) {
ScopedJavaLocalRef<jstring> JNI_LibraryLoader_GetVersionNumber(JNIEnv* env) {
return ConvertUTF8ToJavaString(env, g_library_version_number);
}
......
......@@ -15,7 +15,6 @@ namespace base {
jlong JNI_TaskRunnerImpl_Init(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller,
jint task_runner_type,
jboolean priority_set_explicitly,
jint priority,
......@@ -46,15 +45,13 @@ TaskRunnerAndroid::TaskRunnerAndroid(scoped_refptr<TaskRunner> task_runner)
TaskRunnerAndroid::~TaskRunnerAndroid() = default;
void TaskRunnerAndroid::Destroy(JNIEnv* env,
const base::android::JavaRef<jobject>& caller) {
void TaskRunnerAndroid::Destroy(JNIEnv* env) {
// This could happen on any thread.
delete this;
}
void TaskRunnerAndroid::PostDelayedTask(
JNIEnv* env,
const base::android::JavaRef<jobject>& caller,
const base::android::JavaRef<jobject>& task,
jlong delay) {
task_runner_->PostDelayedTask(
......@@ -64,9 +61,7 @@ void TaskRunnerAndroid::PostDelayedTask(
TimeDelta::FromMilliseconds(delay));
}
bool TaskRunnerAndroid::BelongsToCurrentThread(
JNIEnv* env,
const base::android::JavaRef<jobject>& caller) {
bool TaskRunnerAndroid::BelongsToCurrentThread(JNIEnv* env) {
return task_runner_->RunsTasksInCurrentSequence();
}
......
......@@ -20,15 +20,13 @@ class TaskRunnerAndroid {
explicit TaskRunnerAndroid(scoped_refptr<TaskRunner> task_runner);
~TaskRunnerAndroid();
void Destroy(JNIEnv* env, const base::android::JavaRef<jobject>& caller);
void Destroy(JNIEnv* env);
void PostDelayedTask(JNIEnv* env,
const base::android::JavaRef<jobject>& caller,
const base::android::JavaRef<jobject>& task,
jlong delay);
bool BelongsToCurrentThread(JNIEnv* env,
const base::android::JavaRef<jobject>& caller);
bool BelongsToCurrentThread(JNIEnv* env);
private:
const scoped_refptr<TaskRunner> task_runner_;
......
......@@ -5,6 +5,7 @@
package org.chromium.base.test;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* Class containing only static methods for querying the status of the reached code profiler.
......@@ -17,7 +18,7 @@ public class ReachedCodeProfiler {
* @return Whether the reached code profiler is enabled.
*/
public static boolean isEnabled() {
return nativeIsReachedCodeProfilerEnabled();
return ReachedCodeProfilerJni.get().isReachedCodeProfilerEnabled();
}
/**
......@@ -25,9 +26,12 @@ public class ReachedCodeProfiler {
* profiler.
*/
public static boolean isSupported() {
return nativeIsReachedCodeProfilerSupported();
return ReachedCodeProfilerJni.get().isReachedCodeProfilerSupported();
}
private static native boolean nativeIsReachedCodeProfilerEnabled();
private static native boolean nativeIsReachedCodeProfilerSupported();
@NativeMethods
interface Natives {
boolean isReachedCodeProfilerEnabled();
boolean isReachedCodeProfilerSupported();
}
}
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
package org.chromium.base.test.task;
import org.chromium.base.annotations.NativeMethods;
/** Helpers that allow base::ThreadPoolInstance to be initialized or shutdown for testing. */
public class ThreadPoolTestHelpers {
......@@ -10,16 +11,19 @@ public class ThreadPoolTestHelpers {
* Initializes base::ThreadPoolInstance with default params.
*/
public static void enableThreadPoolExecutionForTesting() {
nativeEnableThreadPoolExecutionForTesting();
ThreadPoolTestHelpersJni.get().enableThreadPoolExecutionForTesting();
}
/**
* Shuts down base::ThreadPoolInstance.
*/
public static void disableThreadPoolExecutionForTesting() {
nativeDisableThreadPoolExecutionForTesting();
ThreadPoolTestHelpersJni.get().disableThreadPoolExecutionForTesting();
}
private static native void nativeEnableThreadPoolExecutionForTesting();
private static native void nativeDisableThreadPoolExecutionForTesting();
@NativeMethods
interface Natives {
void enableThreadPoolExecutionForTesting();
void disableThreadPoolExecutionForTesting();
}
}
......@@ -25,6 +25,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.bar_component.Keybo
import android.support.design.widget.TabLayout;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
......@@ -32,9 +33,11 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordHistogramJni;
import org.chromium.base.metrics.test.ShadowRecordHistogram;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.keyboard_accessory.AccessoryAction;
import org.chromium.chrome.browser.keyboard_accessory.AccessoryBarContents;
......@@ -64,6 +67,9 @@ import java.util.HashMap;
@Config(manifest = Config.NONE,
shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
public class KeyboardAccessoryControllerTest {
@Rule
public JniMocker mocker = new JniMocker();
@Mock
private PropertyObserver<PropertyKey> mMockPropertyObserver;
@Mock
......@@ -78,6 +84,8 @@ public class KeyboardAccessoryControllerTest {
private KeyboardAccessoryCoordinator.TabSwitchingDelegate mMockTabSwitchingDelegate;
@Mock
private AutofillDelegate mMockAutofillDelegate;
@Mock
private RecordHistogram.Natives mMockRecordHistogram;
private final KeyboardAccessoryData.Tab mTestTab =
new KeyboardAccessoryData.Tab("Passwords", null, null, 0, 0, null);
......@@ -91,7 +99,7 @@ public class KeyboardAccessoryControllerTest {
ShadowRecordHistogram.reset();
MockitoAnnotations.initMocks(this);
setAutofillFeature(false);
mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogram);
when(mMockView.getTabLayout()).thenReturn(mock(TabLayout.class));
when(mMockTabLayout.getTabSwitchingDelegate()).thenReturn(mMockTabSwitchingDelegate);
mCoordinator = new KeyboardAccessoryCoordinator(
......
......@@ -22,6 +22,7 @@ import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
......@@ -29,9 +30,11 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordHistogramJni;
import org.chromium.base.metrics.test.ShadowRecordHistogram;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.keyboard_accessory.AccessorySheetTrigger;
import org.chromium.chrome.browser.keyboard_accessory.ManualFillingMetricsRecorder;
import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.Tab;
......@@ -48,6 +51,8 @@ import org.chromium.ui.test.util.modelutil.FakeViewProvider;
@Config(manifest = Config.NONE,
shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
public class AccessorySheetControllerTest {
@Rule
public JniMocker mocker = new JniMocker();
@Mock
private PropertyObservable.PropertyObserver<PropertyKey> mMockPropertyObserver;
@Mock
......@@ -56,6 +61,8 @@ public class AccessorySheetControllerTest {
private AccessorySheetView mMockView;
@Mock
private RecyclerView mMockRecyclerView;
@Mock
private RecordHistogram.Natives mMockRecordHistogramNatives;
private final Tab[] mTabs = new Tab[] {new Tab("Passwords", null, null, 0, 0, null),
new Tab("Passwords", null, null, 0, 0, null),
......@@ -70,6 +77,7 @@ public class AccessorySheetControllerTest {
public void setUp() {
ShadowRecordHistogram.reset();
MockitoAnnotations.initMocks(this);
mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogramNatives);
when(mMockView.getLayoutParams()).thenReturn(new ViewGroup.LayoutParams(0, 0));
mCoordinator = new AccessorySheetCoordinator(new FakeViewProvider<>(mMockView));
mMediator = mCoordinator.getMediatorForTesting();
......
......@@ -22,6 +22,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.Accessor
import android.support.v7.widget.RecyclerView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
......@@ -30,9 +31,11 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordHistogramJni;
import org.chromium.base.metrics.test.ShadowRecordHistogram;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType;
import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData;
......@@ -51,10 +54,14 @@ import java.util.HashMap;
@Config(manifest = Config.NONE,
shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
public class AddressAccessorySheetControllerTest {
@Rule
public JniMocker mocker = new JniMocker();
@Mock
private RecyclerView mMockView;
@Mock
private ListObservable.ListObserver<Void> mMockItemListObserver;
@Mock
private RecordHistogram.Natives mMockRecordHistogramNatives;
private AddressAccessorySheetCoordinator mCoordinator;
private AccessorySheetTabModel mSheetDataPieces;
......@@ -63,6 +70,7 @@ public class AddressAccessorySheetControllerTest {
public void setUp() {
ShadowRecordHistogram.reset();
MockitoAnnotations.initMocks(this);
mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogramNatives);
setAutofillFeature(true);
mCoordinator = new AddressAccessorySheetCoordinator(RuntimeEnvironment.application, null);
assertNotNull(mCoordinator);
......
......@@ -24,6 +24,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.Accessor
import android.support.v7.widget.RecyclerView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
......@@ -32,9 +33,11 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordHistogramJni;
import org.chromium.base.metrics.test.ShadowRecordHistogram;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.keyboard_accessory.AccessoryAction;
import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType;
......@@ -55,10 +58,14 @@ import java.util.HashMap;
@Config(manifest = Config.NONE,
shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
public class PasswordAccessorySheetControllerTest {
@Rule
public JniMocker mocker = new JniMocker();
@Mock
private RecyclerView mMockView;
@Mock
private ListObservable.ListObserver<Void> mMockItemListObserver;
@Mock
private RecordHistogram.Natives mMockRecordHistogramNatives;
private PasswordAccessorySheetCoordinator mCoordinator;
private AccessorySheetTabModel mSheetDataPieces;
......@@ -67,6 +74,7 @@ public class PasswordAccessorySheetControllerTest {
public void setUp() {
ShadowRecordHistogram.reset();
MockitoAnnotations.initMocks(this);
mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogramNatives);
mCoordinator = new PasswordAccessorySheetCoordinator(RuntimeEnvironment.application, null);
assertNotNull(mCoordinator);
mSheetDataPieces = mCoordinator.getSheetDataPiecesForTesting();
......
......@@ -17,7 +17,7 @@ import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import org.chromium.base.Callback;
import org.chromium.base.TimeUtils;
import org.chromium.base.TimeUtilsJni;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.metrics.RecordHistogram;
......@@ -113,7 +113,8 @@ public class ContextMenuHelper implements OnCreateContextMenuListener {
};
mOnMenuShown = () -> {
mSelectedItemBeforeDismiss = false;
mMenuShownTimeMs = TimeUnit.MICROSECONDS.toMillis(TimeUtils.nativeGetTimeTicksNowUs());
mMenuShownTimeMs =
TimeUnit.MICROSECONDS.toMillis(TimeUtilsJni.get().getTimeTicksNowUs());
RecordHistogram.recordBooleanHistogram("ContextMenu.Shown", mWebContents != null);
};
mOnMenuClosed = (notAbandoned) -> {
......@@ -258,7 +259,7 @@ public class ContextMenuHelper implements OnCreateContextMenuListener {
private void recordTimeToTakeActionHistogram(boolean selectedItem) {
final String action = selectedItem ? "SelectedItem" : "Abandoned";
RecordHistogram.recordTimesHistogram("ContextMenu.TimeToTakeAction." + action,
TimeUnit.MICROSECONDS.toMillis(TimeUtils.nativeGetTimeTicksNowUs())
TimeUnit.MICROSECONDS.toMillis(TimeUtilsJni.get().getTimeTicksNowUs())
- mMenuShownTimeMs);
}
......
......@@ -37,7 +37,7 @@ import org.chromium.base.Log;
import org.chromium.base.StrictModeContext;
import org.chromium.base.SysUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.TimeUtils;
import org.chromium.base.TimeUtilsJni;
import org.chromium.base.TraceEvent;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
......@@ -53,10 +53,10 @@ import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.WarmupManager;
import org.chromium.chrome.browser.browserservices.SessionHandler;
import org.chromium.chrome.browser.browserservices.SessionDataHolder;
import org.chromium.chrome.browser.browserservices.Origin;
import org.chromium.chrome.browser.browserservices.PostMessageHandler;
import org.chromium.chrome.browser.browserservices.SessionDataHolder;
import org.chromium.chrome.browser.browserservices.SessionHandler;
import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleLoader;
import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics;
import org.chromium.chrome.browser.device.DeviceClassManager;
......@@ -1153,7 +1153,7 @@ public class CustomTabsConnection {
if (!mNativeTickOffsetUsComputed) {
// Compute offset from time ticks to uptimeMillis.
mNativeTickOffsetUsComputed = true;
long nativeNowUs = TimeUtils.nativeGetTimeTicksNowUs();
long nativeNowUs = TimeUtilsJni.get().getTimeTicksNowUs();
long javaNowUs = SystemClock.uptimeMillis() * 1000;
mNativeTickOffsetUs = nativeNowUs - javaNowUs;
}
......
......@@ -7,7 +7,7 @@ package org.chromium.chrome.browser.customtabs.dynamicmodule;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import org.chromium.base.TimeUtils;
import org.chromium.base.TimeUtilsJni;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.metrics.PageLoadMetrics;
import org.chromium.content_public.browser.WebContents;
......@@ -51,7 +51,7 @@ public class DynamicModulePageLoadObserver implements PageLoadMetrics.Observer {
public DynamicModulePageLoadObserver(ActivityTabProvider activityTabProvider) {
mActivityTabProvider = activityTabProvider;
long nativeNowUs = TimeUtils.nativeGetTimeTicksNowUs();
long nativeNowUs = TimeUtilsJni.get().getTimeTicksNowUs();
long javaNowUs = SystemClock.uptimeMillis() * 1000;
mNativeTickOffsetUs = nativeNowUs - javaNowUs;
}
......
......@@ -4,7 +4,7 @@
package org.chromium.chrome.browser.tasks;
import org.chromium.base.TimeUtils;
import org.chromium.base.TimeUtilsJni;
import java.util.concurrent.TimeUnit;
......@@ -61,7 +61,7 @@ public class EngagementTimeUtil {
public long timeSinceLastEngagementFromTimeTicksMs(
final long lastEngagementMs, final long currentEngagementTicksMs) {
final long currentTimeMs = currentTime();
final long currentTimeTicksUs = TimeUtils.nativeGetTimeTicksNowUs();
final long currentTimeTicksUs = TimeUtilsJni.get().getTimeTicksNowUs();
final long currentTimeTicksMs = TimeUnit.MICROSECONDS.toMillis(currentTimeTicksUs);
final long offsetMs = currentTimeTicksMs - currentEngagementTicksMs;
final long currentEngagementTimeMs = currentTimeMs - offsetMs;
......
......@@ -27,7 +27,9 @@ import org.robolectric.annotation.Implements;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordHistogramJni;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.ContentSettingsType;
import org.chromium.chrome.browser.omnibox.geo.GeolocationHeaderUnitTest.ShadowRecordHistogram;
import org.chromium.chrome.browser.omnibox.geo.GeolocationHeaderUnitTest.ShadowUrlUtilities;
......@@ -48,8 +50,7 @@ import java.util.HashSet;
*/
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE,
shadows = {ShadowUrlUtilities.class, ShadowRecordHistogram.class,
ShadowWebsitePreferenceBridge.class})
shadows = {ShadowUrlUtilities.class, ShadowWebsitePreferenceBridge.class})
public class GeolocationHeaderUnitTest {
private static final String SEARCH_URL = "https://www.google.com/search?q=potatoes";
......@@ -98,12 +99,19 @@ public class GeolocationHeaderUnitTest {
@Rule
public TestRule mFeatureProcessor = new Features.JUnitProcessor();
@Rule
public JniMocker mocker = new JniMocker();
@Mock
RecordHistogram.Natives mRecordHistogramMock;
@Mock
private Tab mTab;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mocker.mock(RecordHistogramJni.TEST_HOOKS, mRecordHistogramMock);
GeolocationTracker.setLocationAgeForTesting(null);
GeolocationHeader.setLocationSourceForTesting(
GeolocationHeader.LocationSource.HIGH_ACCURACY);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment