Commit a7372773 authored by tedchoc@chromium.org's avatar tedchoc@chromium.org

Make content shell on android support relaunching.

Without this change, the content shell would crash after pressing back
to the home screen and relaunching.  The two problems this fixes are:

1.) It was trying to initialize the command line even though it already
    was init'ed before.
2.) The shell wasn't being recreated because it is done during process
    start and the process is already running.

BUG=
TEST=


Review URL: https://chromiumcodereview.appspot.com/10701177

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148365 0039d316-1c4b-4281-b951-d872f2087c98
parent 7959742b
...@@ -13,8 +13,6 @@ import org.chromium.base.JNINamespace; ...@@ -13,8 +13,6 @@ import org.chromium.base.JNINamespace;
import org.chromium.content.app.AppResource; import org.chromium.content.app.AppResource;
import org.chromium.content.app.ContentMain; import org.chromium.content.app.ContentMain;
import org.chromium.content.app.LibraryLoader; import org.chromium.content.app.LibraryLoader;
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ResourceExtractor;
import org.chromium.content.common.CommandLine; import org.chromium.content.common.CommandLine;
// NOTE: This file hasn't been fully upstreamed, please don't merge to downstream. // NOTE: This file hasn't been fully upstreamed, please don't merge to downstream.
...@@ -59,9 +57,10 @@ public class AndroidBrowserProcess { ...@@ -59,9 +57,10 @@ public class AndroidBrowserProcess {
* *
* @param context Context used to obtain the application context. * @param context Context used to obtain the application context.
* @param maxRendererProcesses See ContentView.enableMultiProcess(). * @param maxRendererProcesses See ContentView.enableMultiProcess().
* @return Whether the process actually needed to be initialized (false if already running).
*/ */
public static void initContentViewProcess(Context context, int maxRendererProcesses) { public static boolean initContentViewProcess(Context context, int maxRendererProcesses) {
genericChromiumProcessInit(context, maxRendererProcesses, false); return genericChromiumProcessInit(context, maxRendererProcesses, false);
} }
/** /**
...@@ -70,9 +69,10 @@ public class AndroidBrowserProcess { ...@@ -70,9 +69,10 @@ public class AndroidBrowserProcess {
* *
* @param context Context used to obtain the application context. * @param context Context used to obtain the application context.
* @param maxRendererProcesses See ContentView.enableMultiProcess(). * @param maxRendererProcesses See ContentView.enableMultiProcess().
* @return Whether the process actually needed to be initialized (false if already running).
*/ */
public static void initChromiumBrowserProcess(Context context, int maxRendererProcesses) { public static boolean initChromiumBrowserProcess(Context context, int maxRendererProcesses) {
genericChromiumProcessInit(context, maxRendererProcesses, true); return genericChromiumProcessInit(context, maxRendererProcesses, true);
} }
/** /**
...@@ -80,12 +80,11 @@ public class AndroidBrowserProcess { ...@@ -80,12 +80,11 @@ public class AndroidBrowserProcess {
* @param context Context used to obtain the application context * @param context Context used to obtain the application context
* @param maxRendererProcesses See ContentView.enableMultiProcess() * @param maxRendererProcesses See ContentView.enableMultiProcess()
* @param hostIsChrome pass true if running as the system browser process. * @param hostIsChrome pass true if running as the system browser process.
* @return Whether the process actually needed to be initialized (false if already running).
*/ */
private static void genericChromiumProcessInit(Context context, int maxRendererProcesses, private static boolean genericChromiumProcessInit(Context context, int maxRendererProcesses,
boolean hostIsChrome) { boolean hostIsChrome) {
if (sInitialized) { if (sInitialized) return false;
return;
}
sInitialized = true; sInitialized = true;
// Normally Main.java will have kicked this off asynchronously for Chrome. But // Normally Main.java will have kicked this off asynchronously for Chrome. But
...@@ -128,6 +127,7 @@ public class AndroidBrowserProcess { ...@@ -128,6 +127,7 @@ public class AndroidBrowserProcess {
nativeSetCommandLineFlags(maxRenderers, getPlugins(context)); nativeSetCommandLineFlags(maxRenderers, getPlugins(context));
ContentMain.initApplicationContext(appContext); ContentMain.initApplicationContext(appContext);
ContentMain.start(); ContentMain.start();
return true;
} }
private static String getPlugins(final Context context) { private static String getPlugins(final Context context) {
......
...@@ -73,9 +73,10 @@ public class ContentView extends FrameLayout implements ContentViewCore.Internal ...@@ -73,9 +73,10 @@ public class ContentView extends FrameLayout implements ContentViewCore.Internal
* application process in a separate thread. If the special value MAX_RENDERERS_AUTOMATIC is * application process in a separate thread. If the special value MAX_RENDERERS_AUTOMATIC is
* used then the number of renderers will be determined based on the device memory class. The * used then the number of renderers will be determined based on the device memory class. The
* maximum number of allowed renderers is capped by MAX_RENDERERS_LIMIT. * maximum number of allowed renderers is capped by MAX_RENDERERS_LIMIT.
* @return Whether the process actually needed to be initialized (false if already running).
*/ */
public static void enableMultiProcess(Context context, int maxRendererProcesses) { public static boolean enableMultiProcess(Context context, int maxRendererProcesses) {
ContentViewCore.enableMultiProcess(context, maxRendererProcesses); return ContentViewCore.enableMultiProcess(context, maxRendererProcesses);
} }
/** /**
...@@ -84,10 +85,11 @@ public class ContentView extends FrameLayout implements ContentViewCore.Internal ...@@ -84,10 +85,11 @@ public class ContentView extends FrameLayout implements ContentViewCore.Internal
* *
* @param context Context used to obtain the application context. * @param context Context used to obtain the application context.
* @param maxRendererProcesses Same as ContentView.enableMultiProcess() * @param maxRendererProcesses Same as ContentView.enableMultiProcess()
* @return Whether the process actually needed to be initialized (false if already running).
* @hide Only used by the platform browser. * @hide Only used by the platform browser.
*/ */
public static void initChromiumBrowserProcess(Context context, int maxRendererProcesses) { public static boolean initChromiumBrowserProcess(Context context, int maxRendererProcesses) {
ContentViewCore.initChromiumBrowserProcess(context, maxRendererProcesses); return ContentViewCore.initChromiumBrowserProcess(context, maxRendererProcesses);
} }
private ContentViewCore mContentViewCore; private ContentViewCore mContentViewCore;
......
...@@ -156,9 +156,10 @@ public class ContentViewCore { ...@@ -156,9 +156,10 @@ public class ContentViewCore {
* application process in a separate thread. If the special value MAX_RENDERERS_AUTOMATIC is * application process in a separate thread. If the special value MAX_RENDERERS_AUTOMATIC is
* used then the number of renderers will be determined based on the device memory class. The * used then the number of renderers will be determined based on the device memory class. The
* maximum number of allowed renderers is capped by MAX_RENDERERS_LIMIT. * maximum number of allowed renderers is capped by MAX_RENDERERS_LIMIT.
* @return Whether the process actually needed to be initialized (false if already running).
*/ */
public static void enableMultiProcess(Context context, int maxRendererProcesses) { public static boolean enableMultiProcess(Context context, int maxRendererProcesses) {
AndroidBrowserProcess.initContentViewProcess(context, maxRendererProcesses); return AndroidBrowserProcess.initContentViewProcess(context, maxRendererProcesses);
} }
/** /**
...@@ -167,10 +168,11 @@ public class ContentViewCore { ...@@ -167,10 +168,11 @@ public class ContentViewCore {
* *
* @param context Context used to obtain the application context. * @param context Context used to obtain the application context.
* @param maxRendererProcesses Same as ContentView.enableMultiProcess() * @param maxRendererProcesses Same as ContentView.enableMultiProcess()
* @return Whether the process actually needed to be initialized (false if already running).
* @hide Only used by the platform browser. * @hide Only used by the platform browser.
*/ */
public static void initChromiumBrowserProcess(Context context, int maxRendererProcesses) { public static boolean initChromiumBrowserProcess(Context context, int maxRendererProcesses) {
AndroidBrowserProcess.initChromiumBrowserProcess(context, maxRendererProcesses); return AndroidBrowserProcess.initChromiumBrowserProcess(context, maxRendererProcesses);
} }
/** /**
......
...@@ -24,6 +24,9 @@ public class ContentShellActivity extends Activity { ...@@ -24,6 +24,9 @@ public class ContentShellActivity extends Activity {
private static final String COMMAND_LINE_FILE = "/data/local/tmp/content-shell-command-line"; private static final String COMMAND_LINE_FILE = "/data/local/tmp/content-shell-command-line";
private static final String TAG = ContentShellActivity.class.getName(); private static final String TAG = ContentShellActivity.class.getName();
private static final String ACTIVE_SHELL_URL_KEY = "activeUrl";
private static final String DEFAULT_SHELL_URL = "http://www.google.com";
private ShellManager mShellManager; private ShellManager mShellManager;
@Override @Override
...@@ -31,7 +34,7 @@ public class ContentShellActivity extends Activity { ...@@ -31,7 +34,7 @@ public class ContentShellActivity extends Activity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// Initializing the command line must occur before loading the library. // Initializing the command line must occur before loading the library.
CommandLine.initFromFile(COMMAND_LINE_FILE); if (!CommandLine.isInitialized()) CommandLine.initFromFile(COMMAND_LINE_FILE);
String startupUrl = getUrlFromIntent(getIntent()); String startupUrl = getUrlFromIntent(getIntent());
if (!TextUtils.isEmpty(startupUrl)) { if (!TextUtils.isEmpty(startupUrl)) {
CommandLine.getInstance().appendSwitchesAndArguments( CommandLine.getInstance().appendSwitchesAndArguments(
...@@ -44,7 +47,23 @@ public class ContentShellActivity extends Activity { ...@@ -44,7 +47,23 @@ public class ContentShellActivity extends Activity {
setContentView(R.layout.content_shell_activity); setContentView(R.layout.content_shell_activity);
mShellManager = (ShellManager) findViewById(R.id.shell_container); mShellManager = (ShellManager) findViewById(R.id.shell_container);
ContentView.enableMultiProcess(this, ContentView.MAX_RENDERERS_AUTOMATIC); if (!ContentView.enableMultiProcess(this, ContentView.MAX_RENDERERS_AUTOMATIC)) {
String shellUrl = DEFAULT_SHELL_URL;
if (savedInstanceState != null
&& savedInstanceState.containsKey(ACTIVE_SHELL_URL_KEY)) {
shellUrl = savedInstanceState.getString(ACTIVE_SHELL_URL_KEY);
}
mShellManager.launchShell(shellUrl);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Shell activeShell = getActiveShell();
if (activeShell != null) {
outState.putString(ACTIVE_SHELL_URL_KEY, activeShell.getContentView().getUrl());
}
} }
private void waitForDebuggerIfNeeded() { private void waitForDebuggerIfNeeded() {
......
...@@ -161,6 +161,7 @@ public class Shell extends LinearLayout { ...@@ -161,6 +161,7 @@ public class Shell extends LinearLayout {
private void initFromNativeTabContents(int nativeTabContents) { private void initFromNativeTabContents(int nativeTabContents) {
mContentView = new ContentView( mContentView = new ContentView(
getContext(), nativeTabContents, ContentView.PERSONALITY_CHROME); getContext(), nativeTabContents, ContentView.PERSONALITY_CHROME);
if (mContentView.getUrl() != null) mUrlTextView.setText(mContentView.getUrl());
((FrameLayout) findViewById(R.id.contentview_holder)).addView(mContentView, ((FrameLayout) findViewById(R.id.contentview_holder)).addView(mContentView,
new FrameLayout.LayoutParams( new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT,
......
...@@ -35,6 +35,14 @@ public class ShellManager extends FrameLayout { ...@@ -35,6 +35,14 @@ public class ShellManager extends FrameLayout {
return mActiveShell; return mActiveShell;
} }
/**
* Creates a new shell pointing to the specified URL.
* @param url The URL the shell should load upon creation.
*/
public void launchShell(String url) {
nativeLaunchShell(url);
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
@CalledByNative @CalledByNative
private Object createShell() { private Object createShell() {
...@@ -51,4 +59,5 @@ public class ShellManager extends FrameLayout { ...@@ -51,4 +59,5 @@ public class ShellManager extends FrameLayout {
} }
private static native void nativeInit(Object shellManagerInstance); private static native void nativeInit(Object shellManagerInstance);
private static native void nativeLaunchShell(String url);
} }
...@@ -5,8 +5,13 @@ ...@@ -5,8 +5,13 @@
#include "content/shell/android/shell_manager.h" #include "content/shell/android/shell_manager.h"
#include "base/android/jni_android.h" #include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "content/shell/shell.h"
#include "content/shell/shell_browser_context.h"
#include "content/shell/shell_content_browser_client.h"
#include "googleurl/src/gurl.h"
#include "jni/ShellManager_jni.h" #include "jni/ShellManager_jni.h"
using base::android::ScopedJavaLocalRef; using base::android::ScopedJavaLocalRef;
...@@ -32,4 +37,16 @@ static void Init(JNIEnv* env, jclass clazz, jobject obj) { ...@@ -32,4 +37,16 @@ static void Init(JNIEnv* env, jclass clazz, jobject obj) {
base::android::ScopedJavaLocalRef<jobject>(env, obj)); base::android::ScopedJavaLocalRef<jobject>(env, obj));
} }
void LaunchShell(JNIEnv* env, jclass clazz, jstring jurl) {
ShellBrowserContext* browserContext =
static_cast<ShellContentBrowserClient*>(
GetContentClient()->browser())->browser_context();
GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
Shell::CreateNewWindow(browserContext,
url,
NULL,
MSG_ROUTING_NONE,
NULL);
}
} // namespace content } // namespace content
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