ContentShellActivity.java revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright 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 5package org.chromium.content_shell_apk; 6 7import android.app.Activity; 8import android.content.Intent; 9import android.os.Bundle; 10import android.text.TextUtils; 11import android.util.Log; 12import android.view.KeyEvent; 13import android.widget.Toast; 14 15import org.chromium.base.BaseSwitches; 16import org.chromium.base.CommandLine; 17import org.chromium.base.MemoryPressureListener; 18import org.chromium.base.library_loader.LibraryLoader; 19import org.chromium.base.library_loader.ProcessInitException; 20import org.chromium.content.browser.BrowserStartupController; 21import org.chromium.content.browser.ContentViewCore; 22import org.chromium.content.browser.DeviceUtils; 23import org.chromium.content.common.ContentSwitches; 24import org.chromium.content_shell.Shell; 25import org.chromium.content_shell.ShellManager; 26import org.chromium.ui.base.ActivityWindowAndroid; 27import org.chromium.ui.base.WindowAndroid; 28 29/** 30 * Activity for managing the Content Shell. 31 */ 32public class ContentShellActivity extends Activity { 33 34 public static final String COMMAND_LINE_FILE = "/data/local/tmp/content-shell-command-line"; 35 private static final String TAG = "ContentShellActivity"; 36 37 private static final String ACTIVE_SHELL_URL_KEY = "activeUrl"; 38 public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs"; 39 40 private ShellManager mShellManager; 41 private WindowAndroid mWindowAndroid; 42 43 @Override 44 protected void onCreate(final Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 47 // Initializing the command line must occur before loading the library. 48 if (!CommandLine.isInitialized()) { 49 CommandLine.initFromFile(COMMAND_LINE_FILE); 50 String[] commandLineParams = getCommandLineParamsFromIntent(getIntent()); 51 if (commandLineParams != null) { 52 CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams); 53 } 54 } 55 waitForDebuggerIfNeeded(); 56 57 DeviceUtils.addDeviceSpecificUserAgentSwitch(this); 58 try { 59 LibraryLoader.ensureInitialized(); 60 } catch (ProcessInitException e) { 61 Log.e(TAG, "ContentView initialization failed.", e); 62 // Since the library failed to initialize nothing in the application 63 // can work, so kill the whole application not just the activity 64 System.exit(-1); 65 return; 66 } 67 68 setContentView(R.layout.content_shell_activity); 69 mShellManager = (ShellManager) findViewById(R.id.shell_container); 70 mWindowAndroid = new ActivityWindowAndroid(this); 71 mWindowAndroid.restoreInstanceState(savedInstanceState); 72 mShellManager.setWindow(mWindowAndroid); 73 74 String startupUrl = getUrlFromIntent(getIntent()); 75 if (!TextUtils.isEmpty(startupUrl)) { 76 mShellManager.setStartupUrl(Shell.sanitizeUrl(startupUrl)); 77 } 78 79 if (CommandLine.getInstance().hasSwitch(ContentSwitches.DUMP_RENDER_TREE)) { 80 try { 81 BrowserStartupController.get(this).startBrowserProcessesSync( 82 BrowserStartupController.MAX_RENDERERS_LIMIT); 83 } catch (ProcessInitException e) { 84 Log.e(TAG, "Failed to load native library.", e); 85 System.exit(-1); 86 } 87 } else { 88 try { 89 BrowserStartupController.get(this).startBrowserProcessesAsync( 90 new BrowserStartupController.StartupCallback() { 91 @Override 92 public void onSuccess(boolean alreadyStarted) { 93 finishInitialization(savedInstanceState); 94 } 95 96 @Override 97 public void onFailure() { 98 initializationFailed(); 99 } 100 }); 101 } catch (ProcessInitException e) { 102 Log.e(TAG, "Unable to load native library.", e); 103 System.exit(-1); 104 } 105 } 106 } 107 108 private void finishInitialization(Bundle savedInstanceState) { 109 String shellUrl = ShellManager.DEFAULT_SHELL_URL; 110 if (savedInstanceState != null 111 && savedInstanceState.containsKey(ACTIVE_SHELL_URL_KEY)) { 112 shellUrl = savedInstanceState.getString(ACTIVE_SHELL_URL_KEY); 113 } 114 mShellManager.launchShell(shellUrl); 115 } 116 117 private void initializationFailed() { 118 Log.e(TAG, "ContentView initialization failed."); 119 Toast.makeText(ContentShellActivity.this, 120 R.string.browser_process_initialization_failed, 121 Toast.LENGTH_SHORT).show(); 122 finish(); 123 } 124 125 @Override 126 protected void onSaveInstanceState(Bundle outState) { 127 super.onSaveInstanceState(outState); 128 ContentViewCore contentViewCore = getActiveContentViewCore(); 129 if (contentViewCore != null) { 130 outState.putString(ACTIVE_SHELL_URL_KEY, contentViewCore.getUrl()); 131 } 132 133 mWindowAndroid.saveInstanceState(outState); 134 } 135 136 private void waitForDebuggerIfNeeded() { 137 if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) { 138 Log.e(TAG, "Waiting for Java debugger to connect..."); 139 android.os.Debug.waitForDebugger(); 140 Log.e(TAG, "Java debugger connected. Resuming execution."); 141 } 142 } 143 144 @Override 145 public boolean onKeyUp(int keyCode, KeyEvent event) { 146 if (keyCode == KeyEvent.KEYCODE_BACK) { 147 ContentViewCore contentViewCore = getActiveContentViewCore(); 148 if (contentViewCore != null && contentViewCore.canGoBack()) { 149 contentViewCore.goBack(); 150 return true; 151 } 152 } 153 154 return super.onKeyUp(keyCode, event); 155 } 156 157 @Override 158 protected void onNewIntent(Intent intent) { 159 if (getCommandLineParamsFromIntent(intent) != null) { 160 Log.i(TAG, "Ignoring command line params: can only be set when creating the activity."); 161 } 162 163 if (MemoryPressureListener.handleDebugIntent(this, intent.getAction())) return; 164 165 String url = getUrlFromIntent(intent); 166 if (!TextUtils.isEmpty(url)) { 167 Shell activeView = getActiveShell(); 168 if (activeView != null) { 169 activeView.loadUrl(url); 170 } 171 } 172 } 173 174 @Override 175 protected void onStop() { 176 super.onStop(); 177 178 ContentViewCore contentViewCore = getActiveContentViewCore(); 179 if (contentViewCore != null) contentViewCore.onHide(); 180 } 181 182 @Override 183 protected void onStart() { 184 super.onStart(); 185 186 ContentViewCore contentViewCore = getActiveContentViewCore(); 187 if (contentViewCore != null) contentViewCore.onShow(); 188 } 189 190 @Override 191 public void onActivityResult(int requestCode, int resultCode, Intent data) { 192 super.onActivityResult(requestCode, resultCode, data); 193 mWindowAndroid.onActivityResult(requestCode, resultCode, data); 194 } 195 196 private static String getUrlFromIntent(Intent intent) { 197 return intent != null ? intent.getDataString() : null; 198 } 199 200 private static String[] getCommandLineParamsFromIntent(Intent intent) { 201 return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null; 202 } 203 204 /** 205 * @return The {@link ShellManager} configured for the activity or null if it has not been 206 * created yet. 207 */ 208 public ShellManager getShellManager() { 209 return mShellManager; 210 } 211 212 /** 213 * @return The currently visible {@link Shell} or null if one is not showing. 214 */ 215 public Shell getActiveShell() { 216 return mShellManager != null ? mShellManager.getActiveShell() : null; 217 } 218 219 /** 220 * @return The {@link ContentViewCore} owned by the currently visible {@link Shell} or null if 221 * one is not showing. 222 */ 223 public ContentViewCore getActiveContentViewCore() { 224 Shell shell = getActiveShell(); 225 return shell != null ? shell.getContentViewCore() : null; 226 } 227} 228