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 5 package org.chromium.content_shell; 6 7 import android.app.Activity; 8 import android.content.Context; 9 import android.util.AttributeSet; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.widget.FrameLayout; 13 14 import org.chromium.base.CalledByNative; 15 import org.chromium.base.JNINamespace; 16 import org.chromium.base.ThreadUtils; 17 import org.chromium.content.browser.ActivityContentVideoViewClient; 18 import org.chromium.content.browser.ContentVideoViewClient; 19 import org.chromium.content.browser.ContentViewClient; 20 import org.chromium.content.browser.ContentViewCore; 21 import org.chromium.content.browser.ContentViewRenderView; 22 import org.chromium.ui.base.WindowAndroid; 23 24 /** 25 * Container and generator of ShellViews. 26 */ 27 @JNINamespace("content") 28 public class ShellManager extends FrameLayout { 29 30 public static final String DEFAULT_SHELL_URL = "http://www.google.com"; 31 private static boolean sStartup = true; 32 private WindowAndroid mWindow; 33 private Shell mActiveShell; 34 35 private String mStartupUrl = DEFAULT_SHELL_URL; 36 37 // The target for all content rendering. 38 private ContentViewRenderView mContentViewRenderView; 39 private ContentViewClient mContentViewClient; 40 41 /** 42 * Constructor for inflating via XML. 43 */ 44 public ShellManager(final Context context, AttributeSet attrs) { 45 super(context, attrs); 46 nativeInit(this); 47 mContentViewClient = new ContentViewClient() { 48 @Override 49 public ContentVideoViewClient getContentVideoViewClient() { 50 return new ActivityContentVideoViewClient((Activity) context) { 51 @Override 52 public boolean onShowCustomView(View view) { 53 boolean success = super.onShowCustomView(view); 54 setOverlayVideoMode(true); 55 return success; 56 } 57 58 @Override 59 public void onDestroyContentVideoView() { 60 super.onDestroyContentVideoView(); 61 setOverlayVideoMode(false); 62 } 63 }; 64 } 65 }; 66 } 67 68 /** 69 * @param window The window used to generate all shells. 70 */ 71 public void setWindow(WindowAndroid window) { 72 assert window != null; 73 mWindow = window; 74 mContentViewRenderView = new ContentViewRenderView(getContext()) { 75 @Override 76 protected void onReadyToRender() { 77 if (sStartup) { 78 mActiveShell.loadUrl(mStartupUrl); 79 sStartup = false; 80 } 81 } 82 }; 83 mContentViewRenderView.onNativeLibraryLoaded(window); 84 } 85 86 /** 87 * @return The window used to generate all shells. 88 */ 89 public WindowAndroid getWindow() { 90 return mWindow; 91 } 92 93 /** 94 * Sets the startup URL for new shell windows. 95 */ 96 public void setStartupUrl(String url) { 97 mStartupUrl = url; 98 } 99 100 /** 101 * @return The currently visible shell view or null if one is not showing. 102 */ 103 public Shell getActiveShell() { 104 return mActiveShell; 105 } 106 107 /** 108 * Creates a new shell pointing to the specified URL. 109 * @param url The URL the shell should load upon creation. 110 */ 111 public void launchShell(String url) { 112 ThreadUtils.assertOnUiThread(); 113 Shell previousShell = mActiveShell; 114 nativeLaunchShell(url); 115 if (previousShell != null) previousShell.close(); 116 } 117 118 /** 119 * Enter or leave overlay video mode. 120 * @param enabled Whether overlay mode is enabled. 121 */ 122 public void setOverlayVideoMode(boolean enabled) { 123 if (mContentViewRenderView == null) return; 124 mContentViewRenderView.setOverlayVideoMode(enabled); 125 } 126 127 @SuppressWarnings("unused") 128 @CalledByNative 129 private Object createShell(long nativeShellPtr) { 130 assert mContentViewRenderView != null; 131 LayoutInflater inflater = 132 (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 133 Shell shellView = (Shell) inflater.inflate(R.layout.shell_view, null); 134 shellView.initialize(nativeShellPtr, mWindow, mContentViewClient); 135 136 // TODO(tedchoc): Allow switching back to these inactive shells. 137 if (mActiveShell != null) removeShell(mActiveShell); 138 139 showShell(shellView); 140 return shellView; 141 } 142 143 private void showShell(Shell shellView) { 144 shellView.setContentViewRenderView(mContentViewRenderView); 145 addView(shellView, new FrameLayout.LayoutParams( 146 FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); 147 mActiveShell = shellView; 148 ContentViewCore contentViewCore = mActiveShell.getContentViewCore(); 149 if (contentViewCore != null) { 150 mContentViewRenderView.setCurrentContentViewCore(contentViewCore); 151 contentViewCore.onShow(); 152 } 153 } 154 155 @CalledByNative 156 private void removeShell(Shell shellView) { 157 if (shellView == mActiveShell) mActiveShell = null; 158 if (shellView.getParent() == null) return; 159 ContentViewCore contentViewCore = shellView.getContentViewCore(); 160 if (contentViewCore != null) contentViewCore.onHide(); 161 shellView.setContentViewRenderView(null); 162 removeView(shellView); 163 } 164 165 private static native void nativeInit(Object shellManagerInstance); 166 private static native void nativeLaunchShell(String url); 167 } 168