mirror of
https://github.com/Alex313031/thorium.git
synced 2025-01-09 11:27:32 -03:00
fix android content_shell
This commit is contained in:
parent
7b0c92dc8d
commit
59a4a5a4fd
7 changed files with 10 additions and 643 deletions
|
@ -54,7 +54,7 @@ buildARM32 () {
|
|||
# Build Thorium for ARM32
|
||||
export NINJA_SUMMARIZE_BUILD=1 &&
|
||||
|
||||
./depot_tools/autoninja -C ~/chromium/src/out/thorium chrome_public_apk system_webview_apk -j$@ &&
|
||||
./depot_tools/autoninja -C ~/chromium/src/out/thorium chrome_public_apk content_shell_apk system_webview_apk -j$@ &&
|
||||
# ADD # thorium_shell_apk
|
||||
mv ~/chromium/src/out/thorium/apks/ChromePublic.apk ~/chromium/src/out/thorium/apks/Thorium_Public_arm32.apk &&
|
||||
|
||||
|
@ -71,7 +71,7 @@ esac
|
|||
# Build Thorium for ARM64
|
||||
export NINJA_SUMMARIZE_BUILD=1 &&
|
||||
# ADD # thorium_shell_apk
|
||||
./depot_tools/autoninja -C ~/chromium/src/out/thorium chrome_public_apk -j$@ &&
|
||||
./depot_tools/autoninja -C ~/chromium/src/out/thorium content_shell_apk chrome_public_apk -j$@ &&
|
||||
|
||||
mv ~/chromium/src/out/thorium/apks/ChromePublic.apk ~/chromium/src/out/thorium/apks/Thorium_Public_arm64.apk &&
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ group("gn_all") {
|
|||
"//chrome/test:android_browsertests",
|
||||
"//components:components_junit_tests",
|
||||
"//content/public/android:content_junit_tests",
|
||||
"//content/shell/android:thorium_shell_apk",
|
||||
"//content/shell/android:content_shell_apk",
|
||||
"//device:device_junit_tests",
|
||||
"//media/gpu:video_decode_accelerator_unittest",
|
||||
"//net/android:net_junit_tests",
|
||||
|
@ -408,7 +408,7 @@ group("gn_all") {
|
|||
"//chrome/android:chrome_public_unit_test_apk",
|
||||
"//chrome/browser/android/examples/custom_tabs_client:custom_tabs_client_example_apk",
|
||||
"//chrome/browser/android/examples/partner_browser_customizations_provider:partner_browser_customizations_example_apk",
|
||||
"//content/shell/android:thorium_shell_test_apk",
|
||||
"//content/shell/android:content_shell_test_apk",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ repack("pak") {
|
|||
if (is_android) {
|
||||
group("thorium_shell") {
|
||||
testonly = true
|
||||
deps = [ "//content/shell/android:thorium_shell_apk" ]
|
||||
deps = [ "//content/shell/android:content_shell_apk" ]
|
||||
}
|
||||
} else if (is_mac) {
|
||||
tweak_info_plist("content_shell_plist") {
|
||||
|
|
|
@ -75,7 +75,7 @@ android_resources("content_shell_java_resources") {
|
|||
|
||||
android_library("content_shell_java") {
|
||||
testonly = true
|
||||
resources_package = "org.chromium.thorium_shell"
|
||||
resources_package = "org.chromium.content_shell"
|
||||
deps = [
|
||||
":content_shell_java_resources",
|
||||
":content_shell_manifest",
|
||||
|
@ -108,7 +108,7 @@ jinja_template("content_shell_manifest") {
|
|||
testonly = true
|
||||
input = "shell_apk/AndroidManifest.xml.jinja2"
|
||||
output = content_shell_manifest
|
||||
variables = [ "manifest_package=org.chromium.thorium_shell_apk" ]
|
||||
variables = [ "manifest_package=org.chromium.content_shell_apk" ]
|
||||
}
|
||||
|
||||
jinja_template("content_shell_test_manifest") {
|
||||
|
@ -133,7 +133,7 @@ android_library("content_shell_apk_java") {
|
|||
|
||||
srcjar_deps = [ ":content_javatests_aidl" ]
|
||||
|
||||
resources_package = "org.chromium.thorium_shell_apk"
|
||||
resources_package = "org.chromium.content_shell_apk"
|
||||
deps = [
|
||||
":content_shell_apk_resources",
|
||||
":content_shell_java",
|
||||
|
@ -206,7 +206,7 @@ template("content_shell_apk_tmpl") {
|
|||
}
|
||||
}
|
||||
|
||||
content_shell_apk_tmpl("thorium_shell_apk") {
|
||||
content_shell_apk_tmpl("content_shell_apk") {
|
||||
target_type = "android_apk"
|
||||
apk_name = "ThoriumShell"
|
||||
android_manifest = content_shell_manifest
|
||||
|
@ -215,7 +215,7 @@ content_shell_apk_tmpl("thorium_shell_apk") {
|
|||
command_line_flags_file = "content-shell-command-line"
|
||||
}
|
||||
|
||||
content_shell_apk_tmpl("thorium_shell_test_apk") {
|
||||
content_shell_apk_tmpl("content_shell_test_apk") {
|
||||
target_type = "instrumentation_test_apk"
|
||||
apk_name = "ThoriumShellTest"
|
||||
android_manifest = content_shell_test_manifest
|
||||
|
|
|
@ -1,421 +0,0 @@
|
|||
// Copyright 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.thorium_shell;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ActionMode;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.base.annotations.NativeMethods;
|
||||
import org.chromium.components.embedder_support.view.ContentView;
|
||||
import org.chromium.components.embedder_support.view.ContentViewRenderView;
|
||||
import org.chromium.content_public.browser.ActionModeCallbackHelper;
|
||||
import org.chromium.content_public.browser.LoadUrlParams;
|
||||
import org.chromium.content_public.browser.NavigationController;
|
||||
import org.chromium.content_public.browser.SelectionPopupController;
|
||||
import org.chromium.content_public.browser.WebContents;
|
||||
import org.chromium.ui.base.ViewAndroidDelegate;
|
||||
import org.chromium.ui.base.WindowAndroid;
|
||||
|
||||
/**
|
||||
* Container for the various UI components that make up a shell window.
|
||||
*/
|
||||
@JNINamespace("content")
|
||||
public class Shell extends LinearLayout {
|
||||
|
||||
private static final long COMPLETED_PROGRESS_TIMEOUT_MS = 200;
|
||||
|
||||
// Stylus handwriting: Setting this ime option instructs stylus writing service to restrict
|
||||
// capturing writing events slightly outside the Url bar area. This is needed to prevent stylus
|
||||
// handwriting in inputs in web content area that are very close to url bar area, from being
|
||||
// committed to Url bar's Edit text. Ex: google.com search field.
|
||||
private static final String IME_OPTION_RESTRICT_STYLUS_WRITING_AREA =
|
||||
"restrictDirectWritingArea=true";
|
||||
|
||||
private final Runnable mClearProgressRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mProgressDrawable.setLevel(0);
|
||||
}
|
||||
};
|
||||
|
||||
private WebContents mWebContents;
|
||||
private NavigationController mNavigationController;
|
||||
private EditText mUrlTextView;
|
||||
private ImageButton mPrevButton;
|
||||
private ImageButton mNextButton;
|
||||
private ImageButton mStopReloadButton;
|
||||
|
||||
private ClipDrawable mProgressDrawable;
|
||||
|
||||
private long mNativeShell;
|
||||
private ContentViewRenderView mContentViewRenderView;
|
||||
private WindowAndroid mWindow;
|
||||
private ShellViewAndroidDelegate mViewAndroidDelegate;
|
||||
|
||||
private boolean mLoading;
|
||||
private boolean mIsFullscreen;
|
||||
|
||||
private Callback<Boolean> mOverlayModeChangedCallbackForTesting;
|
||||
|
||||
/**
|
||||
* Constructor for inflating via XML.
|
||||
*/
|
||||
public Shell(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SurfaceView being renderered to as soon as it is available.
|
||||
*/
|
||||
public void setContentViewRenderView(ContentViewRenderView contentViewRenderView) {
|
||||
FrameLayout contentViewHolder = (FrameLayout) findViewById(R.id.contentview_holder);
|
||||
if (contentViewRenderView == null) {
|
||||
if (mContentViewRenderView != null) {
|
||||
contentViewHolder.removeView(mContentViewRenderView);
|
||||
}
|
||||
} else {
|
||||
contentViewHolder.addView(contentViewRenderView,
|
||||
new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.MATCH_PARENT));
|
||||
}
|
||||
mContentViewRenderView = contentViewRenderView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Shell for use.
|
||||
*
|
||||
* @param nativeShell The pointer to the native Shell object.
|
||||
* @param window The owning window for this shell.
|
||||
*/
|
||||
public void initialize(long nativeShell, WindowAndroid window) {
|
||||
mNativeShell = nativeShell;
|
||||
mWindow = window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the shell and cleans up the native instance, which will handle destroying all
|
||||
* dependencies.
|
||||
*/
|
||||
public void close() {
|
||||
if (mNativeShell == 0) return;
|
||||
ShellJni.get().closeShell(mNativeShell);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
private void onNativeDestroyed() {
|
||||
mWindow = null;
|
||||
mNativeShell = 0;
|
||||
mWebContents = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the Shell has been destroyed.
|
||||
* @see #onNativeDestroyed()
|
||||
*/
|
||||
public boolean isDestroyed() {
|
||||
return mNativeShell == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether or not the Shell is loading content.
|
||||
*/
|
||||
public boolean isLoading() {
|
||||
return mLoading;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
View toolbar = findViewById(R.id.toolbar);
|
||||
mProgressDrawable = (ClipDrawable) toolbar.getBackground();
|
||||
initializeUrlField();
|
||||
initializeNavigationButtons();
|
||||
}
|
||||
|
||||
private void initializeUrlField() {
|
||||
mUrlTextView = (EditText) findViewById(R.id.url);
|
||||
mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null
|
||||
|| event.getKeyCode() != KeyEvent.KEYCODE_ENTER
|
||||
|| event.getAction() != KeyEvent.ACTION_DOWN)) {
|
||||
return false;
|
||||
}
|
||||
loadUrl(mUrlTextView.getText().toString());
|
||||
setKeyboardVisibilityForUrl(false);
|
||||
getContentView().requestFocus();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
setKeyboardVisibilityForUrl(hasFocus);
|
||||
mNextButton.setVisibility(hasFocus ? GONE : VISIBLE);
|
||||
mPrevButton.setVisibility(hasFocus ? GONE : VISIBLE);
|
||||
mStopReloadButton.setVisibility(hasFocus ? GONE : VISIBLE);
|
||||
if (!hasFocus) {
|
||||
mUrlTextView.setText(mWebContents.getVisibleUrl().getSpec());
|
||||
}
|
||||
}
|
||||
});
|
||||
mUrlTextView.setOnKeyListener(new OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
getContentView().requestFocus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
mUrlTextView.setPrivateImeOptions(IME_OPTION_RESTRICT_STYLUS_WRITING_AREA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an URL. This will perform minimal amounts of sanitizing of the URL to attempt to
|
||||
* make it valid.
|
||||
*
|
||||
* @param url The URL to be loaded by the shell.
|
||||
*/
|
||||
public void loadUrl(String url) {
|
||||
if (url == null) return;
|
||||
|
||||
if (TextUtils.equals(url, mWebContents.getLastCommittedUrl().getSpec())) {
|
||||
mNavigationController.reload(true);
|
||||
} else {
|
||||
mNavigationController.loadUrl(new LoadUrlParams(sanitizeUrl(url)));
|
||||
}
|
||||
mUrlTextView.clearFocus();
|
||||
// TODO(aurimas): Remove this when crbug.com/174541 is fixed.
|
||||
getContentView().clearFocus();
|
||||
getContentView().requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an URL, this performs minimal sanitizing to ensure it will be valid.
|
||||
* @param url The url to be sanitized.
|
||||
* @return The sanitized URL.
|
||||
*/
|
||||
public static String sanitizeUrl(String url) {
|
||||
if (url == null) return null;
|
||||
if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
|
||||
return url;
|
||||
}
|
||||
|
||||
private void initializeNavigationButtons() {
|
||||
mPrevButton = (ImageButton) findViewById(R.id.prev);
|
||||
mPrevButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mNavigationController.canGoBack()) mNavigationController.goBack();
|
||||
}
|
||||
});
|
||||
|
||||
mNextButton = (ImageButton) findViewById(R.id.next);
|
||||
mNextButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mNavigationController.canGoForward()) mNavigationController.goForward();
|
||||
}
|
||||
});
|
||||
mStopReloadButton = (ImageButton) findViewById(R.id.stop_reload_button);
|
||||
mStopReloadButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mLoading) mWebContents.stop();
|
||||
else mNavigationController.reload(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
private void onUpdateUrl(String url) {
|
||||
mUrlTextView.setText(url);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
private void onLoadProgressChanged(double progress) {
|
||||
removeCallbacks(mClearProgressRunnable);
|
||||
mProgressDrawable.setLevel((int) (10000.0 * progress));
|
||||
if (progress == 1.0) postDelayed(mClearProgressRunnable, COMPLETED_PROGRESS_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
private void toggleFullscreenModeForTab(boolean enterFullscreen) {
|
||||
mIsFullscreen = enterFullscreen;
|
||||
LinearLayout toolBar = (LinearLayout) findViewById(R.id.toolbar);
|
||||
toolBar.setVisibility(enterFullscreen ? GONE : VISIBLE);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
private boolean isFullscreenForTabOrPending() {
|
||||
return mIsFullscreen;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
private void setIsLoading(boolean loading) {
|
||||
mLoading = loading;
|
||||
if (mLoading) {
|
||||
mStopReloadButton
|
||||
.setImageResource(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
} else {
|
||||
mStopReloadButton.setImageResource(R.drawable.ic_refresh);
|
||||
}
|
||||
}
|
||||
|
||||
public ShellViewAndroidDelegate getViewAndroidDelegate() {
|
||||
return mViewAndroidDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the ContentView based on the native tab contents pointer passed in.
|
||||
* @param webContents A {@link WebContents} object.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
private void initFromNativeTabContents(WebContents webContents) {
|
||||
Context context = getContext();
|
||||
ContentView cv =
|
||||
ContentView.createContentView(context, null /* eventOffsetHandler */, webContents);
|
||||
mViewAndroidDelegate = new ShellViewAndroidDelegate(cv);
|
||||
assert (mWebContents != webContents);
|
||||
if (mWebContents != null) mWebContents.clearNativeReference();
|
||||
webContents.initialize(
|
||||
"", mViewAndroidDelegate, cv, mWindow, WebContents.createDefaultInternalsHolder());
|
||||
mWebContents = webContents;
|
||||
SelectionPopupController.fromWebContents(webContents)
|
||||
.setActionModeCallback(defaultActionCallback());
|
||||
mNavigationController = mWebContents.getNavigationController();
|
||||
if (getParent() != null) mWebContents.onShow();
|
||||
mUrlTextView.setText(mWebContents.getVisibleUrl().getSpec());
|
||||
((FrameLayout) findViewById(R.id.contentview_holder)).addView(cv,
|
||||
new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.MATCH_PARENT));
|
||||
cv.requestFocus();
|
||||
mContentViewRenderView.setCurrentWebContents(mWebContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* {link @ActionMode.Callback} that uses the default implementation in
|
||||
* {@link SelectionPopupController}.
|
||||
*/
|
||||
private ActionMode.Callback2 defaultActionCallback() {
|
||||
final ActionModeCallbackHelper helper =
|
||||
SelectionPopupController.fromWebContents(mWebContents)
|
||||
.getActionModeCallbackHelper();
|
||||
|
||||
return new ActionMode.Callback2() {
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
helper.onCreateActionMode(mode, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return helper.onPrepareActionMode(mode, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
return helper.onActionItemClicked(mode, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
helper.onDestroyActionMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
|
||||
helper.onGetContentRect(mode, view, outRect);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void setOverlayMode(boolean useOverlayMode) {
|
||||
mContentViewRenderView.setOverlayVideoMode(useOverlayMode);
|
||||
if (mOverlayModeChangedCallbackForTesting != null) {
|
||||
mOverlayModeChangedCallbackForTesting.onResult(useOverlayMode);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOverayModeChangedCallbackForTesting(Callback<Boolean> callback) {
|
||||
mOverlayModeChangedCallbackForTesting = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable navigation(Prev/Next) button if navigation is allowed/disallowed
|
||||
* in respective direction.
|
||||
* @param controlId Id of button to update
|
||||
* @param enabled enable/disable value
|
||||
*/
|
||||
@CalledByNative
|
||||
private void enableUiControl(int controlId, boolean enabled) {
|
||||
if (controlId == 0) {
|
||||
mPrevButton.setEnabled(enabled);
|
||||
} else if (controlId == 1) {
|
||||
mNextButton.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The {@link View} currently shown by this Shell.
|
||||
*/
|
||||
public View getContentView() {
|
||||
ViewAndroidDelegate viewDelegate = mWebContents.getViewAndroidDelegate();
|
||||
return viewDelegate != null ? viewDelegate.getContainerView() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The {@link WebContents} currently managing the content shown by this Shell.
|
||||
*/
|
||||
public WebContents getWebContents() {
|
||||
return mWebContents;
|
||||
}
|
||||
|
||||
private void setKeyboardVisibilityForUrl(boolean visible) {
|
||||
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
|
||||
Context.INPUT_METHOD_SERVICE);
|
||||
if (visible) {
|
||||
imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
|
||||
} else {
|
||||
imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@NativeMethods
|
||||
interface Natives {
|
||||
void closeShell(long shellPtr);
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
// Copyright 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.thorium_shell;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.chromium.base.ThreadUtils;
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.base.annotations.NativeMethods;
|
||||
import org.chromium.components.embedder_support.view.ContentViewRenderView;
|
||||
import org.chromium.content_public.browser.WebContents;
|
||||
import org.chromium.ui.base.WindowAndroid;
|
||||
|
||||
/**
|
||||
* Container and generator of ShellViews.
|
||||
*/
|
||||
@JNINamespace("content")
|
||||
public class ShellManager extends FrameLayout {
|
||||
|
||||
public static final String DEFAULT_SHELL_URL = "http://www.google.com";
|
||||
private WindowAndroid mWindow;
|
||||
private Shell mActiveShell;
|
||||
|
||||
private String mStartupUrl = DEFAULT_SHELL_URL;
|
||||
|
||||
// The target for all content rendering.
|
||||
private ContentViewRenderView mContentViewRenderView;
|
||||
|
||||
/**
|
||||
* Constructor for inflating via XML.
|
||||
*/
|
||||
public ShellManager(final Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
ShellManagerJni.get().init(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param window The window used to generate all shells.
|
||||
*/
|
||||
public void setWindow(WindowAndroid window) {
|
||||
assert window != null;
|
||||
mWindow = window;
|
||||
mContentViewRenderView = new ContentViewRenderView(getContext());
|
||||
mContentViewRenderView.onNativeLibraryLoaded(window);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The window used to generate all shells.
|
||||
*/
|
||||
public WindowAndroid getWindow() {
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ContentViewRenderView.
|
||||
*/
|
||||
public ContentViewRenderView getContentViewRenderView() {
|
||||
return mContentViewRenderView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the startup URL for new shell windows.
|
||||
*/
|
||||
public void setStartupUrl(String url) {
|
||||
mStartupUrl = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The currently visible shell view or null if one is not showing.
|
||||
*/
|
||||
public Shell getActiveShell() {
|
||||
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) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
Shell previousShell = mActiveShell;
|
||||
ShellManagerJni.get().launchShell(url);
|
||||
if (previousShell != null) previousShell.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
private Object createShell(long nativeShellPtr) {
|
||||
if (mContentViewRenderView == null) {
|
||||
mContentViewRenderView = new ContentViewRenderView(getContext());
|
||||
mContentViewRenderView.onNativeLibraryLoaded(mWindow);
|
||||
}
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
Shell shellView = (Shell) inflater.inflate(R.layout.shell_view, null);
|
||||
shellView.initialize(nativeShellPtr, mWindow);
|
||||
|
||||
// TODO(tedchoc): Allow switching back to these inactive shells.
|
||||
if (mActiveShell != null) removeShell(mActiveShell);
|
||||
|
||||
showShell(shellView);
|
||||
return shellView;
|
||||
}
|
||||
|
||||
private void showShell(Shell shellView) {
|
||||
shellView.setContentViewRenderView(mContentViewRenderView);
|
||||
addView(shellView, new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
|
||||
mActiveShell = shellView;
|
||||
WebContents webContents = mActiveShell.getWebContents();
|
||||
if (webContents != null) {
|
||||
mContentViewRenderView.setCurrentWebContents(webContents);
|
||||
webContents.onShow();
|
||||
}
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
private void removeShell(Shell shellView) {
|
||||
if (shellView == mActiveShell) mActiveShell = null;
|
||||
if (shellView.getParent() == null) return;
|
||||
shellView.setContentViewRenderView(null);
|
||||
removeView(shellView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the Shell manager and associated components.
|
||||
* Always called at activity exit, and potentially called by native in cases where we need to
|
||||
* control the timing of mContentViewRenderView destruction. Must handle being called twice.
|
||||
*/
|
||||
@CalledByNative
|
||||
public void destroy() {
|
||||
// Remove active shell (Currently single shell support only available).
|
||||
if (mActiveShell != null) {
|
||||
removeShell(mActiveShell);
|
||||
}
|
||||
if (mContentViewRenderView != null) {
|
||||
mContentViewRenderView.destroy();
|
||||
mContentViewRenderView = null;
|
||||
}
|
||||
}
|
||||
|
||||
@NativeMethods
|
||||
interface Natives {
|
||||
void init(Object shellManagerInstance);
|
||||
void launchShell(String url);
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright 2017 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.thorium_shell;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.chromium.ui.base.ViewAndroidDelegate;
|
||||
import org.chromium.ui.mojom.CursorType;
|
||||
|
||||
/**
|
||||
* Implementation of the abstract class {@link ViewAndroidDelegate} for content shell.
|
||||
* Extended for testing.
|
||||
*/
|
||||
public class ShellViewAndroidDelegate extends ViewAndroidDelegate {
|
||||
/**
|
||||
* An interface delegates a {@link CallbackHelper} for cursor update. see more in {@link
|
||||
* ContentViewPointerTypeTest.OnCursorUpdateHelperImpl}.
|
||||
*/
|
||||
public interface OnCursorUpdateHelper {
|
||||
/**
|
||||
* Record the last notifyCalled pointer type, see more {@link CallbackHelper#notifyCalled}.
|
||||
* @param type The pointer type of the notifyCalled.
|
||||
*/
|
||||
void notifyCalled(int type);
|
||||
}
|
||||
|
||||
private OnCursorUpdateHelper mOnCursorUpdateHelper;
|
||||
|
||||
public ShellViewAndroidDelegate(ViewGroup containerView) {
|
||||
super(containerView);
|
||||
}
|
||||
|
||||
public void setOnCursorUpdateHelper(OnCursorUpdateHelper helper) {
|
||||
mOnCursorUpdateHelper = helper;
|
||||
}
|
||||
|
||||
public OnCursorUpdateHelper getOnCursorUpdateHelper() {
|
||||
return mOnCursorUpdateHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCursorChangedToCustom(Bitmap customCursorBitmap, int hotspotX, int hotspotY) {
|
||||
super.onCursorChangedToCustom(customCursorBitmap, hotspotX, hotspotY);
|
||||
if (mOnCursorUpdateHelper != null) {
|
||||
mOnCursorUpdateHelper.notifyCalled(CursorType.CUSTOM);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCursorChanged(int cursorType) {
|
||||
super.onCursorChanged(cursorType);
|
||||
if (mOnCursorUpdateHelper != null) {
|
||||
mOnCursorUpdateHelper.notifyCalled(cursorType);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue