package com.borqs.browser; import java.util.List; import org.chromium.content.browser.ContentView; import org.chromium.content.browser.ContentViewRenderView; import com.borqs.browser.Tab.SecurityState; import com.borqs.browser.combo.ComboViewActivityMine; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.PaintDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.Toast; /** * UI interface definitions */ public abstract class BaseUi implements UI { private static final String LOGTAG = "BaseUi"; protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); protected static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER); private static final int MSG_HIDE_TITLEBAR = 1; public static final int HIDE_TITLEBAR_DELAY = 1500; // in ms Activity mActivity; UiController mUiController; TabControl mTabControl; protected Tab mActiveTab; private InputMethodManager mInputManager; private Drawable mLockIconSecure; private Drawable mLockIconMixed; protected Drawable mGenericFavicon; protected FrameLayout mContentView; protected FrameLayout mCustomViewContainer; protected FrameLayout mFullscreenContainer; private FrameLayout mFixedTitlebarContainer; private View mCustomView; // private WebChromeClient.CustomViewCallback mCustomViewCallback; private int mOriginalOrientation; private LinearLayout mErrorConsoleContainer = null; private UrlBarAutoShowManager mUrlBarAutoShowManager; private Toast mStopToast; // the default <video> poster private Bitmap mDefaultVideoPoster; // the video progress view private View mVideoProgressView; private boolean mActivityPaused; protected boolean mUseQuickControls; protected TitleBar mTitleBar; private NavigationBarBase mNavigationBar; // protected PieControl mPieControl; private boolean mBlockFocusAnimations; public BaseUi(Activity browser, UiController controller) { mActivity = browser; mUiController = controller; mTabControl = controller.getTabControl(); Resources res = mActivity.getResources(); mInputManager = (InputMethodManager) browser.getSystemService(Activity.INPUT_METHOD_SERVICE); mLockIconSecure = res.getDrawable(R.drawable.ic_secure_holo_dark); mLockIconMixed = res.getDrawable(R.drawable.ic_secure_partial_holo_dark); FrameLayout frameLayout = (FrameLayout) mActivity.getWindow() .getDecorView().findViewById(android.R.id.content); LayoutInflater.from(mActivity) .inflate(R.layout.custom_screen, frameLayout); mFixedTitlebarContainer = (FrameLayout) frameLayout.findViewById( R.id.fixed_titlebar_container); mContentView = (FrameLayout) frameLayout.findViewById( R.id.main_content); mCustomViewContainer = (FrameLayout) frameLayout.findViewById( R.id.fullscreen_custom_content); // mErrorConsoleContainer = (LinearLayout) frameLayout // .findViewById(R.id.error_console); setFullscreen(BrowserSettings.getInstance().useFullscreen()); //setFullscreen(false); mGenericFavicon = res.getDrawable( R.drawable.app_web_browser_sm); mTitleBar = new TitleBar(mActivity, mUiController, this, mContentView); mTitleBar.setProgress(100); mNavigationBar = mTitleBar.getNavigationBar(); mUrlBarAutoShowManager = new UrlBarAutoShowManager(this); } private void cancelStopToast() { if (mStopToast != null) { mStopToast.cancel(); mStopToast = null; } } public void editUrl(boolean clearInput, boolean forceIME) { if (mUiController.isInCustomActionMode()) { mUiController.endActionMode(); } showTitleBar(); if ((getActiveTab() != null) && !getActiveTab().isSnapshot()) { mNavigationBar.startEditingUrl(clearInput, forceIME); } } boolean canShowTitleBar() { return !isTitleBarShowing() && !isActivityPaused() && (getActiveTab() != null) && (getContentView() != null) && !mUiController.isInCustomActionMode(); } protected void showTitleBar() { mHandler.removeMessages(MSG_HIDE_TITLEBAR); if (canShowTitleBar()) { mTitleBar.show(); } } protected void hideTitleBar() { if (mTitleBar.isShowing()) { mTitleBar.hide(); } } protected boolean isTitleBarShowing() { return mTitleBar.isShowing(); } public boolean isEditingUrl() { return mTitleBar.isEditingUrl(); } public void stopEditingUrl() { mTitleBar.getNavigationBar().stopEditingUrl(); } public TitleBar getTitleBar() { return mTitleBar; } protected void setUrlTitle(Tab tab) { String url = tab.getUrl(); String title = tab.getTitle(); if (TextUtils.isEmpty(title)) { title = url; } if (tab.inForeground()) { mNavigationBar.setDisplayTitle(url); } } // Set the favicon in the title bar. protected void setFavicon(Tab tab) { if (tab.inForeground()) { Bitmap icon = tab.getFavicon(); mNavigationBar.setFavicon(icon); } } protected void updateNavigationState(Tab tab) { } /* @Override public void showComboView(ComboViews startingView, Bundle extras) { Intent intent = new Intent(mActivity, ComboViewActivity.class); intent.putExtra(ComboViewActivity.EXTRA_INITIAL_VIEW, startingView.name()); intent.putExtra(ComboViewActivity.EXTRA_COMBO_ARGS, extras); Tab t = getActiveTab(); if (t != null) { intent.putExtra(ComboViewActivity.EXTRA_CURRENT_URL, t.getUrl()); } mActivity.startActivityForResult(intent, Controller.COMBO_VIEW); } */ @Override public void showCustomView(View view, int requestedOrientation) { // if a view already exists then immediately terminate the new one if (mCustomView != null) { // callback.onCustomViewHidden(); return; } mOriginalOrientation = mActivity.getRequestedOrientation(); FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView(); mFullscreenContainer = new FullscreenHolder(mActivity); mFullscreenContainer.addView(view, COVER_SCREEN_PARAMS); decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS); mCustomView = view; setFullscreen(true); getContentView().setVisibility(View.INVISIBLE); // mCustomViewCallback = callback; mActivity.setRequestedOrientation(requestedOrientation); } @Override public void onHideCustomView() { getContentView().setVisibility(View.VISIBLE); if (mCustomView == null) return; setFullscreen(false); FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView(); decor.removeView(mFullscreenContainer); mFullscreenContainer = null; mCustomView = null; // mCustomViewCallback.onCustomViewHidden(); // Show the content view. mActivity.setRequestedOrientation(mOriginalOrientation); } @Override public boolean isCustomViewShowing() { return mCustomView != null; } protected void dismissIME() { if (mInputManager.isActive()) { mInputManager.hideSoftInputFromWindow(mContentView.getWindowToken(), 0); } } public void onPause() { if (isCustomViewShowing()) { onHideCustomView(); } cancelStopToast(); mActivityPaused = true; } public void onResume() { mActivityPaused = false; // check if we exited without setting active tab // b: 5188145 final Tab ct = mTabControl.getCurrentTab(); if (ct != null) { setActiveTab(ct); } } protected boolean isActivityPaused() { return mActivityPaused; } public void onConfigurationChanged(Configuration config) { } public Activity getActivity() { return mActivity; } Tab getActiveTab() { return mActiveTab; } @Override public void updateTabs(List<Tab> tabs) { } @Override public void removeTab(Tab tab) { if (mActiveTab == tab) { removeTabFromContentView(tab); mActiveTab = null; } } @Override public void detachTab(Tab tab) { removeTabFromContentView(tab); } @Override public void attachTab(Tab tab) { attachTabToContentView(tab); } protected void attachTabToContentView(Tab tab) { if ((tab == null) || (tab.getWebView() == null)) { return; } View container = tab.getViewContainer(); ContentView mainView = tab.getWebView(); ContentViewRenderView renderView = tab.getRenderView(); // Attach the WebView to the container and then attach the // container to the content view. FrameLayout wrapper = (FrameLayout) container.findViewById(R.id.webview_wrapper); ViewGroup parent = (ViewGroup) renderView.getParent(); if (parent != wrapper) { if (parent != null) { parent.removeView(renderView); } wrapper.addView(renderView); } parent = (ViewGroup) mainView.getParent(); if (parent != wrapper) { if (parent != null) { parent.removeView(mainView); } wrapper.addView(mainView); } //2. attach the tab to content view. parent = (ViewGroup) container.getParent(); if (parent != mContentView) { if (parent != null) { parent.removeView(container); } mContentView.addView(container, COVER_SCREEN_PARAMS); } mUiController.attachSubWindow(tab); } private void removeTabFromContentView(Tab tab) { hideTitleBar(); // Remove the container that contains the main WebView. ContentView mainView = tab.getWebView(); View container = tab.getViewContainer(); if (mainView == null) { return; } // Remove the container from the content and then remove the // WebView from the container. This will trigger a focus change // needed by WebView. FrameLayout wrapper = (FrameLayout) container.findViewById(R.id.webview_wrapper); wrapper.removeView(mainView); mContentView.removeView(container); mUiController.endActionMode(); // mUiController.removeSubWindow(tab); /* ww ErrorConsoleView errorConsole = tab.getErrorConsole(false); if (errorConsole != null) { mErrorConsoleContainer.removeView(errorConsole); }*/ } @Override public void onSetWebView(Tab tab, ContentView webView) { View container = tab.getViewContainer(); if (container == null) { // The tab consists of a container view, which contains the main // WebView, as well as any other UI elements associated with the tab. container = mActivity.getLayoutInflater().inflate(R.layout.tab, mContentView, false); tab.setViewContainer(container); } if (tab.getWebView() != webView) { // Just remove the old one. FrameLayout wrapper = (FrameLayout) container.findViewById(R.id.webview_wrapper); wrapper.removeView(tab.getWebView()); } } /** * create a sub window container and webview for the tab * Note: this methods operates through side-effects for now * it sets both the subView and subViewContainer for the given tab * @param tab tab to create the sub window for * @param subView webview to be set as a subwindow for the tab */ @Override public void createSubWindow(Tab tab, ContentView subView) { /* View subViewContainer = mActivity.getLayoutInflater().inflate( R.layout.browser_subwindow, null); ViewGroup inner = (ViewGroup) subViewContainer .findViewById(R.id.inner_container); inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); final ImageButton cancel = (ImageButton) subViewContainer .findViewById(R.id.subwindow_close); final ContentView cancelSubView = subView; cancel.setOnClickListener(new OnClickListener() { public void onClick(View v) { WebViewClassic.fromWebView(cancelSubView).getWebChromeClient().onCloseWindow( cancelSubView); } }); tab.setSubWebView(subView); tab.setSubViewContainer(subViewContainer);*/ } /** * Remove the sub window from the content view. */ @Override public void removeSubWindow(View subviewContainer) { mContentView.removeView(subviewContainer); mUiController.endActionMode(); } /** * Attach the sub window to the content view. */ @Override public void attachSubWindow(View container) { if (container.getParent() != null) { // already attached, remove first ((ViewGroup) container.getParent()).removeView(container); } mContentView.addView(container, COVER_SCREEN_PARAMS); } @Override public boolean isWebShowing() { return mCustomView == null; } @Override public boolean onBackKey() { if (mCustomView != null) { mUiController.hideCustomView(); return true; } return false; } @Override public boolean onMenuKey() { return false; } public void setFullscreen(boolean enabled) { Window win = mActivity.getWindow(); WindowManager.LayoutParams winParams = win.getAttributes(); final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN; if (enabled) { winParams.flags |= bits; } else { winParams.flags &= ~bits; if (mCustomView != null) { mCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } else { mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } } win.setAttributes(winParams); } public Drawable getFaviconDrawable(Bitmap icon) { Drawable[] array = new Drawable[3]; array[0] = new PaintDrawable(Color.BLACK); PaintDrawable p = new PaintDrawable(Color.WHITE); array[1] = p; if (icon == null) { array[2] = mGenericFavicon; } else { array[2] = new BitmapDrawable(icon); } LayerDrawable d = new LayerDrawable(array); d.setLayerInset(1, 1, 1, 1, 1); d.setLayerInset(2, 2, 2, 2, 2); return d; } public boolean isLoading() { return mActiveTab != null ? mActiveTab.inPageLoad() : false; } protected ContentView getContentView() { if (mActiveTab != null) { return mActiveTab.getWebView(); } else { return null; } } /** * Suggest to the UI that the title bar can be hidden. The UI will then * decide whether or not to hide based off a number of factors, such * as if the user is editing the URL bar or if the page is loading */ public void suggestHideTitleBar() { if (!isLoading() && !isEditingUrl() && !mTitleBar.wantsToBeVisible()) { hideTitleBar(); } } protected final void showTitleBarForDuration() { showTitleBarForDuration(HIDE_TITLEBAR_DELAY); } protected final void showTitleBarForDuration(long duration) { showTitleBar(); Message msg = Message.obtain(mHandler, MSG_HIDE_TITLEBAR); mHandler.sendMessageDelayed(msg, duration); } protected Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == MSG_HIDE_TITLEBAR) { suggestHideTitleBar(); } BaseUi.this.handleMessage(msg); } }; /** * Update the lock icon to correspond to our latest state. */ protected void updateLockIconToLatest(Tab t) { if (t != null && t.inForeground()) { //ww updateLockIconImage(t.getSecurityState()); } } /** * Updates the lock-icon image in the title-bar. */ private void updateLockIconImage(SecurityState securityState) { Drawable d = null; if (securityState == SecurityState.SECURITY_STATE_SECURE) { d = mLockIconSecure; } else if (securityState == SecurityState.SECURITY_STATE_MIXED || securityState == SecurityState.SECURITY_STATE_BAD_CERTIFICATE) { // TODO: It would be good to have different icons for insecure vs mixed content. // See http://b/5403800 d = mLockIconMixed; } mNavigationBar.setLock(d); } protected void handleMessage(Message msg) {} @Override public void showWeb(boolean animate) { mUiController.hideCustomView(); } static class FullscreenHolder extends FrameLayout { public FullscreenHolder(Context ctx) { super(ctx); setBackgroundColor(ctx.getResources().getColor(R.color.black)); } @Override public boolean onTouchEvent(MotionEvent evt) { return true; } } public void addFixedTitleBar(View view) { mFixedTitlebarContainer.addView(view); } public void setContentViewMarginTop(int margin) { LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContentView.getLayoutParams(); if (params.topMargin != margin) { params.topMargin = margin; mContentView.setLayoutParams(params); } } @Override public void onPageStopped(Tab tab) { cancelStopToast(); if (tab.inForeground()) { mStopToast = Toast .makeText(mActivity, R.string.stopping, Toast.LENGTH_SHORT); mStopToast.show(); } } @Override public boolean needsRestoreAllTabs() { return true; } @Override public void addTab(Tab tab) { } @Override public void setActiveTab(final Tab tab) { if (tab == null) return; // block unnecessary focus change animations during tab switch mBlockFocusAnimations = true; mHandler.removeMessages(MSG_HIDE_TITLEBAR); if ((tab != mActiveTab) && (mActiveTab != null)) { removeTabFromContentView(mActiveTab); ContentView web = mActiveTab.getWebView(); if (web != null) { web.setOnTouchListener(null); } } mActiveTab = tab; ContentView web = (ContentView) mActiveTab.getWebView(); // ww updateUrlBarAutoShowManagerTarget(); attachTabToContentView(tab); if (web != null) { // Request focus on the top window. if (mUseQuickControls) { //ww mPieControl.forceToTop(mContentView); // ww web.setTitleBar(null); mTitleBar.hide(); } else { // ww web.setTitleBar(mTitleBar); mTitleBar.onScrollChanged(); } } mTitleBar.bringToFront(); tab.getTopWindow().requestFocus(); //ww setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole()); onTabDataChanged(tab); onProgressChanged(tab); mNavigationBar.setIncognitoMode(tab.isPrivateBrowsingEnabled()); // updateAutoLogin(tab, false); mBlockFocusAnimations = false; } @Override public boolean onPrepareOptionsMenu(Menu menu) { return true; } @Override public void updateMenuState(Tab tab, Menu menu) { } @Override public void onOptionsMenuOpened() { } @Override public void onExtendedMenuOpened() { } @Override public boolean onOptionsItemSelected(MenuItem item) { return false; } @Override public void onOptionsMenuClosed(boolean inLoad) { } @Override public void onExtendedMenuClosed(boolean inLoad) { } @Override public void onContextMenuCreated(Menu menu) { } @Override public void onContextMenuClosed(Menu menu, boolean inLoad) { } // Tab callbacks @Override public void onTabDataChanged(Tab tab) { setUrlTitle(tab); setFavicon(tab); updateLockIconToLatest(tab); updateNavigationState(tab); mTitleBar.onTabDataChanged(tab); mNavigationBar.onTabDataChanged(tab); onProgressChanged(tab); } @Override public void onProgressChanged(Tab tab) { int progress = tab.getLoadProgress(); if (tab.inForeground()) { mTitleBar.setProgress(progress); } } @Override public void showMaxTabsWarning() { Toast warning = Toast.makeText(mActivity, mActivity.getString(R.string.max_tabs_warning), Toast.LENGTH_SHORT); warning.show(); } @Override public void bookmarkedStatusHasChanged(Tab tab) { if (tab.inForeground()) { boolean isBookmark = tab.isBookmarkedSite(); mNavigationBar.setCurrentUrlIsBookmark(isBookmark); } } public static final boolean SHOW_ORIGINAL = false; @Override public void showComboView(ComboViews startingView, Bundle extras) { if (SHOW_ORIGINAL) { Intent intent = new Intent(mActivity, ComboViewActivity.class); intent.putExtra(ComboViewActivity.EXTRA_INITIAL_VIEW, startingView.name()); intent.putExtra(ComboViewActivity.EXTRA_COMBO_ARGS, extras); Tab t = getActiveTab(); if (t != null) { intent.putExtra(ComboViewActivity.EXTRA_CURRENT_URL, t.getUrl()); } mActivity.startActivityForResult(intent, Controller.COMBO_VIEW); } else { Intent intent = new Intent(mActivity, ComboViewActivityMine.class); intent.putExtra(ComboViewActivityMine.EXTRA_INITIAL_VIEW, startingView.name()); intent.putExtra(ComboViewActivityMine.EXTRA_COMBO_ARGS, extras); Tab t = getActiveTab(); if (t != null) { intent.putExtra(ComboViewActivityMine.EXTRA_CURRENT_URL, t.getUrl()); } mActivity.startActivityForResult(intent, Controller.COMBO_VIEW); } } @Override public void setShouldShowErrorConsole(Tab tab, boolean flag) { if (tab == null) return; ErrorConsoleView errorConsole = tab.getErrorConsole(true); if (flag) { // Setting the show state of the console will cause it's the layout // to be inflated. if (errorConsole.numberOfErrors() > 0) { errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED); } else { errorConsole.showConsole(ErrorConsoleView.SHOW_NONE); } if (errorConsole.getParent() != null) { mErrorConsoleContainer.removeView(errorConsole); } // Now we can add it to the main view. mErrorConsoleContainer.addView(errorConsole, new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } else { mErrorConsoleContainer.removeView(errorConsole); } } }