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// This class sets up the environment for running the content browser tests 6// inside an android application. 7 8#include <android/log.h> 9#include <unistd.h> 10 11#include "base/android/base_jni_registrar.h" 12#include "base/android/fifo_utils.h" 13#include "base/android/jni_android.h" 14#include "base/android/jni_string.h" 15#include "base/android/library_loader/library_loader_hooks.h" 16#include "base/android/scoped_java_ref.h" 17#include "base/base_switches.h" 18#include "base/command_line.h" 19#include "base/files/file_path.h" 20#include "base/logging.h" 21#include "base/strings/string_tokenizer.h" 22#include "base/strings/string_util.h" 23#include "base/strings/stringprintf.h" 24#include "content/public/app/android_library_loader_hooks.h" 25#include "content/public/app/content_main.h" 26#include "content/public/common/content_switches.h" 27#include "content/public/test/nested_message_pump_android.h" 28#include "content/public/test/test_launcher.h" 29#include "content/shell/android/shell_jni_registrar.h" 30#include "content/shell/app/shell_main_delegate.h" 31#include "jni/ContentBrowserTestsActivity_jni.h" 32#include "media/base/media_switches.h" 33#include "testing/android/native_test_util.h" 34 35using testing::native_test_util::ArgsToArgv; 36using testing::native_test_util::ParseArgsFromCommandLineFile; 37using testing::native_test_util::ScopedMainEntryLogger; 38 39// The main function of the program to be wrapped as an apk. 40extern int main(int argc, char** argv); 41 42namespace { 43 44// The test runner script writes the command line file in 45// "/data/local/tmp". 46static const char kCommandLineFilePath[] = 47 "/data/local/tmp/content-browser-tests-command-line"; 48 49} // namespace 50 51namespace content { 52 53// TODO(nileshagrawal): Refactor and deduplicate with 54// testing/android/native_test_launcher.cc 55static void RunTests(JNIEnv* env, 56 jobject obj, 57 jstring jfiles_dir, 58 jobject app_context) { 59 // Command line basic initialization, will be fully initialized later. 60 static const char* const kInitialArgv[] = { "ContentBrowserTestsActivity" }; 61 CommandLine::Init(arraysize(kInitialArgv), kInitialArgv); 62 63 // Set the application context in base. 64 base::android::ScopedJavaLocalRef<jobject> scoped_context( 65 env, env->NewLocalRef(app_context)); 66 base::android::InitApplicationContext(env, scoped_context); 67 base::android::RegisterJni(env); 68 69 std::vector<std::string> args; 70 ParseArgsFromCommandLineFile(kCommandLineFilePath, &args); 71 72 std::vector<char*> argv; 73 int argc = ArgsToArgv(args, &argv); 74 75 // Fully initialize command line with arguments. 76 CommandLine* command_line = CommandLine::ForCurrentProcess(); 77 command_line->AppendArguments(CommandLine(argc, &argv[0]), false); 78 79 // Append required switches. 80 command_line->AppendSwitch(content::kSingleProcessTestsFlag); 81 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); 82 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); 83 // Specify a socket name to not conflict with the default one used 84 // in content_shell. 85 command_line->AppendSwitchASCII(switches::kRemoteDebuggingSocketName, 86 "content_browsertests_devtools_remote"); 87 88 // Create fifo and redirect stdout and stderr to it. 89 base::FilePath files_dir( 90 base::android::ConvertJavaStringToUTF8(env, jfiles_dir)); 91 base::FilePath fifo_path(files_dir.Append(base::FilePath("test.fifo"))); 92 base::android::CreateFIFO(fifo_path, 0666); 93 base::android::RedirectStream(stdout, fifo_path, "w"); 94 dup2(STDOUT_FILENO, STDERR_FILENO); 95 96 ScopedMainEntryLogger scoped_main_entry_logger; 97 main(argc, &argv[0]); 98} 99} // namespace content 100 101// This is called by the VM when the shared library is first loaded. 102JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { 103 104 base::android::SetLibraryLoadedHook(&content::LibraryLoaded); 105 106 base::android::InitVM(vm); 107 JNIEnv* env = base::android::AttachCurrentThread(); 108 109 if (!base::android::RegisterLibraryLoaderEntryHook(env)) 110 return -1; 111 112 if (!content::android::RegisterShellJni(env)) 113 return -1; 114 115 if (!content::NestedMessagePumpAndroid::RegisterJni(env)) 116 return -1; 117 118 if (!content::RegisterNativesImpl(env)) 119 return -1; 120 121 content::SetContentMainDelegate(new content::ShellMainDelegate()); 122 return JNI_VERSION_1_4; 123} 124