Merge "Import translations. DO NOT MERGE" into jb-dev
diff --git a/res/layout-sw600dp/title_bar_nav.xml b/res/layout-sw600dp/title_bar_nav.xml
index 300b740..651474a 100644
--- a/res/layout-sw600dp/title_bar_nav.xml
+++ b/res/layout-sw600dp/title_bar_nav.xml
@@ -28,7 +28,6 @@
             android:src="@drawable/ic_back_holo_dark"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:paddingLeft="16dip"
             android:contentDescription="@string/accessibility_button_back"
             style="@style/HoloButton" />
         <ImageButton
@@ -52,22 +51,20 @@
         android:layout_width="0dip"
         android:layout_height="match_parent"
         android:layout_weight="1.0"
-        android:layout_marginLeft="8dip"
-        android:layout_marginRight="8dip"
         android:orientation="horizontal"
         android:background="@drawable/url_background">
         <ImageView
             android:id="@+id/url_icon"
-            android:layout_width="48dip"
+            android:layout_width="32dip"
             android:layout_height="20dip"
-            android:paddingLeft="14dip"
-            android:paddingRight="14dip"
             android:src="@drawable/ic_web_holo_dark"
             android:layout_gravity="center" />
         <ImageView
             android:id="@+id/lock"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="0dip"
             style="@style/HoloIcon"
             android:visibility="gone" />
         <com.android.browser.UrlInputView
@@ -75,7 +72,7 @@
             android:layout_width="0dip"
             android:layout_weight="1.0"
             android:layout_height="match_parent"
-            android:paddingLeft="0dip"
+            android:paddingLeft="4dip"
             android:paddingRight="0dip"
             android:background="@null"
             android:textAppearance="?android:attr/textAppearanceMedium"
@@ -115,7 +112,6 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:scaleType="center"
-        android:paddingRight="16dip"
         style="@style/HoloButton"
         android:contentDescription="@string/accessibility_button_bookmarks"
         android:src="@drawable/ic_bookmarks_history_holo_dark" />
diff --git a/src/com/android/browser/ActivityController.java b/src/com/android/browser/ActivityController.java
new file mode 100644
index 0000000..ac248b8
--- /dev/null
+++ b/src/com/android/browser/ActivityController.java
@@ -0,0 +1,74 @@
+package com.android.browser;
+
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.view.ActionMode;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+
+
+public interface ActivityController {
+
+    void start(Intent intent);
+
+    void onSaveInstanceState(Bundle outState);
+
+    void handleNewIntent(Intent intent);
+
+    void onResume();
+
+    boolean onMenuOpened(int featureId, Menu menu);
+
+    void onOptionsMenuClosed(Menu menu);
+
+    void onContextMenuClosed(Menu menu);
+
+    void onPause();
+
+    void onDestroy();
+
+    void onConfgurationChanged(Configuration newConfig);
+
+    void onLowMemory();
+
+    boolean onCreateOptionsMenu(Menu menu);
+
+    boolean onPrepareOptionsMenu(Menu menu);
+
+    boolean onOptionsItemSelected(MenuItem item);
+
+    void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo);
+
+    boolean onContextItemSelected(MenuItem item);
+
+    boolean onKeyDown(int keyCode, KeyEvent event);
+
+    boolean onKeyLongPress(int keyCode, KeyEvent event);
+
+    boolean onKeyUp(int keyCode, KeyEvent event);
+
+    void onActionModeStarted(ActionMode mode);
+
+    void onActionModeFinished(ActionMode mode);
+
+    void onActivityResult(int requestCode, int resultCode, Intent intent);
+
+    boolean onSearchRequested();
+
+    boolean dispatchKeyEvent(KeyEvent event);
+
+    boolean dispatchKeyShortcutEvent(KeyEvent event);
+
+    boolean dispatchTouchEvent(MotionEvent ev);
+
+    boolean dispatchTrackballEvent(MotionEvent ev);
+
+    boolean dispatchGenericMotionEvent(MotionEvent ev);
+
+}
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index e3f5986..cfe9a53 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -113,6 +113,7 @@
     protected TitleBar mTitleBar;
     private NavigationBarBase mNavigationBar;
     protected PieControl mPieControl;
+    private boolean mBlockFocusAnimations;
 
     public BaseUi(Activity browser, UiController controller) {
         mActivity = browser;
@@ -264,6 +265,8 @@
     @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);
@@ -294,6 +297,7 @@
         onProgressChanged(tab);
         mNavigationBar.setIncognitoMode(tab.isPrivateBrowsingEnabled());
         updateAutoLogin(tab, false);
+        mBlockFocusAnimations = false;
     }
 
     protected void updateUrlBarAutoShowManagerTarget() {
@@ -860,4 +864,10 @@
             mContentView.setLayoutParams(params);
         }
     }
+
+    @Override
+    public boolean blockFocusAnimations() {
+        return mBlockFocusAnimations;
+    }
+
 }
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index b7217e9..8511778 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -34,6 +34,7 @@
 import android.view.View;
 import android.view.Window;
 
+import com.android.browser.stub.NullController;
 import com.google.common.annotations.VisibleForTesting;
 
 public class BrowserActivity extends Activity {
@@ -47,8 +48,7 @@
 
     private final static boolean LOGV_ENABLED = Browser.LOGV_ENABLED;
 
-    private Controller mController;
-    private UI mUi;
+    private ActivityController mController = NullController.INSTANCE;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -69,14 +69,7 @@
             finish();
             return;
         }
-        mController = new Controller(this);
-        boolean xlarge = isTablet(this);
-        if (xlarge) {
-            mUi = new XLargeUi(this, mController);
-        } else {
-            mUi = new PhoneUi(this, mController);
-        }
-        mController.setUi(mUi);
+        mController = createController();
 
         Intent intent = (icicle == null) ? getIntent() : null;
         mController.start(intent);
@@ -86,9 +79,22 @@
         return context.getResources().getBoolean(R.bool.isTablet);
     }
 
+    private Controller createController() {
+        Controller controller = new Controller(this);
+        boolean xlarge = isTablet(this);
+        UI ui = null;
+        if (xlarge) {
+            ui = new XLargeUi(this, controller);
+        } else {
+            ui = new PhoneUi(this, controller);
+        }
+        controller.setUi(ui);
+        return controller;
+    }
+
     @VisibleForTesting
     Controller getController() {
-        return mController;
+        return (Controller) mController;
     }
 
     @Override
@@ -132,9 +138,7 @@
         if (LOGV_ENABLED) {
             Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
         }
-        if (mController != null) {
-            mController.onResume();
-        }
+        mController.onResume();
     }
 
     @Override
@@ -166,16 +170,12 @@
         if (LOGV_ENABLED) {
             Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
         }
-        if (mController != null) {
-            mController.onSaveInstanceState(outState);
-        }
+        mController.onSaveInstanceState(outState);
     }
 
     @Override
     protected void onPause() {
-        if (mController != null) {
-            mController.onPause();
-        }
+        mController.onPause();
         super.onPause();
     }
 
@@ -185,19 +185,14 @@
             Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
         }
         super.onDestroy();
-        if (mController != null) {
-            mController.onDestroy();
-        }
-        mUi = null;
-        mController = null;
+        mController.onDestroy();
+        mController = NullController.INSTANCE;
     }
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        if (mController != null) {
-            mController.onConfgurationChanged(newConfig);
-        }
+        mController.onConfgurationChanged(newConfig);
     }
 
     @Override
@@ -209,7 +204,7 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
-        return (mController != null) && mController.onCreateOptionsMenu(menu);
+        return mController.onCreateOptionsMenu(menu);
     }
 
     @Override
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index fb535ba..8a00ba3 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -20,10 +20,7 @@
 import android.app.Dialog;
 import android.app.DownloadManager;
 import android.app.ProgressDialog;
-import android.app.SearchManager;
 import android.content.ClipboardManager;
-import android.content.ContentProvider;
-import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -84,11 +81,8 @@
 
 import com.android.browser.IntentHandler.UrlData;
 import com.android.browser.UI.ComboViews;
-import com.android.browser.provider.BrowserProvider;
 import com.android.browser.provider.BrowserProvider2.Thumbnails;
 import com.android.browser.provider.SnapshotProvider.Snapshots;
-import com.android.browser.search.SearchEngine;
-import com.android.common.Search;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -108,7 +102,7 @@
  * Controller for browser
  */
 public class Controller
-        implements WebViewController, UiController {
+        implements WebViewController, UiController, ActivityController {
 
     private static final String LOGTAG = "Controller";
     private static final String SEND_APP_ID_EXTRA =
@@ -258,7 +252,8 @@
         openIconDatabase();
     }
 
-    void start(final Intent intent) {
+    @Override
+    public void start(final Intent intent) {
         WebViewClassic.setShouldMonitorWebCoreThread();
         // mCrashRecoverHandler has any previously saved state.
         mCrashRecoveryHandler.startRecovery(intent);
@@ -607,7 +602,8 @@
 
     // lifecycle
 
-    protected void onConfgurationChanged(Configuration config) {
+    @Override
+    public void onConfgurationChanged(Configuration config) {
         mConfigChanged = true;
         // update the menu in case of a locale change
         mActivity.invalidateOptionsMenu();
@@ -625,7 +621,8 @@
         mIntentHandler.onNewIntent(intent);
     }
 
-    protected void onPause() {
+    @Override
+    public void onPause() {
         if (mUi.isCustomViewShowing()) {
             hideCustomView();
         }
@@ -659,7 +656,8 @@
         }
     }
 
-    void onSaveInstanceState(Bundle outState) {
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
         // Save all the tabs
         Bundle saveState = createSaveState();
 
@@ -683,7 +681,8 @@
         return saveState;
     }
 
-    void onResume() {
+    @Override
+    public void onResume() {
         if (!mActivityPaused) {
             Log.e(LOGTAG, "BrowserActivity is already resumed.");
             return;
@@ -739,7 +738,8 @@
         return false;
     }
 
-    void onDestroy() {
+    @Override
+    public void onDestroy() {
         if (mUploadHandler != null && !mUploadHandler.handled()) {
             mUploadHandler.onResult(Activity.RESULT_CANCELED, null);
             mUploadHandler = null;
@@ -765,7 +765,8 @@
         return mActivityPaused;
     }
 
-    protected void onLowMemory() {
+    @Override
+    public void onLowMemory() {
         mTabControl.freeMemory();
     }
 
@@ -1103,11 +1104,13 @@
     }
 
     // callback from phone title bar
+    @Override
     public void editUrl() {
         if (mOptionsMenuOpen) mActivity.closeOptionsMenu();
         mUi.editUrl(false, true);
     }
 
+    @Override
     public void showCustomView(Tab tab, View view, int requestedOrientation,
             WebChromeClient.CustomViewCallback callback) {
         if (tab.inForeground()) {
@@ -1135,7 +1138,8 @@
         }
     }
 
-    protected void onActivityResult(int requestCode, int resultCode,
+    @Override
+    public void onActivityResult(int requestCode, int resultCode,
             Intent intent) {
         if (getCurrentTopWebView() == null) return;
         switch (requestCode) {
@@ -1238,7 +1242,8 @@
     // menu handling and state
     // TODO: maybe put into separate handler
 
-    protected boolean onCreateOptionsMenu(Menu menu) {
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
         if (mMenuState == EMPTY_MENU) {
             return false;
         }
@@ -1247,7 +1252,8 @@
         return true;
     }
 
-    protected void onCreateContextMenu(ContextMenu menu, View v,
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
             ContextMenuInfo menuInfo) {
         if (v instanceof TitleBar) {
             return;
@@ -1445,7 +1451,8 @@
         }
     }
 
-    boolean onPrepareOptionsMenu(Menu menu) {
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
         updateInLoadMenuItems(menu, getCurrentTab());
         // hold on to the menu reference here; it is used by the page callbacks
         // to update the menu based on loading state
@@ -1529,6 +1536,7 @@
         mUi.updateMenuState(tab, menu);
     }
 
+    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if (null == getCurrentTopWebView()) {
             return false;
@@ -1784,6 +1792,7 @@
         mPageDialogsHandler.showPageInfo(mTabControl.getCurrentTab(), false, null);
     }
 
+    @Override
     public boolean onContextItemSelected(MenuItem item) {
         // Let the History and Bookmark fragments handle menus they created.
         if (item.getGroupId() == R.id.CONTEXT_MENU) {
@@ -1831,6 +1840,7 @@
         mActivity.openOptionsMenu();
     }
 
+    @Override
     public boolean onMenuOpened(int featureId, Menu menu) {
         if (mOptionsMenuOpen) {
             if (mConfigChanged) {
@@ -1859,11 +1869,13 @@
         return true;
     }
 
+    @Override
     public void onOptionsMenuClosed(Menu menu) {
         mOptionsMenuOpen = false;
         mUi.onOptionsMenuClosed(isInLoad());
     }
 
+    @Override
     public void onContextMenuClosed(Menu menu) {
         mUi.onContextMenuClosed(menu, isInLoad());
     }
@@ -1899,7 +1911,8 @@
 
     // action mode
 
-    void onActionModeStarted(ActionMode mode) {
+    @Override
+    public void onActionModeStarted(ActionMode mode) {
         mUi.onActionModeStarted(mode);
         mActionMode = mode;
     }
@@ -1926,6 +1939,7 @@
      * Called by find and select when they are finished.  Replace title bars
      * as necessary.
      */
+    @Override
     public void onActionModeFinished(ActionMode mode) {
         if (!isInCustomActionMode()) return;
         mUi.onActionModeFinished(isInLoad());
@@ -1980,6 +1994,7 @@
     }
 
     // file chooser
+    @Override
     public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
         mUploadHandler = new UploadHandler(this);
         mUploadHandler.openFileChooser(uploadMsg, acceptType, capture);
@@ -2114,6 +2129,7 @@
     private class Copy implements OnMenuItemClickListener {
         private CharSequence mText;
 
+        @Override
         public boolean onMenuItemClick(MenuItem item) {
             copy(mText);
             return true;
@@ -2131,6 +2147,7 @@
         private static final String FALLBACK_EXTENSION = "dat";
         private static final String IMAGE_BASE_FORMAT = "yyyy-MM-dd-HH-mm-ss-";
 
+        @Override
         public boolean onMenuItemClick(MenuItem item) {
             if (DataUri.isDataUri(mText)) {
                 saveDataUri();
@@ -2163,7 +2180,7 @@
                  manager.addCompletedDownload(target.getName(),
                         mActivity.getTitle().toString(), false,
                         uri.getMimeType(), target.getAbsolutePath(),
-                        (long)uri.getData().length, true);
+                        uri.getData().length, true);
             } catch (IOException e) {
                 Log.e(LOGTAG, "Could not save data URL");
             } finally {
@@ -2201,6 +2218,7 @@
     private static class SelectText implements OnMenuItemClickListener {
         private WebViewClassic mWebView;
 
+        @Override
         public boolean onMenuItemClick(MenuItem item) {
             if (mWebView != null) {
                 return mWebView.selectText();
@@ -2274,6 +2292,7 @@
 
     // Remove the sub window if it exists. Also called by TabControl when the
     // user clicks the 'X' to dismiss a sub window.
+    @Override
     public void dismissSubWindow(Tab tab) {
         removeSubWindow(tab);
         // dismiss the subwindow. This will destroy the WebView.
@@ -2611,7 +2630,8 @@
      * @param event
      * @return true if handled, false to pass to super
      */
-    boolean onKeyDown(int keyCode, KeyEvent event) {
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
         boolean noModifiers = event.hasNoModifiers();
         // Even if MENU is already held down, we need to call to super to open
         // the IME on long press.
@@ -2722,7 +2742,8 @@
          return mUi.dispatchKey(keyCode, event);
     }
 
-    boolean onKeyLongPress(int keyCode, KeyEvent event) {
+    @Override
+    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
         switch(keyCode) {
         case KeyEvent.KEYCODE_BACK:
             if (mUi.isWebShowing()) {
@@ -2734,7 +2755,8 @@
         return false;
     }
 
-    boolean onKeyUp(int keyCode, KeyEvent event) {
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
         if (isMenuOrCtrlKey(keyCode)) {
             mMenuIsDown = false;
             if (KeyEvent.KEYCODE_MENU == keyCode
@@ -2758,6 +2780,7 @@
         return mMenuIsDown;
     }
 
+    @Override
     public void setupAutoFill(Message message) {
         // Open the settings activity at the AutoFill profile fragment so that
         // the user can create a new profile. When they return, we will dispatch
@@ -2769,6 +2792,7 @@
         mActivity.startActivityForResult(intent, AUTOFILL_SETUP);
     }
 
+    @Override
     public boolean onSearchRequested() {
         mUi.editUrl(false, true);
         return true;
@@ -2784,22 +2808,27 @@
         mBlockEvents = block;
     }
 
+    @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         return mBlockEvents;
     }
 
+    @Override
     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
         return mBlockEvents;
     }
 
+    @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         return mBlockEvents;
     }
 
+    @Override
     public boolean dispatchTrackballEvent(MotionEvent ev) {
         return mBlockEvents;
     }
 
+    @Override
     public boolean dispatchGenericMotionEvent(MotionEvent ev) {
         return mBlockEvents;
     }
diff --git a/src/com/android/browser/NavigationBarTablet.java b/src/com/android/browser/NavigationBarTablet.java
index b9c86e3..426174b 100644
--- a/src/com/android/browser/NavigationBarTablet.java
+++ b/src/com/android/browser/NavigationBarTablet.java
@@ -259,34 +259,49 @@
         mStopButton.setContentDescription(mRefreshDescription);
     }
 
+    private AnimatorSet mAnimation;
+
     private void hideNavButtons() {
+        if (mBaseUi.blockFocusAnimations()) {
+            mNavButtons.setVisibility(View.GONE);
+            return;
+        }
         int awidth = mNavButtons.getMeasuredWidth();
         Animator anim1 = ObjectAnimator.ofFloat(mNavButtons, View.TRANSLATION_X, 0, - awidth);
         Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", mUrlContainer.getLeft(),
                 mUrlContainer.getPaddingLeft());
         Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, View.ALPHA, 1f, 0f);
-        AnimatorSet combo = new AnimatorSet();
-        combo.playTogether(anim1, anim2, anim3);
-        combo.addListener(new AnimatorListenerAdapter() {
+        mAnimation = new AnimatorSet();
+        mAnimation.playTogether(anim1, anim2, anim3);
+        mAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 mNavButtons.setVisibility(View.GONE);
+                mAnimation = null;
             }
         });
-        combo.setDuration(150);
-        combo.start();
+        mAnimation.setDuration(150);
+        mAnimation.start();
     }
 
     private void showNavButtons() {
-        int awidth = mNavButtons.getMeasuredWidth();
-        Animator anim1 = ObjectAnimator.ofFloat(mNavButtons, View.TRANSLATION_X, -awidth, 0);
-        Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", 0, awidth);
-        Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, View.ALPHA, 0f, 1f);
-        AnimatorSet combo = new AnimatorSet();
-        combo.playTogether(anim1, anim2, anim3);
+        if (mAnimation != null) {
+            mAnimation.cancel();
+        }
         mNavButtons.setVisibility(View.VISIBLE);
-        combo.setDuration(150);
-        combo.start();
+        if (!mBaseUi.blockFocusAnimations()) {
+            int awidth = mNavButtons.getMeasuredWidth();
+            Animator anim1 = ObjectAnimator.ofFloat(mNavButtons,
+                    View.TRANSLATION_X, -awidth, 0);
+            Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", 0,
+                    awidth);
+            Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, View.ALPHA,
+                    0f, 1f);
+            AnimatorSet combo = new AnimatorSet();
+            combo.playTogether(anim1, anim2, anim3);
+            combo.setDuration(150);
+            combo.start();
+        }
     }
 
     private void showHideStar(Tab tab) {
diff --git a/src/com/android/browser/TitleBar.java b/src/com/android/browser/TitleBar.java
index ffe5553..d3e8f7c 100644
--- a/src/com/android/browser/TitleBar.java
+++ b/src/com/android/browser/TitleBar.java
@@ -405,8 +405,10 @@
 
     @Override
     public View focusSearch(View focused, int dir) {
-        if (FOCUS_DOWN == dir && hasFocus()) {
-            return getCurrentWebView();
+        WebView web = getCurrentWebView();
+        if (FOCUS_DOWN == dir && hasFocus()
+                && web.hasFocusable() && web.getParent() != null) {
+            return web;
         }
         return super.focusSearch(focused, dir);
     }
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index aeab746..96f6640 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -146,4 +146,6 @@
 
     public boolean shouldCaptureThumbnails();
 
+    boolean blockFocusAnimations();
+
 }
diff --git a/src/com/android/browser/stub/NullController.java b/src/com/android/browser/stub/NullController.java
new file mode 100644
index 0000000..149fe4e
--- /dev/null
+++ b/src/com/android/browser/stub/NullController.java
@@ -0,0 +1,152 @@
+package com.android.browser.stub;
+
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.view.ActionMode;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+
+import com.android.browser.ActivityController;
+
+
+public class NullController implements ActivityController {
+
+    public static NullController INSTANCE = new NullController();
+
+    private NullController() {}
+
+    @Override
+    public void start(Intent intent) {
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+    }
+
+    @Override
+    public void handleNewIntent(Intent intent) {
+    }
+
+    @Override
+    public void onResume() {
+    }
+
+    @Override
+    public boolean onMenuOpened(int featureId, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public void onOptionsMenuClosed(Menu menu) {
+    }
+
+    @Override
+    public void onContextMenuClosed(Menu menu) {
+    }
+
+    @Override
+    public void onPause() {
+    }
+
+    @Override
+    public void onDestroy() {
+    }
+
+    @Override
+    public void onConfgurationChanged(Configuration newConfig) {
+    }
+
+    @Override
+    public void onLowMemory() {
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        return false;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        return false;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public void onActionModeStarted(ActionMode mode) {
+    }
+
+    @Override
+    public void onActionModeFinished(ActionMode mode) {
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent ev) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+        return false;
+    }
+
+}