| // Copyright 2012 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.content_shell_apk; |
| |
| import android.app.Activity; |
| import android.content.Intent; |
| import android.os.Bundle; |
| import android.text.TextUtils; |
| import android.util.Log; |
| import android.view.KeyEvent; |
| import android.widget.Toast; |
| |
| import org.chromium.base.BaseSwitches; |
| import org.chromium.base.CommandLine; |
| import org.chromium.base.MemoryPressureListener; |
| import org.chromium.content.app.LibraryLoader; |
| import org.chromium.content.browser.ActivityContentVideoViewClient; |
| import org.chromium.content.browser.BrowserStartupController; |
| import org.chromium.content.browser.ContentVideoViewClient; |
| import org.chromium.content.browser.ContentView; |
| import org.chromium.content.browser.ContentViewClient; |
| import org.chromium.content.browser.DeviceUtils; |
| import org.chromium.content.common.ContentSwitches; |
| import org.chromium.content.common.ProcessInitException; |
| import org.chromium.content_shell.Shell; |
| import org.chromium.content_shell.ShellManager; |
| import org.chromium.ui.base.ActivityWindowAndroid; |
| import org.chromium.ui.base.WindowAndroid; |
| |
| /** |
| * Activity for managing the Content Shell. |
| */ |
| public class ContentShellActivity extends Activity { |
| |
| public static final String COMMAND_LINE_FILE = "/data/local/tmp/content-shell-command-line"; |
| private static final String TAG = "ContentShellActivity"; |
| |
| private static final String ACTIVE_SHELL_URL_KEY = "activeUrl"; |
| public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs"; |
| |
| private ShellManager mShellManager; |
| private WindowAndroid mWindowAndroid; |
| |
| @Override |
| protected void onCreate(final Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| // Initializing the command line must occur before loading the library. |
| if (!CommandLine.isInitialized()) { |
| CommandLine.initFromFile(COMMAND_LINE_FILE); |
| String[] commandLineParams = getCommandLineParamsFromIntent(getIntent()); |
| if (commandLineParams != null) { |
| CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams); |
| } |
| } |
| waitForDebuggerIfNeeded(); |
| |
| DeviceUtils.addDeviceSpecificUserAgentSwitch(this); |
| try { |
| LibraryLoader.ensureInitialized(); |
| } catch (ProcessInitException e) { |
| Log.e(TAG, "ContentView initialization failed.", e); |
| // Since the library failed to initialize nothing in the application |
| // can work, so kill the whole application not just the activity |
| System.exit(-1); |
| return; |
| } |
| |
| setContentView(R.layout.content_shell_activity); |
| mShellManager = (ShellManager) findViewById(R.id.shell_container); |
| mWindowAndroid = new ActivityWindowAndroid(this); |
| mWindowAndroid.restoreInstanceState(savedInstanceState); |
| mShellManager.setWindow(mWindowAndroid); |
| |
| String startupUrl = getUrlFromIntent(getIntent()); |
| if (!TextUtils.isEmpty(startupUrl)) { |
| mShellManager.setStartupUrl(Shell.sanitizeUrl(startupUrl)); |
| } |
| |
| if (CommandLine.getInstance().hasSwitch(ContentSwitches.DUMP_RENDER_TREE)) { |
| try { |
| BrowserStartupController.get(this).startBrowserProcessesSync( |
| BrowserStartupController.MAX_RENDERERS_LIMIT); |
| } catch (ProcessInitException e) { |
| Log.e(TAG, "Failed to load native library.", e); |
| System.exit(-1); |
| } |
| } else { |
| try { |
| BrowserStartupController.get(this).startBrowserProcessesAsync( |
| new BrowserStartupController.StartupCallback() { |
| @Override |
| public void onSuccess(boolean alreadyStarted) { |
| finishInitialization(savedInstanceState); |
| } |
| |
| @Override |
| public void onFailure() { |
| initializationFailed(); |
| } |
| }); |
| } catch (ProcessInitException e) { |
| Log.e(TAG, "Unable to load native library.", e); |
| System.exit(-1); |
| } |
| } |
| } |
| |
| private void finishInitialization(Bundle savedInstanceState) { |
| String shellUrl = ShellManager.DEFAULT_SHELL_URL; |
| if (savedInstanceState != null |
| && savedInstanceState.containsKey(ACTIVE_SHELL_URL_KEY)) { |
| shellUrl = savedInstanceState.getString(ACTIVE_SHELL_URL_KEY); |
| } |
| mShellManager.launchShell(shellUrl); |
| getActiveContentView().setContentViewClient(new ContentViewClient() { |
| @Override |
| public ContentVideoViewClient getContentVideoViewClient() { |
| return new ActivityContentVideoViewClient(ContentShellActivity.this); |
| } |
| }); |
| } |
| |
| private void initializationFailed() { |
| Log.e(TAG, "ContentView initialization failed."); |
| Toast.makeText(ContentShellActivity.this, |
| R.string.browser_process_initialization_failed, |
| Toast.LENGTH_SHORT).show(); |
| finish(); |
| } |
| |
| @Override |
| protected void onSaveInstanceState(Bundle outState) { |
| super.onSaveInstanceState(outState); |
| Shell activeShell = getActiveShell(); |
| if (activeShell != null) { |
| outState.putString(ACTIVE_SHELL_URL_KEY, activeShell.getContentView().getUrl()); |
| } |
| |
| mWindowAndroid.saveInstanceState(outState); |
| } |
| |
| private void waitForDebuggerIfNeeded() { |
| if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) { |
| Log.e(TAG, "Waiting for Java debugger to connect..."); |
| android.os.Debug.waitForDebugger(); |
| Log.e(TAG, "Java debugger connected. Resuming execution."); |
| } |
| } |
| |
| @Override |
| public boolean onKeyUp(int keyCode, KeyEvent event) { |
| if (keyCode != KeyEvent.KEYCODE_BACK) return super.onKeyUp(keyCode, event); |
| |
| Shell activeView = getActiveShell(); |
| if (activeView != null && activeView.getContentView().canGoBack()) { |
| activeView.getContentView().goBack(); |
| return true; |
| } |
| |
| return super.onKeyUp(keyCode, event); |
| } |
| |
| @Override |
| protected void onNewIntent(Intent intent) { |
| if (getCommandLineParamsFromIntent(intent) != null) { |
| Log.i(TAG, "Ignoring command line params: can only be set when creating the activity."); |
| } |
| |
| if (MemoryPressureListener.handleDebugIntent(this, intent.getAction())) return; |
| |
| String url = getUrlFromIntent(intent); |
| if (!TextUtils.isEmpty(url)) { |
| Shell activeView = getActiveShell(); |
| if (activeView != null) { |
| activeView.loadUrl(url); |
| } |
| } |
| } |
| |
| @Override |
| protected void onStop() { |
| super.onStop(); |
| |
| ContentView view = getActiveContentView(); |
| if (view != null) view.onHide(); |
| } |
| |
| @Override |
| protected void onStart() { |
| super.onStart(); |
| |
| ContentView view = getActiveContentView(); |
| if (view != null) view.onShow(); |
| } |
| |
| @Override |
| public void onActivityResult(int requestCode, int resultCode, Intent data) { |
| super.onActivityResult(requestCode, resultCode, data); |
| mWindowAndroid.onActivityResult(requestCode, resultCode, data); |
| } |
| |
| private static String getUrlFromIntent(Intent intent) { |
| return intent != null ? intent.getDataString() : null; |
| } |
| |
| private static String[] getCommandLineParamsFromIntent(Intent intent) { |
| return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null; |
| } |
| |
| /** |
| * @return The {@link ShellManager} configured for the activity or null if it has not been |
| * created yet. |
| */ |
| public ShellManager getShellManager() { |
| return mShellManager; |
| } |
| |
| /** |
| * @return The currently visible {@link Shell} or null if one is not showing. |
| */ |
| public Shell getActiveShell() { |
| return mShellManager != null ? mShellManager.getActiveShell() : null; |
| } |
| |
| /** |
| * @return The {@link ContentView} owned by the currently visible {@link Shell} or null if one |
| * is not showing. |
| */ |
| public ContentView getActiveContentView() { |
| Shell shell = getActiveShell(); |
| return shell != null ? shell.getContentView() : null; |
| } |
| } |