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