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 package org.chromium.chromium_linker_test_apk; 6 7 import android.app.Activity; 8 import android.content.Context; 9 import android.content.Intent; 10 import android.os.Bundle; 11 import android.util.Log; 12 import android.view.LayoutInflater; 13 import android.view.View; 14 15 import org.chromium.base.BaseSwitches; 16 import org.chromium.base.CommandLine; 17 import org.chromium.base.library_loader.LibraryLoader; 18 import org.chromium.base.library_loader.Linker; 19 import org.chromium.base.library_loader.ProcessInitException; 20 import org.chromium.content.browser.BrowserStartupController; 21 import org.chromium.content.browser.ContentViewClient; 22 import org.chromium.content.browser.ContentViewCore; 23 import org.chromium.content_shell.Shell; 24 import org.chromium.content_shell.ShellManager; 25 import org.chromium.ui.base.ActivityWindowAndroid; 26 import org.chromium.ui.base.WindowAndroid; 27 28 /** 29 * Test activity used for verifying the different configuration options for the ContentLinker. 30 */ 31 public class ChromiumLinkerTestActivity extends Activity { 32 public static final String COMMAND_LINE_FILE = 33 "/data/local/tmp/chromium-linker-test-command-line"; 34 35 private static final String TAG = "ChromiumLinkerTestActivity"; 36 37 public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs"; 38 39 // Use this on the command-line to simulate a low-memory device, otherwise 40 // a regular device is simulated by this test, independently from what the 41 // target device running the test really is. 42 private static final String LOW_MEMORY_DEVICE = "--low-memory-device"; 43 44 private ShellManager mShellManager; 45 private WindowAndroid mWindowAndroid; 46 47 @Override 48 public void onCreate(final Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 51 // Initializing the command line must occur before loading the library. 52 if (!CommandLine.isInitialized()) { 53 CommandLine.initFromFile(COMMAND_LINE_FILE); 54 String[] commandLineParams = getCommandLineParamsFromIntent(getIntent()); 55 if (commandLineParams != null) { 56 CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams); 57 } 58 } 59 waitForDebuggerIfNeeded(); 60 61 // CommandLine.getInstance().hasSwitch() doesn't work here for some funky 62 // reason, so parse the command-line differently here: 63 boolean hasLowMemoryDeviceSwitch = false; 64 String[] cmdline = CommandLine.getJavaSwitchesOrNull(); 65 if (cmdline == null) 66 Log.i(TAG, "Command line is null"); 67 else { 68 Log.i(TAG, "Command line is:"); 69 for (int n = 0; n < cmdline.length; ++n) { 70 Log.i(TAG, " '" + cmdline[n] + "'"); 71 if (cmdline[n].equals(LOW_MEMORY_DEVICE)) 72 hasLowMemoryDeviceSwitch = true; 73 } 74 } 75 76 // Determine which kind of device to simulate from the command-line. 77 int memoryDeviceConfig = Linker.MEMORY_DEVICE_CONFIG_NORMAL; 78 if (hasLowMemoryDeviceSwitch) 79 memoryDeviceConfig = Linker.MEMORY_DEVICE_CONFIG_LOW; 80 Linker.setMemoryDeviceConfig(memoryDeviceConfig); 81 82 // Register the test runner class by name. 83 Linker.setTestRunnerClassName(LinkerTests.class.getName()); 84 85 // Load the library in the browser process, this will also run the test 86 // runner in this process. 87 try { 88 LibraryLoader.ensureInitialized(); 89 } catch (ProcessInitException e) { 90 Log.i(TAG, "Cannot load chromium_linker_test:" + e); 91 } 92 93 // Now, start a new renderer process by creating a new view. 94 // This will run the test runner in the renderer process. 95 96 BrowserStartupController.get(getApplicationContext()).initChromiumBrowserProcessForTests(); 97 98 LayoutInflater inflater = 99 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 100 View view = inflater.inflate(R.layout.test_activity, null); 101 mShellManager = (ShellManager) view.findViewById(R.id.shell_container); 102 mWindowAndroid = new ActivityWindowAndroid(this); 103 mShellManager.setWindow(mWindowAndroid); 104 105 mShellManager.setStartupUrl("about:blank"); 106 107 try { 108 BrowserStartupController.get(this).startBrowserProcessesAsync( 109 new BrowserStartupController.StartupCallback() { 110 @Override 111 public void onSuccess(boolean alreadyStarted) { 112 finishInitialization(savedInstanceState); 113 } 114 115 @Override 116 public void onFailure() { 117 initializationFailed(); 118 } 119 }); 120 } catch (ProcessInitException e) { 121 Log.e(TAG, "Unable to load native library.", e); 122 finish(); 123 } 124 125 // TODO(digit): Ensure that after the content view is initialized, 126 // the program finishes(). 127 } 128 129 private void finishInitialization(Bundle savedInstanceState) { 130 String shellUrl = ShellManager.DEFAULT_SHELL_URL; 131 mShellManager.launchShell(shellUrl); 132 getActiveContentViewCore().setContentViewClient(new ContentViewClient()); 133 } 134 135 private void initializationFailed() { 136 Log.e(TAG, "ContentView initialization failed."); 137 finish(); 138 } 139 140 @Override 141 protected void onSaveInstanceState(Bundle outState) { 142 super.onSaveInstanceState(outState); 143 mWindowAndroid.saveInstanceState(outState); 144 } 145 146 private void waitForDebuggerIfNeeded() { 147 if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) { 148 Log.e(TAG, "Waiting for Java debugger to connect..."); 149 android.os.Debug.waitForDebugger(); 150 Log.e(TAG, "Java debugger connected. Resuming execution."); 151 } 152 } 153 154 @Override 155 protected void onStop() { 156 super.onStop(); 157 158 ContentViewCore contentViewCore = getActiveContentViewCore(); 159 if (contentViewCore != null) contentViewCore.onHide(); 160 } 161 162 @Override 163 protected void onStart() { 164 super.onStart(); 165 166 ContentViewCore contentViewCore = getActiveContentViewCore(); 167 if (contentViewCore != null) contentViewCore.onShow(); 168 } 169 170 @Override 171 public void onActivityResult(int requestCode, int resultCode, Intent data) { 172 super.onActivityResult(requestCode, resultCode, data); 173 mWindowAndroid.onActivityResult(requestCode, resultCode, data); 174 } 175 176 private static String[] getCommandLineParamsFromIntent(Intent intent) { 177 return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null; 178 } 179 180 /** 181 * @return The {@link ContentViewCore} owned by the currently visible {@link Shell} or null if 182 * one is not showing. 183 */ 184 public ContentViewCore getActiveContentViewCore() { 185 if (mShellManager == null) 186 return null; 187 188 Shell shell = mShellManager.getActiveShell(); 189 if (shell == null) 190 return null; 191 192 return shell.getContentViewCore(); 193 } 194 } 195