| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- | 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- |
| 2 * This Source Code Form is subject to the terms of the Mozilla Public | 2 * This Source Code Form is subject to the terms of the Mozilla Public |
| 3 * License, v. 2.0. If a copy of the MPL was not distributed with this | 3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 5 | 5 |
| 6 package org.mozilla.gecko; | 6 package org.mozilla.gecko; |
| 7 | 7 |
| 8 import java.io.File; | |
| 9 import java.io.FileNotFoundException; | |
| 10 import java.lang.Override; | |
| 11 import java.lang.reflect.Field; | |
| 12 import java.lang.reflect.Method; | |
| 13 import java.net.URLEncoder; | |
| 14 import java.util.EnumSet; | |
| 15 import java.util.HashSet; | |
| 16 import java.util.List; | |
| 17 import java.util.Locale; | |
| 18 import java.util.Vector; | |
| 19 | |
| 20 import android.support.v4.app.Fragment; | |
| 21 import org.json.JSONException; | |
| 22 import org.json.JSONObject; | |
| 23 | |
| 24 import org.mozilla.gecko.AppConstants.Versions; | 8 import org.mozilla.gecko.AppConstants.Versions; |
| 25 import org.mozilla.gecko.DynamicToolbar.PinReason; | 9 import org.mozilla.gecko.DynamicToolbar.PinReason; |
| 26 import org.mozilla.gecko.DynamicToolbar.VisibilityTransition; | 10 import org.mozilla.gecko.DynamicToolbar.VisibilityTransition; |
| 27 import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException; | 11 import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException; |
| 28 import org.mozilla.gecko.Tabs.TabEvents; | 12 import org.mozilla.gecko.Tabs.TabEvents; |
| 29 import org.mozilla.gecko.animation.PropertyAnimator; | 13 import org.mozilla.gecko.animation.PropertyAnimator; |
| 30 import org.mozilla.gecko.animation.TransitionsTracker; | 14 import org.mozilla.gecko.animation.TransitionsTracker; |
| 31 import org.mozilla.gecko.animation.ViewHelper; | 15 import org.mozilla.gecko.animation.ViewHelper; |
| 32 import org.mozilla.gecko.db.BrowserContract.Combined; | 16 import org.mozilla.gecko.db.BrowserContract.Combined; |
| 33 import org.mozilla.gecko.db.BrowserContract.SearchHistory; | |
| 34 import org.mozilla.gecko.db.BrowserDB; | 17 import org.mozilla.gecko.db.BrowserDB; |
| 35 import org.mozilla.gecko.db.SuggestedSites; | 18 import org.mozilla.gecko.db.SuggestedSites; |
| 36 import org.mozilla.gecko.distribution.Distribution; | 19 import org.mozilla.gecko.distribution.Distribution; |
| 37 import org.mozilla.gecko.favicons.Favicons; | 20 import org.mozilla.gecko.favicons.Favicons; |
| 38 import org.mozilla.gecko.favicons.LoadFaviconTask; | 21 import org.mozilla.gecko.favicons.LoadFaviconTask; |
| 39 import org.mozilla.gecko.favicons.OnFaviconLoadedListener; | 22 import org.mozilla.gecko.favicons.OnFaviconLoadedListener; |
| 40 import org.mozilla.gecko.favicons.decoders.IconDirectoryEntry; | 23 import org.mozilla.gecko.favicons.decoders.IconDirectoryEntry; |
| 24 import org.mozilla.gecko.firstrun.FirstrunPane; | |
| 41 import org.mozilla.gecko.fxa.FirefoxAccounts; | 25 import org.mozilla.gecko.fxa.FirefoxAccounts; |
| 42 import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity; | 26 import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity; |
| 43 import org.mozilla.gecko.gfx.BitmapUtils; | 27 import org.mozilla.gecko.gfx.BitmapUtils; |
| 44 import org.mozilla.gecko.gfx.ImmutableViewportMetrics; | 28 import org.mozilla.gecko.gfx.ImmutableViewportMetrics; |
| 45 import org.mozilla.gecko.gfx.LayerMarginsAnimator; | 29 import org.mozilla.gecko.gfx.LayerMarginsAnimator; |
| 46 import org.mozilla.gecko.gfx.LayerView; | 30 import org.mozilla.gecko.gfx.LayerView; |
| 47 import org.mozilla.gecko.health.BrowserHealthRecorder; | 31 import org.mozilla.gecko.health.BrowserHealthRecorder; |
| 48 import org.mozilla.gecko.health.BrowserHealthReporter; | 32 import org.mozilla.gecko.health.BrowserHealthReporter; |
| 49 import org.mozilla.gecko.health.HealthRecorder; | 33 import org.mozilla.gecko.health.HealthRecorder; |
| 50 import org.mozilla.gecko.health.SessionInformation; | 34 import org.mozilla.gecko.health.SessionInformation; |
| 51 import org.mozilla.gecko.home.BrowserSearch; | 35 import org.mozilla.gecko.home.BrowserSearch; |
| 52 import org.mozilla.gecko.home.HomeBanner; | 36 import org.mozilla.gecko.home.HomeBanner; |
| 53 import org.mozilla.gecko.home.HomePager; | 37 import org.mozilla.gecko.home.HomePager; |
| 54 import org.mozilla.gecko.home.HomePager.OnUrlOpenInBackgroundListener; | 38 import org.mozilla.gecko.home.HomePager.OnUrlOpenInBackgroundListener; |
| 55 import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; | 39 import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; |
| 56 import org.mozilla.gecko.home.HomePanelsManager; | 40 import org.mozilla.gecko.home.HomePanelsManager; |
| 57 import org.mozilla.gecko.home.TopSitesPanel; | |
| 58 import org.mozilla.gecko.home.SearchEngine; | 41 import org.mozilla.gecko.home.SearchEngine; |
| 59 import org.mozilla.gecko.menu.GeckoMenu; | 42 import org.mozilla.gecko.menu.GeckoMenu; |
| 60 import org.mozilla.gecko.menu.GeckoMenuItem; | 43 import org.mozilla.gecko.menu.GeckoMenuItem; |
| 61 import org.mozilla.gecko.mozglue.ContextUtils; | 44 import org.mozilla.gecko.mozglue.ContextUtils; |
| 45 import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent; | |
| 46 import org.mozilla.gecko.mozglue.RobocopTarget; | |
| 47 import org.mozilla.gecko.overlays.ui.ShareDialog; | |
| 62 import org.mozilla.gecko.preferences.ClearOnShutdownPref; | 48 import org.mozilla.gecko.preferences.ClearOnShutdownPref; |
| 63 import org.mozilla.gecko.preferences.GeckoPreferences; | 49 import org.mozilla.gecko.preferences.GeckoPreferences; |
| 64 import org.mozilla.gecko.prompts.Prompt; | 50 import org.mozilla.gecko.prompts.Prompt; |
| 65 import org.mozilla.gecko.prompts.PromptListItem; | 51 import org.mozilla.gecko.prompts.PromptListItem; |
| 66 import org.mozilla.gecko.sync.setup.SyncAccounts; | 52 import org.mozilla.gecko.sync.setup.SyncAccounts; |
| 53 import org.mozilla.gecko.tabqueue.TabQueueHelper; | |
| 67 import org.mozilla.gecko.tabs.TabHistoryController; | 54 import org.mozilla.gecko.tabs.TabHistoryController; |
| 55 import org.mozilla.gecko.tabs.TabHistoryController.OnShowTabHistory; | |
| 68 import org.mozilla.gecko.tabs.TabHistoryFragment; | 56 import org.mozilla.gecko.tabs.TabHistoryFragment; |
| 69 import org.mozilla.gecko.tabs.TabHistoryPage; | 57 import org.mozilla.gecko.tabs.TabHistoryPage; |
| 70 import org.mozilla.gecko.tabs.TabsPanel; | 58 import org.mozilla.gecko.tabs.TabsPanel; |
| 71 import org.mozilla.gecko.tabs.TabHistoryController.OnShowTabHistory; | |
| 72 import org.mozilla.gecko.tiles.TilesRecorder; | |
| 73 import org.mozilla.gecko.toolbar.AutocompleteHandler; | 59 import org.mozilla.gecko.toolbar.AutocompleteHandler; |
| 74 import org.mozilla.gecko.toolbar.BrowserToolbar; | 60 import org.mozilla.gecko.toolbar.BrowserToolbar; |
| 75 import org.mozilla.gecko.toolbar.BrowserToolbar.TabEditingState; | 61 import org.mozilla.gecko.toolbar.BrowserToolbar.TabEditingState; |
| 76 import org.mozilla.gecko.toolbar.ToolbarProgressView; | 62 import org.mozilla.gecko.toolbar.ToolbarProgressView; |
| 77 import org.mozilla.gecko.util.ActivityUtils; | 63 import org.mozilla.gecko.util.ActivityUtils; |
| 78 import org.mozilla.gecko.util.Clipboard; | 64 import org.mozilla.gecko.util.Clipboard; |
| 79 import org.mozilla.gecko.util.EventCallback; | 65 import org.mozilla.gecko.util.EventCallback; |
| 80 import org.mozilla.gecko.util.GamepadUtils; | 66 import org.mozilla.gecko.util.GamepadUtils; |
| 81 import org.mozilla.gecko.util.GeckoEventListener; | 67 import org.mozilla.gecko.util.GeckoEventListener; |
| 82 import org.mozilla.gecko.util.HardwareUtils; | 68 import org.mozilla.gecko.util.HardwareUtils; |
| 83 import org.mozilla.gecko.util.MenuUtils; | 69 import org.mozilla.gecko.util.MenuUtils; |
| 84 import org.mozilla.gecko.util.NativeEventListener; | 70 import org.mozilla.gecko.util.NativeEventListener; |
| 85 import org.mozilla.gecko.util.NativeJSObject; | 71 import org.mozilla.gecko.util.NativeJSObject; |
| 86 import org.mozilla.gecko.util.PrefUtils; | 72 import org.mozilla.gecko.util.PrefUtils; |
| 87 import org.mozilla.gecko.util.StringUtils; | 73 import org.mozilla.gecko.util.StringUtils; |
| 88 import org.mozilla.gecko.util.ThreadUtils; | 74 import org.mozilla.gecko.util.ThreadUtils; |
| 89 import org.mozilla.gecko.util.UIAsyncTask; | 75 import org.mozilla.gecko.util.UIAsyncTask; |
| 90 import org.mozilla.gecko.widget.ButtonToast; | 76 import org.mozilla.gecko.widget.ButtonToast; |
| 91 import org.mozilla.gecko.widget.ButtonToast.ToastListener; | 77 import org.mozilla.gecko.widget.ButtonToast.ToastListener; |
| 92 import org.mozilla.gecko.widget.GeckoActionProvider; | 78 import org.mozilla.gecko.widget.GeckoActionProvider; |
| 93 | 79 |
| 94 import android.app.Activity; | 80 import android.app.Activity; |
| 95 import android.app.AlertDialog; | 81 import android.app.AlertDialog; |
| 96 import android.content.BroadcastReceiver; | 82 import android.content.ContentResolver; |
| 97 import android.content.ContentValues; | |
| 98 import android.content.Context; | 83 import android.content.Context; |
| 99 import android.content.DialogInterface; | 84 import android.content.DialogInterface; |
| 100 import android.content.Intent; | 85 import android.content.Intent; |
| 101 import android.content.SharedPreferences; | 86 import android.content.SharedPreferences; |
| 102 import android.content.pm.PackageManager; | 87 import android.content.pm.PackageManager; |
| 103 import android.content.pm.ResolveInfo; | 88 import android.content.pm.ResolveInfo; |
| 104 import android.content.res.Configuration; | 89 import android.content.res.Configuration; |
| 105 import android.content.res.Resources; | 90 import android.content.res.Resources; |
| 106 import android.database.Cursor; | 91 import android.database.Cursor; |
| 107 import android.graphics.Bitmap; | 92 import android.graphics.Bitmap; |
| 108 import android.graphics.Rect; | 93 import android.graphics.Rect; |
| 109 import android.graphics.drawable.BitmapDrawable; | 94 import android.graphics.drawable.BitmapDrawable; |
| 110 import android.graphics.drawable.Drawable; | 95 import android.graphics.drawable.Drawable; |
| 111 import android.net.Uri; | 96 import android.net.Uri; |
| 112 import android.nfc.NdefMessage; | 97 import android.nfc.NdefMessage; |
| 113 import android.nfc.NdefRecord; | 98 import android.nfc.NdefRecord; |
| 114 import android.nfc.NfcAdapter; | 99 import android.nfc.NfcAdapter; |
| 115 import android.nfc.NfcEvent; | 100 import android.nfc.NfcEvent; |
| 116 import android.os.Build; | 101 import android.os.Build; |
| 117 import android.os.Bundle; | 102 import android.os.Bundle; |
| 118 import android.os.StrictMode; | 103 import android.os.StrictMode; |
| 119 import android.support.v4.app.DialogFragment; | 104 import android.support.v4.app.Fragment; |
| 120 import android.support.v4.app.FragmentManager; | 105 import android.support.v4.app.FragmentManager; |
| 121 import android.support.v4.content.LocalBroadcastManager; | |
| 122 import android.text.TextUtils; | 106 import android.text.TextUtils; |
| 123 import android.util.AttributeSet; | 107 import android.util.AttributeSet; |
| 108 import android.util.Base64; | |
| 109 import android.util.Base64OutputStream; | |
| 124 import android.util.Log; | 110 import android.util.Log; |
| 125 import android.view.InputDevice; | 111 import android.view.InputDevice; |
| 126 import android.view.KeyEvent; | 112 import android.view.KeyEvent; |
| 127 import android.view.LayoutInflater; | 113 import android.view.LayoutInflater; |
| 128 import android.view.Menu; | 114 import android.view.Menu; |
| 129 import android.view.MenuInflater; | 115 import android.view.MenuInflater; |
| 130 import android.view.MenuItem; | 116 import android.view.MenuItem; |
| 131 import android.view.MotionEvent; | 117 import android.view.MotionEvent; |
| 132 import android.view.SubMenu; | 118 import android.view.SubMenu; |
| 133 import android.view.View; | 119 import android.view.View; |
| 134 import android.view.ViewGroup; | 120 import android.view.ViewGroup; |
| 135 import android.view.ViewStub; | 121 import android.view.ViewStub; |
| 136 import android.view.ViewTreeObserver; | 122 import android.view.ViewTreeObserver; |
| 137 import android.view.Window; | 123 import android.view.Window; |
| 138 import android.view.animation.Interpolator; | 124 import android.view.animation.Interpolator; |
| 139 import android.widget.ListView; | 125 import android.widget.ListView; |
| 140 import android.widget.RelativeLayout; | 126 import android.widget.RelativeLayout; |
| 141 import android.widget.Toast; | 127 import android.widget.Toast; |
| 142 import android.widget.ViewFlipper; | 128 import android.widget.ViewFlipper; |
| 129 import org.json.JSONException; | |
| 130 import org.json.JSONObject; | |
| 131 | |
| 132 import java.io.ByteArrayOutputStream; | |
| 133 import java.io.File; | |
| 134 import java.io.FileNotFoundException; | |
| 135 import java.io.IOException; | |
| 136 import java.lang.reflect.Method; | |
| 137 import java.net.URLEncoder; | |
| 138 import java.util.EnumSet; | |
| 139 import java.util.HashSet; | |
| 140 import java.util.List; | |
| 141 import java.util.Locale; | |
| 142 import java.util.Vector; | |
| 143 | 143 |
| 144 public class BrowserApp extends GeckoApp | 144 public class BrowserApp extends GeckoApp |
| 145 implements TabsPanel.TabsLayoutChangeListener, | 145 implements TabsPanel.TabsLayoutChangeListener, |
| 146 PropertyAnimator.PropertyAnimationListener, | 146 PropertyAnimator.PropertyAnimationListener, |
| 147 View.OnKeyListener, | 147 View.OnKeyListener, |
| 148 LayerView.OnMetricsChangedListener, | 148 LayerView.OnMetricsChangedListener, |
| 149 BrowserSearch.OnSearchListener, | 149 BrowserSearch.OnSearchListener, |
| 150 BrowserSearch.OnEditSuggestionListener, | 150 BrowserSearch.OnEditSuggestionListener, |
| 151 OnUrlOpenListener, | 151 OnUrlOpenListener, |
| 152 OnUrlOpenInBackgroundListener, | 152 OnUrlOpenInBackgroundListener, |
| 153 ActionModeCompat.Presenter, | 153 ActionModeCompat.Presenter, |
| 154 LayoutInflater.Factory { | 154 LayoutInflater.Factory { |
| 155 private static final String LOGTAG = "GeckoBrowserApp"; | 155 private static final String LOGTAG = "GeckoBrowserApp"; |
| 156 | 156 |
| 157 private static final boolean ZOOMED_VIEW_ENABLED = AppConstants.NIGHTLY_BUIL D; | |
| 158 | |
| 157 private static final int TABS_ANIMATION_DURATION = 450; | 159 private static final int TABS_ANIMATION_DURATION = 450; |
| 158 | 160 |
| 159 private static final String ADD_SHORTCUT_TOAST = "add_shortcut_toast"; | 161 private static final String ADD_SHORTCUT_TOAST = "add_shortcut_toast"; |
| 160 public static final String GUEST_BROWSING_ARG = "--guest"; | 162 public static final String GUEST_BROWSING_ARG = "--guest"; |
| 161 | 163 |
| 162 private static final String STATE_ABOUT_HOME_TOP_PADDING = "abouthome_top_pa dding"; | 164 private static final String STATE_ABOUT_HOME_TOP_PADDING = "abouthome_top_pa dding"; |
| 163 | 165 |
| 164 private static final String BROWSER_SEARCH_TAG = "browser_search"; | 166 private static final String BROWSER_SEARCH_TAG = "browser_search"; |
| 165 private static final String ONBOARD_STARTPANE_TAG = "startpane_dialog"; | |
| 166 | 167 |
| 167 // Request ID for startActivityForResult. | 168 // Request ID for startActivityForResult. |
| 168 private static final int ACTIVITY_REQUEST_PREFERENCES = 1001; | 169 private static final int ACTIVITY_REQUEST_PREFERENCES = 1001; |
| 169 | 170 |
| 170 public static final String PREF_STARTPANE_ENABLED = "startpane_enabled"; | 171 @RobocopTarget |
| 172 public static final String EXTRA_SKIP_STARTPANE = "skipstartpane"; | |
| 171 | 173 |
| 172 private BrowserSearch mBrowserSearch; | 174 private BrowserSearch mBrowserSearch; |
| 173 private View mBrowserSearchContainer; | 175 private View mBrowserSearchContainer; |
| 174 | 176 |
| 175 public ViewGroup mBrowserChrome; | 177 public ViewGroup mBrowserChrome; |
| 176 public ViewFlipper mActionBarFlipper; | 178 public ViewFlipper mActionBarFlipper; |
| 177 public ActionModeCompatView mActionBar; | 179 public ActionModeCompatView mActionBar; |
| 178 private BrowserToolbar mBrowserToolbar; | 180 private BrowserToolbar mBrowserToolbar; |
| 179 // We can't name the TabStrip class because it's not included on API 9. | 181 // We can't name the TabStrip class because it's not included on API 9. |
| 180 private Refreshable mTabStrip; | 182 private Refreshable mTabStrip; |
| 181 private ToolbarProgressView mProgressView; | 183 private ToolbarProgressView mProgressView; |
| 184 private FirstrunPane mFirstrunPane; | |
| 182 private HomePager mHomePager; | 185 private HomePager mHomePager; |
| 183 private TabsPanel mTabsPanel; | 186 private TabsPanel mTabsPanel; |
| 184 private ViewGroup mHomePagerContainer; | 187 private ViewGroup mHomePagerContainer; |
| 185 protected Telemetry.Timer mAboutHomeStartupTimer; | |
| 186 private ActionModeCompat mActionMode; | 188 private ActionModeCompat mActionMode; |
| 187 private boolean mHideDynamicToolbarOnActionModeEnd; | 189 private boolean mHideDynamicToolbarOnActionModeEnd; |
| 188 private TabHistoryController tabHistoryController; | 190 private TabHistoryController tabHistoryController; |
| 191 private ZoomedView mZoomedView; | |
| 189 | 192 |
| 190 private static final int GECKO_TOOLS_MENU = -1; | 193 private static final int GECKO_TOOLS_MENU = -1; |
| 191 private static final int ADDON_MENU_OFFSET = 1000; | 194 private static final int ADDON_MENU_OFFSET = 1000; |
| 192 public static final String TAB_HISTORY_FRAGMENT_TAG = "tabHistoryFragment"; | 195 public static final String TAB_HISTORY_FRAGMENT_TAG = "tabHistoryFragment"; |
| 196 | |
| 193 private static class MenuItemInfo { | 197 private static class MenuItemInfo { |
| 194 public int id; | 198 public int id; |
| 195 public String label; | 199 public String label; |
| 196 public String icon; | 200 public String icon; |
| 197 public boolean checkable; | 201 public boolean checkable; |
| 198 public boolean checked; | 202 public boolean checked; |
| 199 public boolean enabled = true; | 203 public boolean enabled = true; |
| 200 public boolean visible = true; | 204 public boolean visible = true; |
| 201 public int parent; | 205 public int parent; |
| 202 public boolean added; // So we can re-add after a locale change. | 206 public boolean added; // So we can re-add after a locale change. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 230 private int mToolbarHeight; | 234 private int mToolbarHeight; |
| 231 | 235 |
| 232 // Stored value of whether the last metrics change allowed for toolbar | 236 // Stored value of whether the last metrics change allowed for toolbar |
| 233 // scrolling. | 237 // scrolling. |
| 234 private boolean mDynamicToolbarCanScroll; | 238 private boolean mDynamicToolbarCanScroll; |
| 235 | 239 |
| 236 private SharedPreferencesHelper mSharedPreferencesHelper; | 240 private SharedPreferencesHelper mSharedPreferencesHelper; |
| 237 | 241 |
| 238 private OrderedBroadcastHelper mOrderedBroadcastHelper; | 242 private OrderedBroadcastHelper mOrderedBroadcastHelper; |
| 239 | 243 |
| 240 private BroadcastReceiver mOnboardingReceiver; | |
| 241 | |
| 242 private BrowserHealthReporter mBrowserHealthReporter; | 244 private BrowserHealthReporter mBrowserHealthReporter; |
| 243 | 245 |
| 244 private ReadingListHelper mReadingListHelper; | 246 private ReadingListHelper mReadingListHelper; |
| 245 | 247 |
| 246 // The tab to be selected on editing mode exit. | 248 // The tab to be selected on editing mode exit. |
| 247 private Integer mTargetTabForEditingMode; | 249 private Integer mTargetTabForEditingMode; |
| 248 | 250 |
| 249 private final TabEditingState mLastTabEditingState = new TabEditingState(); | 251 private final TabEditingState mLastTabEditingState = new TabEditingState(); |
| 250 | 252 |
| 251 // The animator used to toggle HomePager visibility has a race where if the HomePager is shown | 253 // The animator used to toggle HomePager visibility has a race where if the HomePager is shown |
| 252 // (starting the animation), the HomePager is hidden, and the HomePager anim ation completes, | 254 // (starting the animation), the HomePager is hidden, and the HomePager anim ation completes, |
| 253 // both the web content and the HomePager will be hidden. This flag is used to prevent the | 255 // both the web content and the HomePager will be hidden. This flag is used to prevent the |
| 254 // race by determining if the web content should be hidden at the animation' s end. | 256 // race by determining if the web content should be hidden at the animation' s end. |
| 255 private boolean mHideWebContentOnAnimationEnd; | 257 private boolean mHideWebContentOnAnimationEnd; |
| 256 | 258 |
| 257 private final DynamicToolbar mDynamicToolbar = new DynamicToolbar(); | 259 private final DynamicToolbar mDynamicToolbar = new DynamicToolbar(); |
| 258 | 260 |
| 261 private DragHelper mDragHelper; | |
| 262 | |
| 263 private class DragHelper implements OuterLayout.DragCallback { | |
| 264 private int[] mToolbarLocation = new int[2]; // to avoid creation every time we need to check for toolbar location. | |
| 265 // When dragging horizontally, the area of mainlayout between left drag bound and right drag bound can | |
| 266 // be dragged. A touch on the right of that area will automatically clos e the view. | |
| 267 private int mStatusBarHeight; | |
| 268 | |
| 269 public DragHelper() { | |
| 270 // If a layout round happens from the root, the offset placed by vie wdraghelper gets forgotten and | |
| 271 // main layout gets replaced to offset 0. | |
| 272 ((MainLayout) mMainLayout).setLayoutInterceptor(new LayoutIntercepto r() { | |
| 273 @Override | |
| 274 public void onLayout() { | |
| 275 if (mRootLayout.isMoving()) { | |
| 276 mRootLayout.restoreTargetViewPosition(); | |
| 277 } | |
| 278 } | |
| 279 }); | |
| 280 } | |
| 281 | |
| 282 @Override | |
| 283 public void onDragProgress(float progress) { | |
| 284 mBrowserToolbar.setToolBarButtonsAlpha(1.0f - progress); | |
| 285 mTabsPanel.translateInRange(progress); | |
| 286 } | |
| 287 | |
| 288 @Override | |
| 289 public View getViewToDrag() { | |
| 290 return mMainLayout; | |
| 291 } | |
| 292 | |
| 293 /** | |
| 294 * Since pressing the tabs button slides the main layout, whereas draghe lper changes its offset, here we | |
| 295 * restore the position of mainlayout as if it was opened by pressing th e button. This allows the closing | |
| 296 * mechanism to work. | |
| 297 */ | |
| 298 @Override | |
| 299 public void startDrag(boolean wasOpen) { | |
| 300 if (wasOpen) { | |
| 301 mTabsPanel.setHWLayerEnabled(true); | |
| 302 mMainLayout.offsetTopAndBottom(getDragRange()); | |
| 303 mMainLayout.scrollTo(0, 0); | |
| 304 } else { | |
| 305 prepareTabsToShow(); | |
| 306 mBrowserToolbar.hideVirtualKeyboard(); | |
| 307 } | |
| 308 mBrowserToolbar.setContextMenuEnabled(false); | |
| 309 } | |
| 310 | |
| 311 @Override | |
| 312 public void stopDrag(boolean stoppingToOpen) { | |
| 313 if (stoppingToOpen) { | |
| 314 mTabsPanel.setHWLayerEnabled(false); | |
| 315 mMainLayout.offsetTopAndBottom(-getDragRange()); | |
| 316 mMainLayout.scrollTo(0, -getDragRange()); | |
| 317 } else { | |
| 318 mTabsPanel.hideImmediately(); | |
| 319 mTabsPanel.setHWLayerEnabled(false); | |
| 320 } | |
| 321 // Re-enabling context menu only while stopping to close. | |
| 322 if (stoppingToOpen) { | |
| 323 mBrowserToolbar.setContextMenuEnabled(false); | |
| 324 } else { | |
| 325 mBrowserToolbar.setContextMenuEnabled(true); | |
| 326 } | |
| 327 } | |
| 328 | |
| 329 @Override | |
| 330 public int getDragRange() { | |
| 331 return mTabsPanel.getVerticalPanelHeight(); | |
| 332 } | |
| 333 | |
| 334 @Override | |
| 335 public int getOrderedChildIndex(int index) { | |
| 336 // See ViewDragHelper's findTopChildUnder method. ViewDragHelper loo ks for the topmost view in z order | |
| 337 // to understand what needs to be dragged. Here we are tampering Toa st's index in case it's hidden, | |
| 338 // otherwise draghelper would try to drag it. | |
| 339 int mainLayoutIndex = mRootLayout.indexOfChild(mMainLayout); | |
| 340 if (index > mainLayoutIndex && (mToast == null || !mToast.isVisible ())) { | |
| 341 return mainLayoutIndex; | |
| 342 } else { | |
| 343 return index; | |
| 344 } | |
| 345 } | |
| 346 | |
| 347 @Override | |
| 348 public boolean canDrag(MotionEvent event) { | |
| 349 if (!AppConstants.MOZ_DRAGGABLE_URLBAR) { | |
| 350 return false; | |
| 351 } | |
| 352 | |
| 353 // if no current tab is active. | |
| 354 if (Tabs.getInstance().getSelectedTab() == null) { | |
| 355 return false; | |
| 356 } | |
| 357 | |
| 358 // currently disabled for tablets. | |
| 359 if (HardwareUtils.isTablet()) { | |
| 360 return false; | |
| 361 } | |
| 362 | |
| 363 // not enabled in editing mode. | |
| 364 if (mBrowserToolbar.isEditing()) { | |
| 365 return false; | |
| 366 } | |
| 367 | |
| 368 return isInToolbarBounds((int) event.getRawY()); | |
| 369 } | |
| 370 | |
| 371 @Override | |
| 372 public boolean canInterceptEventWhileOpen(MotionEvent event) { | |
| 373 if (event.getActionMasked() != MotionEvent.ACTION_DOWN) { | |
| 374 return false; | |
| 375 } | |
| 376 | |
| 377 // Need to check if are intercepting a touch on main layout since we might hit a visible toast. | |
| 378 if (mRootLayout.findTopChildUnder(event) == mMainLayout && | |
| 379 isInToolbarBounds((int) event.getRawY())) { | |
| 380 return true; | |
| 381 } | |
| 382 return false; | |
| 383 } | |
| 384 | |
| 385 private boolean isInToolbarBounds(int y) { | |
| 386 mBrowserToolbar.getLocationOnScreen(mToolbarLocation); | |
| 387 final int upperLimit = mToolbarLocation[1] + mBrowserToolbar.getMeas uredHeight(); | |
| 388 final int lowerLimit = mToolbarLocation[1]; | |
| 389 return (y > lowerLimit && y < upperLimit); | |
| 390 } | |
| 391 | |
| 392 public void prepareTabsToShow() { | |
| 393 if (ensureTabsPanelExists()) { | |
| 394 // If we've just inflated the tabs panel, only show it once the current | |
| 395 // layout pass is done to avoid displayed temporary UI states du ring | |
| 396 // relayout. | |
| 397 final ViewTreeObserver vto = mTabsPanel.getViewTreeObserver(); | |
| 398 if (vto.isAlive()) { | |
| 399 vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalL ayoutListener() { | |
| 400 @Override | |
| 401 public void onGlobalLayout() { | |
| 402 mTabsPanel.getViewTreeObserver().removeGlobalOnLayou tListener(this); | |
| 403 prepareTabsToShow(); | |
| 404 } | |
| 405 }); | |
| 406 } | |
| 407 } else { | |
| 408 mTabsPanel.prepareToDrag(); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 public int getLowerLimit() { | |
| 413 return getStatusBarHeight(); | |
| 414 } | |
| 415 | |
| 416 private int getStatusBarHeight() { | |
| 417 if (mStatusBarHeight != 0) { | |
| 418 return mStatusBarHeight; | |
| 419 } | |
| 420 final int resourceId = getResources().getIdentifier("status_bar_heig ht", "dimen", "android"); | |
| 421 if (resourceId > 0) { | |
| 422 mStatusBarHeight = getResources().getDimensionPixelSize(resource Id); | |
| 423 return mStatusBarHeight; | |
| 424 } | |
| 425 Log.e(LOGTAG, "Unable to find statusbar height"); | |
| 426 return 0; | |
| 427 } | |
| 428 } | |
| 429 | |
| 259 @Override | 430 @Override |
| 260 public View onCreateView(final String name, final Context context, final Att ributeSet attrs) { | 431 public View onCreateView(final String name, final Context context, final Att ributeSet attrs) { |
| 261 final View view; | 432 final View view; |
| 262 if (BrowserToolbar.class.getName().equals(name)) { | 433 if (BrowserToolbar.class.getName().equals(name)) { |
| 263 view = BrowserToolbar.create(context, attrs); | 434 view = BrowserToolbar.create(context, attrs); |
| 264 } else if (TabsPanel.TabsLayout.class.getName().equals(name)) { | 435 } else if (TabsPanel.TabsLayout.class.getName().equals(name)) { |
| 265 view = TabsPanel.createTabsLayout(context, attrs); | 436 view = TabsPanel.createTabsLayout(context, attrs); |
| 266 } else { | 437 } else { |
| 267 view = super.onCreateView(name, context, attrs); | 438 view = super.onCreateView(name, context, attrs); |
| 268 } | 439 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 case UNSELECTED: | 494 case UNSELECTED: |
| 324 // We receive UNSELECTED immediately after the SELECTED listener s run | 495 // We receive UNSELECTED immediately after the SELECTED listener s run |
| 325 // so we are ensured that the unselectedTabEditingText has not c hanged. | 496 // so we are ensured that the unselectedTabEditingText has not c hanged. |
| 326 if (tab.isEditing()) { | 497 if (tab.isEditing()) { |
| 327 // Copy to avoid constructing new objects. | 498 // Copy to avoid constructing new objects. |
| 328 tab.getEditingState().copyFrom(mLastTabEditingState); | 499 tab.getEditingState().copyFrom(mLastTabEditingState); |
| 329 } | 500 } |
| 330 break; | 501 break; |
| 331 } | 502 } |
| 332 | 503 |
| 333 if (NewTabletUI.isEnabled(this) && msg == TabEvents.SELECTED) { | 504 if (HardwareUtils.isTablet() && msg == TabEvents.SELECTED) { |
| 334 updateEditingModeForTab(tab); | 505 updateEditingModeForTab(tab); |
| 335 } | 506 } |
| 336 | 507 |
| 337 super.onTabChanged(tab, msg, data); | 508 super.onTabChanged(tab, msg, data); |
| 338 } | 509 } |
| 339 | 510 |
| 340 private void updateEditingModeForTab(final Tab selectedTab) { | 511 private void updateEditingModeForTab(final Tab selectedTab) { |
| 341 // (bug 1086983 comment 11) Because the tab may be selected from the gec ko thread and we're | 512 // (bug 1086983 comment 11) Because the tab may be selected from the gec ko thread and we're |
| 342 // running this code on the UI thread, the selected tab argument may not still refer to the | 513 // running this code on the UI thread, the selected tab argument may not still refer to the |
| 343 // selected tab. However, that means this code should be run again and t he initial state | 514 // selected tab. However, that means this code should be run again and t he initial state |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 @Override | 657 @Override |
| 487 public boolean onKeyUp(int keyCode, KeyEvent event) { | 658 public boolean onKeyUp(int keyCode, KeyEvent event) { |
| 488 if (AndroidGamepadManager.handleKeyEvent(event)) { | 659 if (AndroidGamepadManager.handleKeyEvent(event)) { |
| 489 return true; | 660 return true; |
| 490 } | 661 } |
| 491 return super.onKeyUp(keyCode, event); | 662 return super.onKeyUp(keyCode, event); |
| 492 } | 663 } |
| 493 | 664 |
| 494 @Override | 665 @Override |
| 495 public void onCreate(Bundle savedInstanceState) { | 666 public void onCreate(Bundle savedInstanceState) { |
| 496 mAboutHomeStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_ ABOUTHOME"); | 667 final Intent intent = getIntent(); |
| 497 | 668 |
| 498 final Intent intent = getIntent(); | 669 // Note that we're calling GeckoProfile.get *before GeckoApp.onCreate*. |
| 670 // This means we're reliant on the logic in GeckoProfile to correctly | |
| 671 // look up our launch intent (via BrowserApp's Activity-ness) and pull | |
| 672 // out the arguments. Be careful if you change that! | |
| 499 final GeckoProfile p = GeckoProfile.get(this); | 673 final GeckoProfile p = GeckoProfile.get(this); |
| 674 | |
| 500 if (p != null && !p.inGuestMode()) { | 675 if (p != null && !p.inGuestMode()) { |
| 501 // This is *only* valid because we never want to use the guest mode | 676 // This is *only* valid because we never want to use the guest mode |
| 502 // profile concurrently with a normal profile -- no syncing to it, | 677 // profile concurrently with a normal profile -- no syncing to it, |
| 503 // no dual-profile usage, nothing. BrowserApp startup with a convent ional | 678 // no dual-profile usage, nothing. BrowserApp startup with a convent ional |
| 504 // GeckoProfile will cause the guest profile to be deleted. | 679 // GeckoProfile will cause the guest profile to be deleted. |
| 505 GeckoProfile.maybeCleanupGuestProfile(this); | 680 GeckoProfile.maybeCleanupGuestProfile(this); |
| 506 } | 681 } |
| 507 | 682 |
| 508 // This has to be prepared prior to calling GeckoApp.onCreate, because | 683 // This has to be prepared prior to calling GeckoApp.onCreate, because |
| 509 // widget code and BrowserToolbar need it, and they're created by the | 684 // widget code and BrowserToolbar need it, and they're created by the |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 final String action = intent.getAction(); | 716 final String action = intent.getAction(); |
| 542 if (Intent.ACTION_VIEW.equals(action)) { | 717 if (Intent.ACTION_VIEW.equals(action)) { |
| 543 // Show the target URL immediately in the toolbar. | 718 // Show the target URL immediately in the toolbar. |
| 544 mBrowserToolbar.setTitle(intent.getDataString()); | 719 mBrowserToolbar.setTitle(intent.getDataString()); |
| 545 | 720 |
| 546 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryCon tract.Method.INTENT); | 721 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryCon tract.Method.INTENT); |
| 547 } else if (GuestSession.NOTIFICATION_INTENT.equals(action)) { | 722 } else if (GuestSession.NOTIFICATION_INTENT.equals(action)) { |
| 548 GuestSession.handleIntent(this, intent); | 723 GuestSession.handleIntent(this, intent); |
| 549 } | 724 } |
| 550 | 725 |
| 551 if (NewTabletUI.isEnabled(this)) { | 726 if (HardwareUtils.isTablet()) { |
| 552 mTabStrip = (Refreshable) (((ViewStub) findViewById(R.id.new_tablet_ tab_strip)).inflate()); | 727 mTabStrip = (Refreshable) (((ViewStub) findViewById(R.id.new_tablet_ tab_strip)).inflate()); |
| 553 } | 728 } |
| 554 | 729 |
| 555 ((GeckoApp.MainLayout) mMainLayout).setTouchEventInterceptor(new HideOnT ouchListener()); | 730 ((GeckoApp.MainLayout) mMainLayout).setTouchEventInterceptor(new HideOnT ouchListener()); |
| 556 ((GeckoApp.MainLayout) mMainLayout).setMotionEventInterceptor(new Motion EventInterceptor() { | 731 ((GeckoApp.MainLayout) mMainLayout).setMotionEventInterceptor(new Motion EventInterceptor() { |
| 557 @Override | 732 @Override |
| 558 public boolean onInterceptMotionEvent(View view, MotionEvent event) { | 733 public boolean onInterceptMotionEvent(View view, MotionEvent event) { |
| 559 // If we get a gamepad panning MotionEvent while the focus is no t on the layerview, | 734 // If we get a gamepad panning MotionEvent while the focus is no t on the layerview, |
| 560 // put the focus on the layerview and carry on | 735 // put the focus on the layerview and carry on |
| 561 if (mLayerView != null && !mLayerView.hasFocus() && GamepadUtils .isPanningControl(event)) { | 736 if (mLayerView != null && !mLayerView.hasFocus() && GamepadUtils .isPanningControl(event)) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 591 "Menu:Open", | 766 "Menu:Open", |
| 592 "Menu:Update", | 767 "Menu:Update", |
| 593 "Search:Keyword", | 768 "Search:Keyword", |
| 594 "Prompt:ShowTop", | 769 "Prompt:ShowTop", |
| 595 "Accounts:Exist"); | 770 "Accounts:Exist"); |
| 596 | 771 |
| 597 EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventLi stener)this, | 772 EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventLi stener)this, |
| 598 "Accounts:Create", | 773 "Accounts:Create", |
| 599 "CharEncoding:Data", | 774 "CharEncoding:Data", |
| 600 "CharEncoding:State", | 775 "CharEncoding:State", |
| 776 "Favicon:CacheLoad", | |
| 601 "Feedback:LastUrl", | 777 "Feedback:LastUrl", |
| 602 "Feedback:MaybeLater", | 778 "Feedback:MaybeLater", |
| 603 "Feedback:OpenPlayStore", | 779 "Feedback:OpenPlayStore", |
| 604 "Menu:Add", | 780 "Menu:Add", |
| 605 "Menu:Remove", | 781 "Menu:Remove", |
| 606 "Reader:Share", | 782 "Reader:Share", |
| 607 "Settings:Show", | 783 "Settings:Show", |
| 608 "Telemetry:Gather", | 784 "Telemetry:Gather", |
| 609 "Updater:Launch", | 785 "Updater:Launch"); |
| 610 "BrowserToolbar:Visibility"); | |
| 611 | 786 |
| 612 Distribution distribution = Distribution.init(this); | 787 Distribution distribution = Distribution.init(this); |
| 613 | 788 |
| 614 // Init suggested sites engine in BrowserDB. | 789 // Init suggested sites engine in BrowserDB. |
| 615 final SuggestedSites suggestedSites = new SuggestedSites(appContext, dis tribution); | 790 final SuggestedSites suggestedSites = new SuggestedSites(appContext, dis tribution); |
| 616 BrowserDB.setSuggestedSites(suggestedSites); | 791 final BrowserDB db = getProfile().getDB(); |
| 792 db.setSuggestedSites(suggestedSites); | |
| 617 | 793 |
| 618 JavaAddonManager.getInstance().init(appContext); | 794 JavaAddonManager.getInstance().init(appContext); |
| 619 mSharedPreferencesHelper = new SharedPreferencesHelper(appContext); | 795 mSharedPreferencesHelper = new SharedPreferencesHelper(appContext); |
| 620 mOrderedBroadcastHelper = new OrderedBroadcastHelper(appContext); | 796 mOrderedBroadcastHelper = new OrderedBroadcastHelper(appContext); |
| 621 mBrowserHealthReporter = new BrowserHealthReporter(); | 797 mBrowserHealthReporter = new BrowserHealthReporter(); |
| 622 mReadingListHelper = new ReadingListHelper(appContext); | 798 mReadingListHelper = new ReadingListHelper(appContext, getProfile()); |
| 623 | 799 |
| 624 if (AppConstants.MOZ_ANDROID_BEAM) { | 800 if (AppConstants.MOZ_ANDROID_BEAM) { |
| 625 NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this); | 801 NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this); |
| 626 if (nfc != null) { | 802 if (nfc != null) { |
| 627 nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageC allback() { | 803 nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageC allback() { |
| 628 @Override | 804 @Override |
| 629 public NdefMessage createNdefMessage(NfcEvent event) { | 805 public NdefMessage createNdefMessage(NfcEvent event) { |
| 630 Tab tab = Tabs.getInstance().getSelectedTab(); | 806 Tab tab = Tabs.getInstance().getSelectedTab(); |
| 631 if (tab == null || tab.isPrivate()) { | 807 if (tab == null || tab.isPrivate()) { |
| 632 return null; | 808 return null; |
| 633 } | 809 } |
| 634 return new NdefMessage(new NdefRecord[] { NdefRecord.cre ateUri(tab.getURL()) }); | 810 return new NdefMessage(new NdefRecord[] { NdefRecord.cre ateUri(tab.getURL()) }); |
| 635 } | 811 } |
| 636 }, this); | 812 }, this); |
| 637 } | 813 } |
| 638 } | 814 } |
| 639 | 815 |
| 640 if (savedInstanceState != null) { | 816 if (savedInstanceState != null) { |
| 641 mDynamicToolbar.onRestoreInstanceState(savedInstanceState); | 817 mDynamicToolbar.onRestoreInstanceState(savedInstanceState); |
| 642 mHomePagerContainer.setPadding(0, savedInstanceState.getInt(STATE_AB OUT_HOME_TOP_PADDING), 0, 0); | 818 mHomePagerContainer.setPadding(0, savedInstanceState.getInt(STATE_AB OUT_HOME_TOP_PADDING), 0, 0); |
| 643 } | 819 } |
| 644 | 820 |
| 645 mDynamicToolbar.setEnabledChangedListener(new DynamicToolbar.OnEnabledCh angedListener() { | 821 mDynamicToolbar.setEnabledChangedListener(new DynamicToolbar.OnEnabledCh angedListener() { |
| 646 @Override | 822 @Override |
| 647 public void onEnabledChanged(boolean enabled) { | 823 public void onEnabledChanged(boolean enabled) { |
| 648 setDynamicToolbarEnabled(enabled); | 824 setDynamicToolbarEnabled(enabled); |
| 649 } | 825 } |
| 650 }); | 826 }); |
| 651 | 827 |
| 828 mDragHelper = new DragHelper(); | |
| 829 mRootLayout.setDraggableCallback(mDragHelper); | |
| 830 | |
| 652 // Set the maximum bits-per-pixel the favicon system cares about. | 831 // Set the maximum bits-per-pixel the favicon system cares about. |
| 653 IconDirectoryEntry.setMaxBPP(GeckoAppShell.getScreenDepth()); | 832 IconDirectoryEntry.setMaxBPP(GeckoAppShell.getScreenDepth()); |
| 833 | |
| 834 if (ZOOMED_VIEW_ENABLED) { | |
| 835 ViewStub stub = (ViewStub) findViewById(R.id.zoomed_view_stub); | |
| 836 mZoomedView = (ZoomedView) stub.inflate(); | |
| 837 } | |
| 654 } | 838 } |
| 655 | 839 |
| 656 /** | 840 /** |
| 657 * Check and show Onboarding start pane if Firefox has never been launched a nd | 841 * Check and show the firstrun pane if the browser has never been launched a nd |
| 658 * is not opening an external link from another application. | 842 * is not opening an external link from another application. |
| 659 * | 843 * |
| 660 * @param context Context of application; used to show Start Pane if appropr iate | 844 * @param context Context of application; used to show firstrun pane if appr opriate |
| 661 * @param intentAction Intent that launched this activity | 845 * @param intent Intent that launched this activity |
| 662 */ | 846 */ |
| 663 private void checkStartPane(Context context, String intentAction) { | 847 private void checkFirstrun(Context context, SafeIntent intent) { |
| 848 if (intent.getBooleanExtra(EXTRA_SKIP_STARTPANE, false)) { | |
| 849 // Note that we don't set the pref, so subsequent launches can resul t | |
| 850 // in the firstrun pane being shown. | |
| 851 return; | |
| 852 } | |
| 664 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskRe ads(); | 853 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskRe ads(); |
| 665 | 854 |
| 666 try { | 855 try { |
| 667 final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this); | 856 final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this); |
| 668 | 857 |
| 669 if (prefs.getBoolean(PREF_STARTPANE_ENABLED, false)) { | 858 if (prefs.getBoolean(FirstrunPane.PREF_FIRSTRUN_ENABLED, false)) { |
| 670 if (!Intent.ACTION_VIEW.equals(intentAction)) { | 859 if (!Intent.ACTION_VIEW.equals(intent.getAction())) { |
| 671 final DialogFragment dialog = new org.adblockplus.browser.St artPane(); | 860 showFirstrunPager(); |
| 672 dialog.show(getSupportFragmentManager(), ONBOARD_STARTPANE_T AG); | |
| 673 } | 861 } |
| 674 // Don't bother trying again to show the v1 minimal first run. | 862 // Don't bother trying again to show the v1 minimal first run. |
| 675 prefs.edit().putBoolean(PREF_STARTPANE_ENABLED, false).apply(); | 863 prefs.edit().putBoolean(FirstrunPane.PREF_FIRSTRUN_ENABLED, fals e).apply(); |
| 676 } | 864 } |
| 677 } finally { | 865 } finally { |
| 678 StrictMode.setThreadPolicy(savedPolicy); | 866 StrictMode.setThreadPolicy(savedPolicy); |
| 679 } | 867 } |
| 680 } | 868 } |
| 681 | 869 |
| 682 private Class<?> getMediaPlayerManager() { | 870 private Class<?> getMediaPlayerManager() { |
| 683 if (AppConstants.MOZ_MEDIA_PLAYER) { | 871 if (AppConstants.MOZ_MEDIA_PLAYER) { |
| 684 try { | 872 try { |
| 685 return Class.forName("org.mozilla.gecko.MediaPlayerManager"); | 873 return Class.forName("org.mozilla.gecko.MediaPlayerManager"); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 701 | 889 |
| 702 if (mBrowserToolbar.onBackPressed()) { | 890 if (mBrowserToolbar.onBackPressed()) { |
| 703 return; | 891 return; |
| 704 } | 892 } |
| 705 | 893 |
| 706 if (mActionMode != null) { | 894 if (mActionMode != null) { |
| 707 endActionModeCompat(); | 895 endActionModeCompat(); |
| 708 return; | 896 return; |
| 709 } | 897 } |
| 710 | 898 |
| 899 if (hideFirstrunPager()) { | |
| 900 Telemetry.sendUIEvent(TelemetryContract.Event.CANCEL, TelemetryContr act.Method.BACK, "firstrun-pane"); | |
| 901 return; | |
| 902 } | |
| 903 | |
| 711 super.onBackPressed(); | 904 super.onBackPressed(); |
| 712 } | 905 } |
| 713 | 906 |
| 714 @Override | 907 @Override |
| 715 public void onAttachedToWindow() { | 908 public void onAttachedToWindow() { |
| 716 // We can't show Onboarding until Gecko has finished initialization (bug 1077583). | 909 // We can't show the first run experience until Gecko has finished initi alization (bug 1077583). |
|
Felix Dahlke
2015/07/22 16:19:18
lol, their term for this is even worse, "first run
| |
| 717 checkStartPane(this, getIntent().getAction()); | 910 checkFirstrun(this, new SafeIntent(getIntent())); |
| 911 } | |
| 912 | |
| 913 private void processTabQueue() { | |
| 914 if (AppConstants.NIGHTLY_BUILD && AppConstants.MOZ_ANDROID_TAB_QUEUE) { | |
| 915 ThreadUtils.postToBackgroundThread(new Runnable() { | |
| 916 @Override | |
| 917 public void run() { | |
| 918 if (TabQueueHelper.shouldOpenTabQueueUrls(BrowserApp.this)) { | |
| 919 TabQueueHelper.openQueuedUrls(BrowserApp.this, mProfile, TabQueueHelper.FILE_NAME); | |
| 920 } | |
| 921 } | |
| 922 }); | |
| 923 } | |
| 718 } | 924 } |
| 719 | 925 |
| 720 @Override | 926 @Override |
| 721 public void onResume() { | 927 public void onResume() { |
| 722 super.onResume(); | 928 super.onResume(); |
| 723 | 929 |
| 724 final String args = ContextUtils.getStringExtra(getIntent(), "args"); | 930 final String args = ContextUtils.getStringExtra(getIntent(), "args"); |
| 725 // If an external intent tries to start Fennec in guest mode, and it's n ot already | 931 // If an external intent tries to start Fennec in guest mode, and it's n ot already |
| 726 // in guest mode, this will change modes before opening the url. | 932 // in guest mode, this will change modes before opening the url. |
| 727 // NOTE: OnResume is called twice sometimes when showing on the lock scr een. | 933 // NOTE: OnResume is called twice sometimes when showing on the lock scr een. |
| 728 final boolean enableGuestSession = GuestSession.shouldUse(this, args); | 934 final boolean enableGuestSession = GuestSession.shouldUse(this, args); |
| 729 final boolean inGuestSession = GeckoProfile.get(this).inGuestMode(); | 935 final boolean inGuestSession = GeckoProfile.get(this).inGuestMode(); |
| 730 if (enableGuestSession != inGuestSession) { | 936 if (enableGuestSession != inGuestSession) { |
| 731 doRestart(getIntent()); | 937 doRestart(getIntent()); |
| 732 GeckoAppShell.gracefulExit(); | 938 GeckoAppShell.gracefulExit(); |
| 733 return; | 939 return; |
| 734 } | 940 } |
| 735 | 941 |
| 736 EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventL istener)this, | 942 EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventL istener)this, |
| 737 "Prompt:ShowTop"); | 943 "Prompt:ShowTop"); |
| 944 | |
| 945 processTabQueue(); | |
| 738 } | 946 } |
| 739 | 947 |
| 740 @Override | 948 @Override |
| 741 public void onPause() { | 949 public void onPause() { |
| 742 super.onPause(); | 950 super.onPause(); |
| 743 // Register for Prompt:ShowTop so we can foreground this activity even i f it's hidden. | 951 // Register for Prompt:ShowTop so we can foreground this activity even i f it's hidden. |
| 744 EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventLis tener)this, | 952 EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventLis tener)this, |
| 745 "Prompt:ShowTop"); | 953 "Prompt:ShowTop"); |
| 746 | |
| 747 final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this ); | |
| 748 lbm.unregisterReceiver(mOnboardingReceiver); | |
| 749 } | 954 } |
| 750 | 955 |
| 751 @Override | 956 @Override |
| 752 public void onStart() { | 957 public void onStart() { |
| 753 super.onStart(); | 958 super.onStart(); |
| 754 | 959 |
| 755 // Queue this work so that the first launch of the activity doesn't | 960 // Queue this work so that the first launch of the activity doesn't |
| 756 // trigger profile init too early. | 961 // trigger profile init too early. |
| 757 ThreadUtils.postToBackgroundThread(new Runnable() { | 962 ThreadUtils.postToBackgroundThread(new Runnable() { |
| 758 @Override | 963 @Override |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 items[1] = new PromptListItem(res.getString(R.string.contextmenu_add_to_ launcher)); | 1117 items[1] = new PromptListItem(res.getString(R.string.contextmenu_add_to_ launcher)); |
| 913 | 1118 |
| 914 ps.show("", "", items, ListView.CHOICE_MODE_NONE); | 1119 ps.show("", "", items, ListView.CHOICE_MODE_NONE); |
| 915 } | 1120 } |
| 916 | 1121 |
| 917 private void setDynamicToolbarEnabled(boolean enabled) { | 1122 private void setDynamicToolbarEnabled(boolean enabled) { |
| 918 ThreadUtils.assertOnUiThread(); | 1123 ThreadUtils.assertOnUiThread(); |
| 919 | 1124 |
| 920 if (enabled) { | 1125 if (enabled) { |
| 921 if (mLayerView != null) { | 1126 if (mLayerView != null) { |
| 922 mLayerView.setOnMetricsChangedListener(this); | 1127 mLayerView.setOnMetricsChangedDynamicToolbarViewportListener(thi s); |
| 923 } | 1128 } |
| 924 setToolbarMargin(0); | 1129 setToolbarMargin(0); |
| 925 mHomePagerContainer.setPadding(0, mBrowserChrome.getHeight(), 0, 0); | 1130 mHomePagerContainer.setPadding(0, mBrowserChrome.getHeight(), 0, 0); |
| 926 } else { | 1131 } else { |
| 927 // Immediately show the toolbar when disabling the dynamic | 1132 // Immediately show the toolbar when disabling the dynamic |
| 928 // toolbar. | 1133 // toolbar. |
| 929 if (mLayerView != null) { | 1134 if (mLayerView != null) { |
| 930 mLayerView.setOnMetricsChangedListener(null); | 1135 mLayerView.setOnMetricsChangedDynamicToolbarViewportListener(null ); |
| 931 } | 1136 } |
| 932 mHomePagerContainer.setPadding(0, 0, 0, 0); | 1137 mHomePagerContainer.setPadding(0, 0, 0, 0); |
| 933 if (mBrowserChrome != null) { | 1138 if (mBrowserChrome != null) { |
| 934 ViewHelper.setTranslationY(mBrowserChrome, 0); | 1139 ViewHelper.setTranslationY(mBrowserChrome, 0); |
| 935 } | 1140 } |
| 936 } | 1141 } |
| 937 | 1142 |
| 938 refreshToolbarHeight(); | 1143 refreshToolbarHeight(); |
| 939 } | 1144 } |
| 940 | 1145 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1091 | 1296 |
| 1092 if (mBrowserHealthReporter != null) { | 1297 if (mBrowserHealthReporter != null) { |
| 1093 mBrowserHealthReporter.uninit(); | 1298 mBrowserHealthReporter.uninit(); |
| 1094 mBrowserHealthReporter = null; | 1299 mBrowserHealthReporter = null; |
| 1095 } | 1300 } |
| 1096 | 1301 |
| 1097 if (mReadingListHelper != null) { | 1302 if (mReadingListHelper != null) { |
| 1098 mReadingListHelper.uninit(); | 1303 mReadingListHelper.uninit(); |
| 1099 mReadingListHelper = null; | 1304 mReadingListHelper = null; |
| 1100 } | 1305 } |
| 1306 if (mZoomedView != null) { | |
| 1307 mZoomedView.destroy(); | |
| 1308 } | |
| 1101 | 1309 |
| 1102 EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventL istener)this, | 1310 EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventL istener)this, |
| 1103 "Menu:Open", | 1311 "Menu:Open", |
| 1104 "Menu:Update", | 1312 "Menu:Update", |
| 1105 "Search:Keyword", | 1313 "Search:Keyword", |
| 1106 "Prompt:ShowTop", | 1314 "Prompt:ShowTop", |
| 1107 "Accounts:Exist"); | 1315 "Accounts:Exist"); |
| 1108 | 1316 |
| 1109 EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEvent Listener)this, | 1317 EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEvent Listener)this, |
| 1110 "Accounts:Create", | 1318 "Accounts:Create", |
| 1111 "CharEncoding:Data", | 1319 "CharEncoding:Data", |
| 1112 "CharEncoding:State", | 1320 "CharEncoding:State", |
| 1321 "Favicon:CacheLoad", | |
| 1113 "Feedback:LastUrl", | 1322 "Feedback:LastUrl", |
| 1114 "Feedback:MaybeLater", | 1323 "Feedback:MaybeLater", |
| 1115 "Feedback:OpenPlayStore", | 1324 "Feedback:OpenPlayStore", |
| 1116 "Menu:Add", | 1325 "Menu:Add", |
| 1117 "Menu:Remove", | 1326 "Menu:Remove", |
| 1118 "Reader:Share", | 1327 "Reader:Share", |
| 1119 "Settings:Show", | 1328 "Settings:Show", |
| 1120 "Telemetry:Gather", | 1329 "Telemetry:Gather", |
| 1121 "Updater:Launch", | 1330 "Updater:Launch"); |
| 1122 "BrowserToolbar:Visibility"); | |
| 1123 | 1331 |
| 1124 if (AppConstants.MOZ_ANDROID_BEAM) { | 1332 if (AppConstants.MOZ_ANDROID_BEAM) { |
| 1125 NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this); | 1333 NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this); |
| 1126 if (nfc != null) { | 1334 if (nfc != null) { |
| 1127 // null this out even though the docs say it's not needed, | 1335 // null this out even though the docs say it's not needed, |
| 1128 // because the source code looks like it will only do this | 1336 // because the source code looks like it will only do this |
| 1129 // automatically on API 14+ | 1337 // automatically on API 14+ |
| 1130 nfc.setNdefPushMessageCallback(null, this); | 1338 nfc.setNdefPushMessageCallback(null, this); |
| 1131 } | 1339 } |
| 1132 } | 1340 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 url = ReaderModeUtils.getUrlFromAboutReader(url); | 1376 url = ReaderModeUtils.getUrlFromAboutReader(url); |
| 1169 } | 1377 } |
| 1170 | 1378 |
| 1171 GeckoAppShell.openUriExternal(url, "text/plain", "", "", | 1379 GeckoAppShell.openUriExternal(url, "text/plain", "", "", |
| 1172 Intent.ACTION_SEND, tab.getDisplayTitle()) ; | 1380 Intent.ACTION_SEND, tab.getDisplayTitle()) ; |
| 1173 | 1381 |
| 1174 // Context: Sharing via chrome list (no explicit session is active) | 1382 // Context: Sharing via chrome list (no explicit session is active) |
| 1175 Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.M ethod.LIST); | 1383 Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.M ethod.LIST); |
| 1176 } | 1384 } |
| 1177 | 1385 |
| 1178 @Override | |
| 1179 protected void loadStartupTab(String url, int flags) { | |
| 1180 // We aren't showing about:home, so cancel the telemetry timer | |
| 1181 if (url != null || mShouldRestore) { | |
| 1182 mAboutHomeStartupTimer.cancel(); | |
| 1183 } | |
| 1184 | |
| 1185 super.loadStartupTab(url, flags); | |
| 1186 } | |
| 1187 | |
| 1188 private void setToolbarMargin(int margin) { | 1386 private void setToolbarMargin(int margin) { |
| 1189 ((RelativeLayout.LayoutParams) mGeckoLayout.getLayoutParams()).topMargin = margin; | 1387 ((RelativeLayout.LayoutParams) mGeckoLayout.getLayoutParams()).topMargin = margin; |
| 1190 mGeckoLayout.requestLayout(); | 1388 mGeckoLayout.requestLayout(); |
| 1191 } | 1389 } |
| 1192 | 1390 |
| 1193 @Override | 1391 @Override |
| 1194 public void onMetricsChanged(ImmutableViewportMetrics aMetrics) { | 1392 public void onMetricsChanged(ImmutableViewportMetrics aMetrics) { |
| 1195 if (isHomePagerVisible() || mBrowserChrome == null) { | 1393 if (isHomePagerVisible() || mBrowserChrome == null) { |
| 1196 return; | 1394 return; |
| 1197 } | 1395 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1315 mActionBarFlipper.requestFocusFromTouch(); | 1513 mActionBarFlipper.requestFocusFromTouch(); |
| 1316 } | 1514 } |
| 1317 }); | 1515 }); |
| 1318 } | 1516 } |
| 1319 | 1517 |
| 1320 @Override | 1518 @Override |
| 1321 public void refreshChrome() { | 1519 public void refreshChrome() { |
| 1322 invalidateOptionsMenu(); | 1520 invalidateOptionsMenu(); |
| 1323 | 1521 |
| 1324 if (mTabsPanel != null) { | 1522 if (mTabsPanel != null) { |
| 1523 mRootLayout.reset(); | |
| 1325 updateSideBarState(); | 1524 updateSideBarState(); |
| 1326 mTabsPanel.refresh(); | 1525 mTabsPanel.refresh(); |
| 1327 } | 1526 } |
| 1328 | 1527 |
| 1329 if (mTabStrip != null) { | 1528 if (mTabStrip != null) { |
| 1330 mTabStrip.refresh(); | 1529 mTabStrip.refresh(); |
| 1331 } | 1530 } |
| 1332 | 1531 |
| 1333 mBrowserToolbar.refresh(); | 1532 mBrowserToolbar.refresh(); |
| 1334 } | 1533 } |
| 1335 | 1534 |
| 1336 @Override | 1535 @Override |
| 1337 public boolean hasTabsSideBar() { | 1536 public boolean hasTabsSideBar() { |
| 1338 return (mTabsPanel != null && mTabsPanel.isSideBar()); | 1537 return (mTabsPanel != null && mTabsPanel.isSideBar()); |
| 1339 } | 1538 } |
| 1340 | 1539 |
| 1341 private void setBrowserToolbarVisible(final boolean visible) { | 1540 private boolean isSideBar() { |
| 1342 ThreadUtils.postToUiThread(new Runnable() { | 1541 return (HardwareUtils.isTablet() && getOrientation() == Configuration.OR IENTATION_LANDSCAPE); |
| 1343 @Override | |
| 1344 public void run() { | |
| 1345 if (mDynamicToolbar.isEnabled()) { | |
| 1346 mDynamicToolbar.setVisible(visible, VisibilityTransition.IMM EDIATE); | |
| 1347 } | |
| 1348 } | |
| 1349 }); | |
| 1350 } | 1542 } |
| 1351 | 1543 |
| 1352 private void updateSideBarState() { | 1544 private void updateSideBarState() { |
| 1353 if (NewTabletUI.isEnabled(this)) { | 1545 if (NewTabletUI.isEnabled(this)) { |
| 1354 return; | 1546 return; |
| 1355 } | 1547 } |
| 1356 | 1548 |
| 1357 if (mMainLayoutAnimator != null) | 1549 if (mMainLayoutAnimator != null) |
| 1358 mMainLayoutAnimator.stop(); | 1550 mMainLayoutAnimator.stop(); |
| 1359 | 1551 |
| 1360 boolean isSideBar = (HardwareUtils.isTablet() && getOrientation() == Con figuration.ORIENTATION_LANDSCAPE); | 1552 boolean isSideBar = isSideBar(); |
| 1361 final int sidebarWidth = getResources().getDimensionPixelSize(R.dimen.ta bs_sidebar_width); | 1553 final int sidebarWidth = getResources().getDimensionPixelSize(R.dimen.ta bs_sidebar_width); |
| 1362 | 1554 |
| 1363 ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mTabsPa nel.getLayoutParams(); | 1555 ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mTabsPa nel.getLayoutParams(); |
| 1364 lp.width = (isSideBar ? sidebarWidth : ViewGroup.LayoutParams.MATCH_PARE NT); | 1556 lp.width = (isSideBar ? sidebarWidth : ViewGroup.LayoutParams.MATCH_PARE NT); |
| 1365 mTabsPanel.requestLayout(); | 1557 mTabsPanel.requestLayout(); |
| 1366 | 1558 |
| 1367 final boolean sidebarIsShown = (isSideBar && mTabsPanel.isShown()); | 1559 final boolean sidebarIsShown = (isSideBar && mTabsPanel.isShown()); |
| 1368 final int mainLayoutScrollX = (sidebarIsShown ? -sidebarWidth : 0); | 1560 final int mainLayoutScrollX = (sidebarIsShown ? -sidebarWidth : 0); |
| 1369 mMainLayout.scrollTo(mainLayoutScrollX, 0); | 1561 mMainLayout.scrollTo(mainLayoutScrollX, 0); |
| 1370 | 1562 |
| 1371 mTabsPanel.setIsSideBar(isSideBar); | 1563 mTabsPanel.setIsSideBar(isSideBar); |
| 1564 mRootLayout.updateDragHelperParameters(); | |
| 1372 } | 1565 } |
| 1373 | 1566 |
| 1374 @Override | 1567 @Override |
| 1375 public void handleMessage(final String event, final NativeJSObject message, | 1568 public void handleMessage(final String event, final NativeJSObject message, |
| 1376 final EventCallback callback) { | 1569 final EventCallback callback) { |
| 1377 if ("Accounts:Create".equals(event)) { | 1570 if ("Accounts:Create".equals(event)) { |
| 1378 // Do exactly the same thing as if you tapped 'Sync' in Settings. | 1571 // Do exactly the same thing as if you tapped 'Sync' in Settings. |
| 1379 final Intent intent = new Intent(getContext(), FxAccountGetStartedAc tivity.class); | 1572 final Intent intent = new Intent(getContext(), FxAccountGetStartedAc tivity.class); |
| 1380 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 1573 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| 1381 final NativeJSObject extras = message.optObject("extras", null); | 1574 final NativeJSObject extras = message.optObject("extras", null); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1426 final Menu menu = mMenu; | 1619 final Menu menu = mMenu; |
| 1427 ThreadUtils.postToUiThread(new Runnable() { | 1620 ThreadUtils.postToUiThread(new Runnable() { |
| 1428 @Override | 1621 @Override |
| 1429 public void run() { | 1622 public void run() { |
| 1430 if (menu != null) { | 1623 if (menu != null) { |
| 1431 menu.findItem(R.id.char_encoding).setVisible(visible); | 1624 menu.findItem(R.id.char_encoding).setVisible(visible); |
| 1432 } | 1625 } |
| 1433 } | 1626 } |
| 1434 }); | 1627 }); |
| 1435 | 1628 |
| 1629 } else if ("Favicon:CacheLoad".equals(event)) { | |
| 1630 final String url = message.getString("url"); | |
| 1631 getFaviconFromCache(callback, url); | |
| 1632 | |
| 1436 } else if ("Feedback:LastUrl".equals(event)) { | 1633 } else if ("Feedback:LastUrl".equals(event)) { |
| 1437 getLastUrl(callback); | 1634 getLastUrl(callback); |
| 1438 | 1635 |
| 1439 } else if ("Feedback:MaybeLater".equals(event)) { | 1636 } else if ("Feedback:MaybeLater".equals(event)) { |
| 1440 resetFeedbackLaunchCount(); | 1637 resetFeedbackLaunchCount(); |
| 1441 | 1638 |
| 1442 } else if ("Feedback:OpenPlayStore".equals(event)) { | 1639 } else if ("Feedback:OpenPlayStore".equals(event)) { |
| 1443 final Intent intent = new Intent(Intent.ACTION_VIEW); | 1640 final Intent intent = new Intent(Intent.ACTION_VIEW); |
| 1444 intent.setData(Uri.parse("market://details?id=" + getPackageName())) ; | 1641 intent.setData(Uri.parse("market://details?id=" + getPackageName())) ; |
| 1445 startActivity(intent); | 1642 startActivity(intent); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1484 GeckoPreferences.setResourceToOpen(settingsIntent, resource); | 1681 GeckoPreferences.setResourceToOpen(settingsIntent, resource); |
| 1485 startActivityForResult(settingsIntent, ACTIVITY_REQUEST_PREFERENCES) ; | 1682 startActivityForResult(settingsIntent, ACTIVITY_REQUEST_PREFERENCES) ; |
| 1486 | 1683 |
| 1487 // Don't use a transition to settings if we're on a device where tha t | 1684 // Don't use a transition to settings if we're on a device where tha t |
| 1488 // would look bad. | 1685 // would look bad. |
| 1489 if (HardwareUtils.IS_KINDLE_DEVICE) { | 1686 if (HardwareUtils.IS_KINDLE_DEVICE) { |
| 1490 overridePendingTransition(0, 0); | 1687 overridePendingTransition(0, 0); |
| 1491 } | 1688 } |
| 1492 | 1689 |
| 1493 } else if ("Telemetry:Gather".equals(event)) { | 1690 } else if ("Telemetry:Gather".equals(event)) { |
| 1494 Telemetry.addToHistogram("PLACES_PAGES_COUNT", | 1691 final BrowserDB db = getProfile().getDB(); |
| 1495 BrowserDB.getCount(getContentResolver(), "history")); | 1692 final ContentResolver cr = getContentResolver(); |
| 1496 Telemetry.addToHistogram("PLACES_BOOKMARKS_COUNT", | 1693 Telemetry.addToHistogram("PLACES_PAGES_COUNT", db.getCount(cr, "hist ory")); |
| 1497 BrowserDB.getCount(getContentResolver(), "bookmarks")); | 1694 Telemetry.addToHistogram("PLACES_BOOKMARKS_COUNT", db.getCount(cr, " bookmarks")); |
| 1498 Telemetry.addToHistogram("FENNEC_FAVICONS_COUNT", | 1695 Telemetry.addToHistogram("FENNEC_FAVICONS_COUNT", db.getCount(cr, "f avicons")); |
| 1499 BrowserDB.getCount(getContentResolver(), "favicons")); | 1696 Telemetry.addToHistogram("FENNEC_THUMBNAILS_COUNT", db.getCount(cr, "thumbnails")); |
| 1500 Telemetry.addToHistogram("FENNEC_THUMBNAILS_COUNT", | 1697 Telemetry.addToHistogram("FENNEC_READING_LIST_COUNT", db.getReadingL istAccessor().getCount(cr)); |
| 1501 BrowserDB.getCount(getContentResolver(), "thumbnails")); | |
| 1502 Telemetry.addToHistogram("FENNEC_READING_LIST_COUNT", | |
| 1503 BrowserDB.getCount(getContentResolver(), "readinglist")); | |
| 1504 Telemetry.addToHistogram("BROWSER_IS_USER_DEFAULT", (isDefaultBrowse r(Intent.ACTION_VIEW) ? 1 : 0)); | 1698 Telemetry.addToHistogram("BROWSER_IS_USER_DEFAULT", (isDefaultBrowse r(Intent.ACTION_VIEW) ? 1 : 0)); |
| 1505 if (Versions.feature16Plus) { | 1699 if (Versions.feature16Plus) { |
| 1506 Telemetry.addToHistogram("BROWSER_IS_ASSIST_DEFAULT", (isDefault Browser(Intent.ACTION_ASSIST) ? 1 : 0)); | 1700 Telemetry.addToHistogram("BROWSER_IS_ASSIST_DEFAULT", (isDefault Browser(Intent.ACTION_ASSIST) ? 1 : 0)); |
| 1507 } | 1701 } |
| 1508 } else if ("Updater:Launch".equals(event)) { | 1702 } else if ("Updater:Launch".equals(event)) { |
| 1509 handleUpdaterLaunch(); | 1703 handleUpdaterLaunch(); |
| 1510 | |
| 1511 } else if ("BrowserToolbar:Visibility".equals(event)) { | |
| 1512 setBrowserToolbarVisible(message.getBoolean("visible")); | |
| 1513 | |
| 1514 } else { | 1704 } else { |
| 1515 super.handleMessage(event, message, callback); | 1705 super.handleMessage(event, message, callback); |
| 1516 } | 1706 } |
| 1517 } | 1707 } |
| 1518 | 1708 |
| 1709 private void getFaviconFromCache(final EventCallback callback, final String url) { | |
| 1710 final OnFaviconLoadedListener listener = new OnFaviconLoadedListener() { | |
| 1711 @Override | |
| 1712 public void onFaviconLoaded(final String url, final String faviconUR L, final Bitmap favicon) { | |
| 1713 ThreadUtils.assertOnUiThread(); | |
| 1714 // Convert Bitmap to Base64 data URI in background. | |
| 1715 ThreadUtils.postToBackgroundThread(new Runnable() { | |
| 1716 @Override | |
| 1717 public void run() { | |
| 1718 ByteArrayOutputStream out = null; | |
| 1719 Base64OutputStream b64 = null; | |
| 1720 | |
| 1721 // Failed to load favicon from local. | |
| 1722 if (favicon == null) { | |
| 1723 callback.sendError("Failed to get favicon from cache "); | |
| 1724 } else { | |
| 1725 try { | |
| 1726 out = new ByteArrayOutputStream(); | |
| 1727 out.write("data:image/png;base64,".getBytes()); | |
| 1728 b64 = new Base64OutputStream(out, Base64.NO_WRAP ); | |
| 1729 favicon.compress(Bitmap.CompressFormat.PNG, 100, b64); | |
| 1730 callback.sendSuccess(new String(out.toByteArray( ))); | |
| 1731 } catch (IOException e) { | |
| 1732 Log.w(LOGTAG, "Failed to convert to base64 data URI"); | |
| 1733 callback.sendError("Failed to convert favicon to a base64 data URI"); | |
| 1734 } finally { | |
| 1735 try { | |
| 1736 if (out != null) { | |
| 1737 out.close(); | |
| 1738 } | |
| 1739 if (b64 != null) { | |
| 1740 b64.close(); | |
| 1741 } | |
| 1742 } catch (IOException e) { | |
| 1743 Log.w(LOGTAG, "Failed to close the streams") ; | |
| 1744 } | |
| 1745 } | |
| 1746 } | |
| 1747 } | |
| 1748 }); | |
| 1749 } | |
| 1750 }; | |
| 1751 Favicons.getSizedFaviconForPageFromLocal(getContext(), | |
| 1752 url, | |
| 1753 listener); | |
| 1754 } | |
| 1755 | |
| 1519 /** | 1756 /** |
| 1520 * Use a dummy Intent to do a default browser check. | 1757 * Use a dummy Intent to do a default browser check. |
| 1521 * | 1758 * |
| 1522 * @return true if this package is the default browser on this device, false otherwise. | 1759 * @return true if this package is the default browser on this device, false otherwise. |
| 1523 */ | 1760 */ |
| 1524 private boolean isDefaultBrowser(String action) { | 1761 private boolean isDefaultBrowser(String action) { |
| 1525 final Intent viewIntent = new Intent(action, Uri.parse("http://www.mozil la.org")); | 1762 final Intent viewIntent = new Intent(action, Uri.parse("http://www.mozil la.org")); |
| 1526 final ResolveInfo info = getPackageManager().resolveActivity(viewIntent, PackageManager.MATCH_DEFAULT_ONLY); | 1763 final ResolveInfo info = getPackageManager().resolveActivity(viewIntent, PackageManager.MATCH_DEFAULT_ONLY); |
| 1527 if (info == null) { | 1764 if (info == null) { |
| 1528 // No default is set | 1765 // No default is set |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1696 if (ensureTabsPanelExists()) { | 1933 if (ensureTabsPanelExists()) { |
| 1697 // If we've just inflated the tabs panel, only show it once the curr ent | 1934 // If we've just inflated the tabs panel, only show it once the curr ent |
| 1698 // layout pass is done to avoid displayed temporary UI states during | 1935 // layout pass is done to avoid displayed temporary UI states during |
| 1699 // relayout. | 1936 // relayout. |
| 1700 ViewTreeObserver vto = mTabsPanel.getViewTreeObserver(); | 1937 ViewTreeObserver vto = mTabsPanel.getViewTreeObserver(); |
| 1701 if (vto.isAlive()) { | 1938 if (vto.isAlive()) { |
| 1702 vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayou tListener() { | 1939 vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayou tListener() { |
| 1703 @Override | 1940 @Override |
| 1704 public void onGlobalLayout() { | 1941 public void onGlobalLayout() { |
| 1705 mTabsPanel.getViewTreeObserver().removeGlobalOnLayoutLis tener(this); | 1942 mTabsPanel.getViewTreeObserver().removeGlobalOnLayoutLis tener(this); |
| 1706 mTabsPanel.show(panel); | 1943 showTabs(panel); |
| 1707 } | 1944 } |
| 1708 }); | 1945 }); |
| 1709 } | 1946 } |
| 1710 } else { | 1947 } else { |
| 1948 if (mDoorHangerPopup != null) { | |
| 1949 mDoorHangerPopup.disable(); | |
| 1950 } | |
| 1711 mTabsPanel.show(panel); | 1951 mTabsPanel.show(panel); |
| 1712 } | 1952 } |
| 1713 } | 1953 } |
| 1714 | 1954 |
| 1715 @Override | 1955 @Override |
| 1716 public void hideTabs() { | 1956 public void hideTabs() { |
| 1717 mTabsPanel.hide(); | 1957 mTabsPanel.hide(); |
| 1958 if (mDoorHangerPopup != null) { | |
| 1959 mDoorHangerPopup.enable(); | |
| 1960 } | |
| 1718 } | 1961 } |
| 1719 | 1962 |
| 1720 @Override | 1963 @Override |
| 1721 public boolean autoHideTabs() { | 1964 public boolean autoHideTabs() { |
| 1722 if (areTabsShown()) { | 1965 if (areTabsShown()) { |
| 1723 hideTabs(); | 1966 hideTabs(); |
| 1724 return true; | 1967 return true; |
| 1725 } | 1968 } |
| 1726 return false; | 1969 return false; |
| 1727 } | 1970 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1785 | 2028 |
| 1786 @Override | 2029 @Override |
| 1787 public void onPropertyAnimationStart() { | 2030 public void onPropertyAnimationStart() { |
| 1788 } | 2031 } |
| 1789 | 2032 |
| 1790 @Override | 2033 @Override |
| 1791 public void onPropertyAnimationEnd() { | 2034 public void onPropertyAnimationEnd() { |
| 1792 if (!areTabsShown()) { | 2035 if (!areTabsShown()) { |
| 1793 mTabsPanel.setVisibility(View.INVISIBLE); | 2036 mTabsPanel.setVisibility(View.INVISIBLE); |
| 1794 mTabsPanel.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDAN TS); | 2037 mTabsPanel.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDAN TS); |
| 2038 mRootLayout.setClosed(); | |
| 2039 mBrowserToolbar.setContextMenuEnabled(true); | |
| 1795 } else { | 2040 } else { |
| 1796 // Cancel editing mode to return to page content when the TabsPanel closes. We cancel | 2041 // Cancel editing mode to return to page content when the TabsPanel closes. We cancel |
| 1797 // it here because there are graphical glitches if it's canceled whi le it's visible. | 2042 // it here because there are graphical glitches if it's canceled whi le it's visible. |
| 1798 mBrowserToolbar.cancelEdit(); | 2043 mBrowserToolbar.cancelEdit(); |
| 2044 mRootLayout.setOpen(); | |
| 1799 } | 2045 } |
| 1800 | 2046 |
| 1801 mTabsPanel.finishTabsAnimation(); | 2047 mTabsPanel.finishTabsAnimation(); |
| 1802 | 2048 |
| 1803 mMainLayoutAnimator = null; | 2049 mMainLayoutAnimator = null; |
| 1804 } | 2050 } |
| 1805 | 2051 |
| 1806 @Override | 2052 @Override |
| 1807 public void onSaveInstanceState(Bundle outState) { | 2053 public void onSaveInstanceState(Bundle outState) { |
| 1808 super.onSaveInstanceState(outState); | 2054 super.onSaveInstanceState(outState); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1898 Tabs.getInstance().loadUrl(url, searchEngine, -1, flags); | 2144 Tabs.getInstance().loadUrl(url, searchEngine, -1, flags); |
| 1899 | 2145 |
| 1900 mBrowserToolbar.cancelEdit(); | 2146 mBrowserToolbar.cancelEdit(); |
| 1901 } | 2147 } |
| 1902 | 2148 |
| 1903 private boolean isHomePagerVisible() { | 2149 private boolean isHomePagerVisible() { |
| 1904 return (mHomePager != null && mHomePager.isVisible() | 2150 return (mHomePager != null && mHomePager.isVisible() |
| 1905 && mHomePagerContainer != null && mHomePagerContainer.getVisibility( ) == View.VISIBLE); | 2151 && mHomePagerContainer != null && mHomePagerContainer.getVisibility( ) == View.VISIBLE); |
| 1906 } | 2152 } |
| 1907 | 2153 |
| 2154 private boolean isFirstrunVisible() { | |
| 2155 return (mFirstrunPane != null && mFirstrunPane.isVisible() | |
| 2156 && mHomePagerContainer != null && mHomePagerContainer.getVisibility( ) == View.VISIBLE); | |
| 2157 } | |
| 2158 | |
| 1908 /** | 2159 /** |
| 1909 * Enters editing mode with the current tab's URL. There might be no | 2160 * Enters editing mode with the current tab's URL. There might be no |
| 1910 * tabs loaded by the time the user enters editing mode e.g. just after | 2161 * tabs loaded by the time the user enters editing mode e.g. just after |
| 1911 * the app starts. In this case, we simply fallback to an empty URL. | 2162 * the app starts. In this case, we simply fallback to an empty URL. |
| 1912 */ | 2163 */ |
| 1913 private void enterEditingMode() { | 2164 private void enterEditingMode() { |
| 2165 if (hideFirstrunPager()) { | |
| 2166 Telemetry.sendUIEvent(TelemetryContract.Event.CANCEL, TelemetryContr act.Method.ACTIONBAR, "firstrun-pane"); | |
| 2167 } | |
| 2168 | |
| 1914 String url = ""; | 2169 String url = ""; |
| 1915 | 2170 |
| 1916 final Tab tab = Tabs.getInstance().getSelectedTab(); | 2171 final Tab tab = Tabs.getInstance().getSelectedTab(); |
| 1917 if (tab != null) { | 2172 if (tab != null) { |
| 1918 final String userRequested = tab.getUserRequested(); | 2173 final String userRequested = tab.getUserRequested(); |
| 1919 | 2174 |
| 1920 // Check to see if there's a user-entered search term, | 2175 // Check to see if there's a user-entered search term, |
| 1921 // which we save whenever the user performs a search. | 2176 // which we save whenever the user performs a search. |
| 1922 url = (TextUtils.isEmpty(userRequested) ? tab.getURL() : userRequest ed); | 2177 url = (TextUtils.isEmpty(userRequested) ? tab.getURL() : userRequest ed); |
| 1923 } | 2178 } |
| 1924 | 2179 |
| 1925 enterEditingMode(url); | 2180 enterEditingMode(url); |
| 1926 } | 2181 } |
| 1927 | 2182 |
| 1928 /** | 2183 /** |
| 1929 * Enters editing mode with the specified URL. If a null | 2184 * Enters editing mode with the specified URL. If a null |
| 1930 * url is given, the empty String will be used instead. | 2185 * url is given, the empty String will be used instead. |
| 1931 */ | 2186 */ |
| 1932 private void enterEditingMode(String url) { | 2187 private void enterEditingMode(String url) { |
| 1933 if (url == null) { | 2188 if (url == null) { |
| 1934 url = ""; | 2189 url = ""; |
| 1935 } | 2190 } |
| 1936 | 2191 |
| 1937 if (mBrowserToolbar.isEditing() || mBrowserToolbar.isAnimating()) { | 2192 if (mBrowserToolbar.isEditing() || mBrowserToolbar.isAnimating()) { |
| 1938 return; | 2193 return; |
| 1939 } | 2194 } |
| 1940 | 2195 |
| 1941 final Tab selectedTab = Tabs.getInstance().getSelectedTab(); | 2196 final Tab selectedTab = Tabs.getInstance().getSelectedTab(); |
| 1942 mTargetTabForEditingMode = (selectedTab != null ? selectedTab.getId() : null); | 2197 final String panelId; |
| 2198 if (selectedTab != null) { | |
| 2199 mTargetTabForEditingMode = selectedTab.getId(); | |
| 2200 panelId = selectedTab.getMostRecentHomePanel(); | |
| 2201 } else { | |
| 2202 mTargetTabForEditingMode = null; | |
| 2203 panelId = null; | |
| 2204 } | |
| 1943 | 2205 |
| 1944 final PropertyAnimator animator = new PropertyAnimator(250); | 2206 final PropertyAnimator animator = new PropertyAnimator(250); |
| 1945 animator.setUseHardwareLayer(false); | 2207 animator.setUseHardwareLayer(false); |
| 1946 | 2208 |
| 1947 TransitionsTracker.track(animator); | 2209 TransitionsTracker.track(animator); |
| 1948 | 2210 |
| 1949 mBrowserToolbar.startEditing(url, animator); | 2211 mBrowserToolbar.startEditing(url, animator); |
| 1950 | 2212 |
| 1951 final String panelId = selectedTab.getMostRecentHomePanel(); | |
| 1952 showHomePagerWithAnimator(panelId, animator); | 2213 showHomePagerWithAnimator(panelId, animator); |
| 1953 | 2214 |
| 1954 animator.start(); | 2215 animator.start(); |
| 1955 Telemetry.startUISession(TelemetryContract.Session.AWESOMESCREEN); | 2216 Telemetry.startUISession(TelemetryContract.Session.AWESOMESCREEN); |
| 1956 } | 2217 } |
| 1957 | 2218 |
| 1958 private void commitEditingMode() { | 2219 private void commitEditingMode() { |
| 1959 if (!mBrowserToolbar.isEditing()) { | 2220 if (!mBrowserToolbar.isEditing()) { |
| 1960 return; | 2221 return; |
| 1961 } | 2222 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1987 } | 2248 } |
| 1988 | 2249 |
| 1989 // If the URL doesn't look like a search query, just load it. | 2250 // If the URL doesn't look like a search query, just load it. |
| 1990 if (!StringUtils.isSearchQuery(url, true)) { | 2251 if (!StringUtils.isSearchQuery(url, true)) { |
| 1991 Tabs.getInstance().loadUrl(url, Tabs.LOADURL_USER_ENTERED); | 2252 Tabs.getInstance().loadUrl(url, Tabs.LOADURL_USER_ENTERED); |
| 1992 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryCon tract.Method.ACTIONBAR, "user"); | 2253 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryCon tract.Method.ACTIONBAR, "user"); |
| 1993 return; | 2254 return; |
| 1994 } | 2255 } |
| 1995 | 2256 |
| 1996 // Otherwise, check for a bookmark keyword. | 2257 // Otherwise, check for a bookmark keyword. |
| 2258 final BrowserDB db = getProfile().getDB(); | |
| 1997 ThreadUtils.postToBackgroundThread(new Runnable() { | 2259 ThreadUtils.postToBackgroundThread(new Runnable() { |
| 1998 @Override | 2260 @Override |
| 1999 public void run() { | 2261 public void run() { |
| 2000 final String keyword; | 2262 final String keyword; |
| 2001 final String keywordSearch; | 2263 final String keywordSearch; |
| 2002 | 2264 |
| 2003 final int index = url.indexOf(" "); | 2265 final int index = url.indexOf(" "); |
| 2004 if (index == -1) { | 2266 if (index == -1) { |
| 2005 keyword = url; | 2267 keyword = url; |
| 2006 keywordSearch = ""; | 2268 keywordSearch = ""; |
| 2007 } else { | 2269 } else { |
| 2008 keyword = url.substring(0, index); | 2270 keyword = url.substring(0, index); |
| 2009 keywordSearch = url.substring(index + 1); | 2271 keywordSearch = url.substring(index + 1); |
| 2010 } | 2272 } |
| 2011 | 2273 |
| 2012 final String keywordUrl = BrowserDB.getUrlForKeyword(getContentR esolver(), keyword); | 2274 final String keywordUrl = db.getUrlForKeyword(getContentResolver (), keyword); |
| 2013 | 2275 |
| 2014 // If there isn't a bookmark keyword, load the url. This may res ult in a query | 2276 // If there isn't a bookmark keyword, load the url. This may res ult in a query |
| 2015 // using the default search engine. | 2277 // using the default search engine. |
| 2016 if (TextUtils.isEmpty(keywordUrl)) { | 2278 if (TextUtils.isEmpty(keywordUrl)) { |
| 2017 Tabs.getInstance().loadUrl(url, Tabs.LOADURL_USER_ENTERED); | 2279 Tabs.getInstance().loadUrl(url, Tabs.LOADURL_USER_ENTERED); |
| 2018 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, Tele metryContract.Method.ACTIONBAR, "user"); | 2280 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, Tele metryContract.Method.ACTIONBAR, "user"); |
| 2019 return; | 2281 return; |
| 2020 } | 2282 } |
| 2021 | 2283 |
| 2022 recordSearch(null, "barkeyword"); | 2284 recordSearch(null, "barkeyword"); |
| 2023 | 2285 |
| 2024 // Otherwise, construct a search query from the bookmark keyword . | 2286 // Otherwise, construct a search query from the bookmark keyword . |
| 2025 final String searchUrl = keywordUrl.replace("%s", URLEncoder.enc ode(keywordSearch)); | 2287 // Replace lower case bookmark keywords with URLencoded search q uery or |
| 2288 // replace upper case bookmark keywords with un-encoded search q uery. | |
| 2289 // This makes it match the same behaviour as on Firefox for the desktop. | |
| 2290 final String searchUrl = keywordUrl.replace("%s", URLEncoder.enc ode(keywordSearch)).replace("%S", keywordSearch); | |
| 2291 | |
| 2026 Tabs.getInstance().loadUrl(searchUrl, Tabs.LOADURL_USER_ENTERED) ; | 2292 Tabs.getInstance().loadUrl(searchUrl, Tabs.LOADURL_USER_ENTERED) ; |
| 2027 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, | 2293 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, |
| 2028 TelemetryContract.Method.ACTIONBAR, | 2294 TelemetryContract.Method.ACTIONBAR, |
| 2029 "keyword"); | 2295 "keyword"); |
| 2030 } | 2296 } |
| 2031 }); | 2297 }); |
| 2032 } | 2298 } |
| 2033 | 2299 |
| 2034 /** | 2300 /** |
| 2035 * Record in Health Report that a search has occurred. | 2301 * Record in Health Report that a search has occurred. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2052 Log.e(LOGTAG, "Error recording search.", e); | 2318 Log.e(LOGTAG, "Error recording search.", e); |
| 2053 } | 2319 } |
| 2054 } | 2320 } |
| 2055 | 2321 |
| 2056 /** | 2322 /** |
| 2057 * Store search query in SearchHistoryProvider. | 2323 * Store search query in SearchHistoryProvider. |
| 2058 * | 2324 * |
| 2059 * @param query | 2325 * @param query |
| 2060 * a search query to store. We won't store empty queries. | 2326 * a search query to store. We won't store empty queries. |
| 2061 */ | 2327 */ |
| 2062 private void storeSearchQuery(String query) { | 2328 private void storeSearchQuery(final String query) { |
| 2063 if (TextUtils.isEmpty(query)) { | 2329 if (TextUtils.isEmpty(query)) { |
| 2064 return; | 2330 return; |
| 2065 } | 2331 } |
| 2066 | 2332 |
| 2067 final ContentValues values = new ContentValues(); | 2333 final GeckoProfile profile = getProfile(); |
| 2068 values.put(SearchHistory.QUERY, query); | 2334 // Don't bother storing search queries in guest mode |
| 2335 if (profile.inGuestMode()) { | |
| 2336 return; | |
| 2337 } | |
| 2338 | |
| 2339 final BrowserDB db = profile.getDB(); | |
| 2069 ThreadUtils.postToBackgroundThread(new Runnable() { | 2340 ThreadUtils.postToBackgroundThread(new Runnable() { |
| 2070 @Override | 2341 @Override |
| 2071 public void run() { | 2342 public void run() { |
| 2072 getContentResolver().insert(SearchHistory.CONTENT_URI, values); | 2343 db.getSearches().insert(getContentResolver(), query); |
| 2073 } | 2344 } |
| 2074 }); | 2345 }); |
| 2075 } | 2346 } |
| 2076 | 2347 |
| 2077 void filterEditingMode(String searchTerm, AutocompleteHandler handler) { | 2348 void filterEditingMode(String searchTerm, AutocompleteHandler handler) { |
| 2078 if (TextUtils.isEmpty(searchTerm)) { | 2349 if (TextUtils.isEmpty(searchTerm)) { |
| 2079 hideBrowserSearch(); | 2350 hideBrowserSearch(); |
| 2080 } else { | 2351 } else { |
| 2081 showBrowserSearch(); | 2352 showBrowserSearch(); |
| 2082 mBrowserSearch.filter(searchTerm, handler); | 2353 mBrowserSearch.filter(searchTerm, handler); |
| 2083 } | 2354 } |
| 2084 } | 2355 } |
| 2085 | 2356 |
| 2086 /** | 2357 /** |
| 2087 * Selects the target tab for editing mode. This is expected to be the tab s elected on editing | 2358 * Selects the target tab for editing mode. This is expected to be the tab s elected on editing |
| 2088 * mode entry, unless it is subsequently overridden. | 2359 * mode entry, unless it is subsequently overridden. |
| 2089 * | 2360 * |
| 2090 * A background tab may be selected while editing mode is active (e.g. popup s), causing the | 2361 * A background tab may be selected while editing mode is active (e.g. popup s), causing the |
| 2091 * new url to load in the newly selected tab. Call this method on editing mo de exit to | 2362 * new url to load in the newly selected tab. Call this method on editing mo de exit to |
| 2092 * mitigate this. | 2363 * mitigate this. |
| 2093 * | 2364 * |
| 2094 * Note that this method is disabled for new tablets because we can see the selected tab in the | 2365 * Note that this method is disabled for new tablets because we can see the selected tab in the |
| 2095 * tab strip and, when the selected tab changes during editing mode as in th is hack, the | 2366 * tab strip and, when the selected tab changes during editing mode as in th is hack, the |
| 2096 * temporarily selected tab is visible to users. | 2367 * temporarily selected tab is visible to users. |
| 2097 */ | 2368 */ |
| 2098 private void selectTargetTabForEditingMode() { | 2369 private void selectTargetTabForEditingMode() { |
| 2099 if (NewTabletUI.isEnabled(this)) { | 2370 if (HardwareUtils.isTablet()) { |
| 2100 return; | 2371 return; |
| 2101 } | 2372 } |
| 2102 | 2373 |
| 2103 if (mTargetTabForEditingMode != null) { | 2374 if (mTargetTabForEditingMode != null) { |
| 2104 Tabs.getInstance().selectTab(mTargetTabForEditingMode); | 2375 Tabs.getInstance().selectTab(mTargetTabForEditingMode); |
| 2105 } | 2376 } |
| 2106 | 2377 |
| 2107 mTargetTabForEditingMode = null; | 2378 mTargetTabForEditingMode = null; |
| 2108 } | 2379 } |
| 2109 | 2380 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2170 } | 2441 } |
| 2171 onLocaleChanged(Locales.getLanguageTag(locale)); | 2442 onLocaleChanged(Locales.getLanguageTag(locale)); |
| 2172 } | 2443 } |
| 2173 }); | 2444 }); |
| 2174 break; | 2445 break; |
| 2175 default: | 2446 default: |
| 2176 super.onActivityResult(requestCode, resultCode, data); | 2447 super.onActivityResult(requestCode, resultCode, data); |
| 2177 } | 2448 } |
| 2178 } | 2449 } |
| 2179 | 2450 |
| 2451 private void showFirstrunPager() { | |
|
Felix Dahlke
2015/07/22 16:19:18
Also more for the record, there's a change for re-
| |
| 2452 if (mFirstrunPane == null) { | |
| 2453 final ViewStub firstrunPagerStub = (ViewStub) findViewById(R.id.firs trun_pager_stub); | |
| 2454 mFirstrunPane = (FirstrunPane) firstrunPagerStub.inflate(); | |
| 2455 mFirstrunPane.load(getSupportFragmentManager()); | |
| 2456 mFirstrunPane.registerOnFinishListener(new FirstrunPane.OnFinishList ener() { | |
| 2457 @Override | |
| 2458 public void onFinish() { | |
| 2459 BrowserApp.this.mFirstrunPane = null; | |
| 2460 } | |
| 2461 }); | |
| 2462 } | |
| 2463 | |
| 2464 mHomePagerContainer.setVisibility(View.VISIBLE); | |
| 2465 } | |
| 2466 | |
| 2180 private void showHomePager(String panelId) { | 2467 private void showHomePager(String panelId) { |
| 2181 showHomePagerWithAnimator(panelId, null); | 2468 showHomePagerWithAnimator(panelId, null); |
| 2182 } | 2469 } |
| 2183 | 2470 |
| 2184 private void showHomePagerWithAnimator(String panelId, PropertyAnimator anim ator) { | 2471 private void showHomePagerWithAnimator(String panelId, PropertyAnimator anim ator) { |
| 2185 if (isHomePagerVisible()) { | 2472 if (isHomePagerVisible()) { |
| 2186 // Home pager already visible, make sure it shows the correct panel. | 2473 // Home pager already visible, make sure it shows the correct panel. |
| 2187 mHomePager.showPanel(panelId); | 2474 mHomePager.showPanel(panelId); |
| 2188 return; | 2475 return; |
| 2189 } | 2476 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2257 } | 2544 } |
| 2258 }); | 2545 }); |
| 2259 } | 2546 } |
| 2260 | 2547 |
| 2261 private void hideWebContent() { | 2548 private void hideWebContent() { |
| 2262 // The view is set to INVISIBLE, rather than GONE, to avoid | 2549 // The view is set to INVISIBLE, rather than GONE, to avoid |
| 2263 // the additional requestLayout() call. | 2550 // the additional requestLayout() call. |
| 2264 mLayerView.setVisibility(View.INVISIBLE); | 2551 mLayerView.setVisibility(View.INVISIBLE); |
| 2265 } | 2552 } |
| 2266 | 2553 |
| 2554 public boolean hideFirstrunPager() { | |
| 2555 if (!isFirstrunVisible()) { | |
| 2556 return false; | |
| 2557 } | |
| 2558 | |
| 2559 mFirstrunPane.hide(); | |
| 2560 return true; | |
| 2561 } | |
| 2562 | |
| 2267 /** | 2563 /** |
| 2268 * Hides the HomePager, using the url of the currently selected tab as the u rl to be | 2564 * Hides the HomePager, using the url of the currently selected tab as the u rl to be |
| 2269 * loaded. | 2565 * loaded. |
| 2270 */ | 2566 */ |
| 2271 private void hideHomePager() { | 2567 private void hideHomePager() { |
| 2272 final Tab selectedTab = Tabs.getInstance().getSelectedTab(); | 2568 final Tab selectedTab = Tabs.getInstance().getSelectedTab(); |
| 2273 final String url = (selectedTab != null) ? selectedTab.getURL() : null; | 2569 final String url = (selectedTab != null) ? selectedTab.getURL() : null; |
| 2274 | 2570 |
| 2275 hideHomePager(url); | 2571 hideHomePager(url); |
| 2276 } | 2572 } |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2578 // Add add-on menu items, if any exist. | 2874 // Add add-on menu items, if any exist. |
| 2579 if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) { | 2875 if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) { |
| 2580 for (MenuItemInfo item : mAddonMenuItemsCache) { | 2876 for (MenuItemInfo item : mAddonMenuItemsCache) { |
| 2581 addAddonMenuItemToMenu(mMenu, item); | 2877 addAddonMenuItemToMenu(mMenu, item); |
| 2582 } | 2878 } |
| 2583 } | 2879 } |
| 2584 | 2880 |
| 2585 // Action providers are available only ICS+. | 2881 // Action providers are available only ICS+. |
| 2586 if (Versions.feature14Plus) { | 2882 if (Versions.feature14Plus) { |
| 2587 GeckoMenuItem share = (GeckoMenuItem) mMenu.findItem(R.id.share); | 2883 GeckoMenuItem share = (GeckoMenuItem) mMenu.findItem(R.id.share); |
| 2884 final GeckoMenuItem quickShare = (GeckoMenuItem) mMenu.findItem(R.id .quickshare); | |
| 2885 | |
| 2588 GeckoActionProvider provider = GeckoActionProvider.getForType(GeckoA ctionProvider.DEFAULT_MIME_TYPE, this); | 2886 GeckoActionProvider provider = GeckoActionProvider.getForType(GeckoA ctionProvider.DEFAULT_MIME_TYPE, this); |
| 2887 | |
| 2589 share.setActionProvider(provider); | 2888 share.setActionProvider(provider); |
| 2889 quickShare.setActionProvider(provider); | |
| 2590 } | 2890 } |
| 2591 | 2891 |
| 2592 org.adblockplus.browser.BrowserAppUtils.updateBlockAdsMenuItem( | 2892 org.adblockplus.browser.BrowserAppUtils.updateBlockAdsMenuItem( |
| 2593 mMenu.findItem(R.id.abb_block_ads)); | 2893 mMenu.findItem(R.id.abb_block_ads)); |
| 2594 | 2894 |
| 2595 return true; | 2895 return true; |
| 2596 } | 2896 } |
| 2597 | 2897 |
| 2598 @Override | 2898 @Override |
| 2599 public void openOptionsMenu() { | 2899 public void openOptionsMenu() { |
| 2600 // Disable menu access (for hardware buttons) when the software menu but ton is inaccessible. | 2900 // Disable menu access (for hardware buttons) when the software menu but ton is inaccessible. |
| 2601 // Note that the software button is always accessible on new tablet. | 2901 // Note that the software button is always accessible on new tablet. |
| 2602 if (mBrowserToolbar.isEditing() && !NewTabletUI.isEnabled(this)) { | 2902 if (mBrowserToolbar.isEditing() && !HardwareUtils.isTablet()) { |
| 2603 return; | 2903 return; |
| 2604 } | 2904 } |
| 2605 | 2905 |
| 2606 if (ActivityUtils.isFullScreen(this)) { | 2906 if (ActivityUtils.isFullScreen(this)) { |
| 2607 return; | 2907 return; |
| 2608 } | 2908 } |
| 2609 | 2909 |
| 2610 if (areTabsShown()) { | 2910 if (areTabsShown()) { |
| 2611 mTabsPanel.showMenu(); | 2911 mTabsPanel.showMenu(); |
| 2612 return; | 2912 return; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2666 frag.dismiss(); | 2966 frag.dismiss(); |
| 2667 } | 2967 } |
| 2668 | 2968 |
| 2669 if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { | 2969 if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { |
| 2670 aMenu.findItem(R.id.settings).setEnabled(false); | 2970 aMenu.findItem(R.id.settings).setEnabled(false); |
| 2671 aMenu.findItem(R.id.help).setEnabled(false); | 2971 aMenu.findItem(R.id.help).setEnabled(false); |
| 2672 } | 2972 } |
| 2673 | 2973 |
| 2674 Tab tab = Tabs.getInstance().getSelectedTab(); | 2974 Tab tab = Tabs.getInstance().getSelectedTab(); |
| 2675 MenuItem bookmark = aMenu.findItem(R.id.bookmark); | 2975 MenuItem bookmark = aMenu.findItem(R.id.bookmark); |
| 2976 final MenuItem reader = aMenu.findItem(R.id.reading_list); | |
| 2676 MenuItem back = aMenu.findItem(R.id.back); | 2977 MenuItem back = aMenu.findItem(R.id.back); |
| 2677 MenuItem forward = aMenu.findItem(R.id.forward); | 2978 MenuItem forward = aMenu.findItem(R.id.forward); |
| 2678 MenuItem share = aMenu.findItem(R.id.share); | 2979 MenuItem share = aMenu.findItem(R.id.share); |
| 2980 final MenuItem quickShare = aMenu.findItem(R.id.quickshare); | |
| 2679 MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf); | 2981 MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf); |
| 2680 MenuItem charEncoding = aMenu.findItem(R.id.char_encoding); | 2982 MenuItem charEncoding = aMenu.findItem(R.id.char_encoding); |
| 2681 MenuItem findInPage = aMenu.findItem(R.id.find_in_page); | 2983 MenuItem findInPage = aMenu.findItem(R.id.find_in_page); |
| 2682 MenuItem desktopMode = aMenu.findItem(R.id.desktop_mode); | 2984 MenuItem desktopMode = aMenu.findItem(R.id.desktop_mode); |
| 2683 MenuItem enterGuestMode = aMenu.findItem(R.id.new_guest_session); | 2985 MenuItem enterGuestMode = aMenu.findItem(R.id.new_guest_session); |
| 2684 MenuItem exitGuestMode = aMenu.findItem(R.id.exit_guest_session); | 2986 MenuItem exitGuestMode = aMenu.findItem(R.id.exit_guest_session); |
| 2685 | 2987 |
| 2686 // Only show the "Quit" menu item on pre-ICS, television devices, | 2988 // Only show the "Quit" menu item on pre-ICS, television devices, |
| 2687 // or if the user has explicitly enabled the clear on shutdown pref. | 2989 // or if the user has explicitly enabled the clear on shutdown pref. |
| 2688 // (We check the pref last to save the pref read.) | 2990 // (We check the pref last to save the pref read.) |
| 2689 // In ICS+, it's easy to kill an app through the task switcher. | 2991 // In ICS+, it's easy to kill an app through the task switcher. |
| 2690 final boolean visible = Versions.preICS || | 2992 final boolean visible = Versions.preICS || |
| 2691 HardwareUtils.isTelevision() || | 2993 HardwareUtils.isTelevision() || |
| 2692 !PrefUtils.getStringSet(GeckoSharedPrefs.forProf ile(this), | 2994 !PrefUtils.getStringSet(GeckoSharedPrefs.forProf ile(this), |
| 2693 ClearOnShutdownPref.PREF , | 2995 ClearOnShutdownPref.PREF , |
| 2694 new HashSet<String>()).i sEmpty(); | 2996 new HashSet<String>()).i sEmpty(); |
| 2695 aMenu.findItem(R.id.quit).setVisible(visible); | 2997 aMenu.findItem(R.id.quit).setVisible(visible); |
| 2998 aMenu.findItem(R.id.logins).setVisible(AppConstants.NIGHTLY_BUILD); | |
| 2696 | 2999 |
| 2697 if (tab == null || tab.getURL() == null) { | 3000 if (tab == null || tab.getURL() == null) { |
| 2698 bookmark.setEnabled(false); | 3001 bookmark.setEnabled(false); |
| 3002 reader.setEnabled(false); | |
| 2699 back.setEnabled(false); | 3003 back.setEnabled(false); |
| 2700 forward.setEnabled(false); | 3004 forward.setEnabled(false); |
| 2701 share.setEnabled(false); | 3005 share.setEnabled(false); |
| 3006 quickShare.setEnabled(false); | |
| 2702 saveAsPDF.setEnabled(false); | 3007 saveAsPDF.setEnabled(false); |
| 2703 findInPage.setEnabled(false); | 3008 findInPage.setEnabled(false); |
| 2704 | 3009 |
| 2705 // NOTE: Use MenuUtils.safeSetEnabled because some actions might | 3010 // NOTE: Use MenuUtils.safeSetEnabled because some actions might |
| 2706 // be on the BrowserToolbar context menu. | 3011 // be on the BrowserToolbar context menu. |
| 2707 if (Versions.feature11Plus) { | 3012 if (Versions.feature11Plus) { |
| 2708 // There is no page menu prior to v11 resources. | 3013 // There is no page menu prior to v11 resources. |
| 2709 MenuUtils.safeSetEnabled(aMenu, R.id.page, false); | 3014 MenuUtils.safeSetEnabled(aMenu, R.id.page, false); |
| 2710 } | 3015 } |
| 2711 MenuUtils.safeSetEnabled(aMenu, R.id.subscribe, false); | 3016 MenuUtils.safeSetEnabled(aMenu, R.id.subscribe, false); |
| 2712 MenuUtils.safeSetEnabled(aMenu, R.id.add_search_engine, false); | 3017 MenuUtils.safeSetEnabled(aMenu, R.id.add_search_engine, false); |
| 2713 MenuUtils.safeSetEnabled(aMenu, R.id.site_settings, false); | 3018 MenuUtils.safeSetEnabled(aMenu, R.id.site_settings, false); |
| 2714 MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, false); | 3019 MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, false); |
| 2715 | 3020 |
| 2716 return true; | 3021 return true; |
| 2717 } | 3022 } |
| 2718 | 3023 |
| 2719 bookmark.setEnabled(!AboutPages.isAboutReader(tab.getURL())); | 3024 final boolean inGuestMode = GeckoProfile.get(this).inGuestMode(); |
| 2720 bookmark.setVisible(!GeckoProfile.get(this).inGuestMode()); | 3025 |
| 3026 final boolean isAboutReader = AboutPages.isAboutReader(tab.getURL()); | |
| 3027 bookmark.setEnabled(!isAboutReader); | |
| 3028 bookmark.setVisible(!inGuestMode); | |
| 2721 bookmark.setCheckable(true); | 3029 bookmark.setCheckable(true); |
| 2722 bookmark.setChecked(tab.isBookmark()); | 3030 bookmark.setChecked(tab.isBookmark()); |
| 2723 bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark())); | 3031 bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark())); |
| 3032 bookmark.setTitle(resolveBookmarkTitleID(tab.isBookmark())); | |
| 3033 | |
| 3034 reader.setEnabled(isAboutReader || !AboutPages.isAboutPage(tab.getURL()) ); | |
| 3035 reader.setVisible(!inGuestMode); | |
| 3036 reader.setCheckable(true); | |
| 3037 final boolean isPageInReadingList = tab.isInReadingList(); | |
| 3038 reader.setChecked(isPageInReadingList); | |
| 3039 reader.setIcon(resolveReadingListIconID(isPageInReadingList)); | |
| 3040 reader.setTitle(resolveReadingListTitleID(isPageInReadingList)); | |
| 2724 | 3041 |
| 2725 back.setEnabled(tab.canDoBack()); | 3042 back.setEnabled(tab.canDoBack()); |
| 2726 forward.setEnabled(tab.canDoForward()); | 3043 forward.setEnabled(tab.canDoForward()); |
| 2727 desktopMode.setChecked(tab.getDesktopMode()); | 3044 desktopMode.setChecked(tab.getDesktopMode()); |
| 2728 desktopMode.setIcon(tab.getDesktopMode() ? R.drawable.ic_menu_desktop_mo de_on : R.drawable.ic_menu_desktop_mode_off); | 3045 desktopMode.setIcon(tab.getDesktopMode() ? R.drawable.ic_menu_desktop_mo de_on : R.drawable.ic_menu_desktop_mode_off); |
| 2729 | 3046 |
| 2730 String url = tab.getURL(); | 3047 String url = tab.getURL(); |
| 2731 if (AboutPages.isAboutReader(url)) { | 3048 if (AboutPages.isAboutReader(url)) { |
| 2732 String urlFromReader = ReaderModeUtils.getUrlFromAboutReader(url); | 3049 String urlFromReader = ReaderModeUtils.getUrlFromAboutReader(url); |
| 2733 if (urlFromReader != null) { | 3050 if (urlFromReader != null) { |
| 2734 url = urlFromReader; | 3051 url = urlFromReader; |
| 2735 } | 3052 } |
| 2736 } | 3053 } |
| 2737 | 3054 |
| 2738 // Disable share menuitem for about:, chrome:, file:, and resource: URIs | 3055 // Disable share menuitem for about:, chrome:, file:, and resource: URIs |
| 2739 final boolean shareEnabled = RestrictedProfiles.isAllowed(this, Restrict edProfiles.Restriction.DISALLOW_SHARE); | 3056 final boolean shareVisible = RestrictedProfiles.isAllowed(this, Restrict edProfiles.Restriction.DISALLOW_SHARE); |
| 2740 share.setVisible(shareEnabled); | 3057 share.setVisible(shareVisible); |
| 2741 share.setEnabled(StringUtils.isShareableUrl(url) && shareEnabled); | 3058 final boolean shareEnabled = StringUtils.isShareableUrl(url) && shareVis ible; |
| 3059 share.setEnabled(shareEnabled); | |
| 2742 MenuUtils.safeSetEnabled(aMenu, R.id.apps, RestrictedProfiles.isAllowed( this, RestrictedProfiles.Restriction.DISALLOW_INSTALL_APPS)); | 3060 MenuUtils.safeSetEnabled(aMenu, R.id.apps, RestrictedProfiles.isAllowed( this, RestrictedProfiles.Restriction.DISALLOW_INSTALL_APPS)); |
| 2743 MenuUtils.safeSetEnabled(aMenu, R.id.addons, RestrictedProfiles.isAllowe d(this, RestrictedProfiles.Restriction.DISALLOW_INSTALL_EXTENSION)); | 3061 MenuUtils.safeSetEnabled(aMenu, R.id.addons, RestrictedProfiles.isAllowe d(this, RestrictedProfiles.Restriction.DISALLOW_INSTALL_EXTENSION)); |
| 2744 MenuUtils.safeSetEnabled(aMenu, R.id.downloads, RestrictedProfiles.isAll owed(this, RestrictedProfiles.Restriction.DISALLOW_DOWNLOADS)); | 3062 MenuUtils.safeSetEnabled(aMenu, R.id.downloads, RestrictedProfiles.isAll owed(this, RestrictedProfiles.Restriction.DISALLOW_DOWNLOADS)); |
| 2745 | 3063 |
| 2746 // NOTE: Use MenuUtils.safeSetEnabled because some actions might | 3064 // NOTE: Use MenuUtils.safeSetEnabled because some actions might |
| 2747 // be on the BrowserToolbar context menu. | 3065 // be on the BrowserToolbar context menu. |
| 2748 if (Versions.feature11Plus) { | 3066 if (Versions.feature11Plus) { |
| 2749 MenuUtils.safeSetEnabled(aMenu, R.id.page, !isAboutHome(tab)); | 3067 MenuUtils.safeSetEnabled(aMenu, R.id.page, !isAboutHome(tab)); |
| 2750 } | 3068 } |
| 2751 MenuUtils.safeSetEnabled(aMenu, R.id.subscribe, tab.hasFeeds()); | 3069 MenuUtils.safeSetEnabled(aMenu, R.id.subscribe, tab.hasFeeds()); |
| 2752 MenuUtils.safeSetEnabled(aMenu, R.id.add_search_engine, tab.hasOpenSearc h()); | 3070 MenuUtils.safeSetEnabled(aMenu, R.id.add_search_engine, tab.hasOpenSearc h()); |
| 2753 MenuUtils.safeSetEnabled(aMenu, R.id.site_settings, !isAboutHome(tab)); | 3071 MenuUtils.safeSetEnabled(aMenu, R.id.site_settings, !isAboutHome(tab)); |
| 2754 MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, !isAboutHome(tab)) ; | 3072 MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, !isAboutHome(tab)) ; |
| 2755 | 3073 |
| 2756 // Action providers are available only ICS+. | 3074 // Action providers are available only ICS+. |
| 2757 if (Versions.feature14Plus) { | 3075 if (Versions.feature14Plus) { |
| 3076 quickShare.setVisible(shareVisible); | |
| 3077 quickShare.setEnabled(shareEnabled); | |
| 3078 | |
| 3079 // This provider also applies to the quick share menu item. | |
| 2758 final GeckoActionProvider provider = ((GeckoMenuItem) share).getGeck oActionProvider(); | 3080 final GeckoActionProvider provider = ((GeckoMenuItem) share).getGeck oActionProvider(); |
| 2759 if (provider != null) { | 3081 if (provider != null) { |
| 2760 Intent shareIntent = provider.getIntent(); | 3082 Intent shareIntent = provider.getIntent(); |
| 2761 | 3083 |
| 2762 // For efficiency, the provider's intent is only set once | 3084 // For efficiency, the provider's intent is only set once |
| 2763 if (shareIntent == null) { | 3085 if (shareIntent == null) { |
| 2764 shareIntent = new Intent(Intent.ACTION_SEND); | 3086 shareIntent = new Intent(Intent.ACTION_SEND); |
| 2765 shareIntent.setType("text/plain"); | 3087 shareIntent.setType("text/plain"); |
| 2766 provider.setIntent(shareIntent); | 3088 provider.setIntent(shareIntent); |
| 2767 } | 3089 } |
| 2768 | 3090 |
| 2769 // Replace the existing intent's extras | 3091 // Replace the existing intent's extras |
| 2770 shareIntent.putExtra(Intent.EXTRA_TEXT, url); | 3092 shareIntent.putExtra(Intent.EXTRA_TEXT, url); |
| 2771 shareIntent.putExtra(Intent.EXTRA_SUBJECT, tab.getDisplayTitle() ); | 3093 shareIntent.putExtra(Intent.EXTRA_SUBJECT, tab.getDisplayTitle() ); |
| 2772 shareIntent.putExtra(Intent.EXTRA_TITLE, tab.getDisplayTitle()); | 3094 shareIntent.putExtra(Intent.EXTRA_TITLE, tab.getDisplayTitle()); |
| 3095 shareIntent.putExtra(ShareDialog.INTENT_EXTRA_DEVICES_ONLY, true ); | |
| 2773 | 3096 |
| 2774 // Clear the existing thumbnail extras so we don't share an old thumbnail. | 3097 // Clear the existing thumbnail extras so we don't share an old thumbnail. |
| 2775 shareIntent.removeExtra("share_screenshot_uri"); | 3098 shareIntent.removeExtra("share_screenshot_uri"); |
| 2776 | 3099 |
| 2777 // Include the thumbnail of the page being shared. | 3100 // Include the thumbnail of the page being shared. |
| 2778 BitmapDrawable drawable = tab.getThumbnail(); | 3101 BitmapDrawable drawable = tab.getThumbnail(); |
| 2779 if (drawable != null) { | 3102 if (drawable != null) { |
| 2780 Bitmap thumbnail = drawable.getBitmap(); | 3103 Bitmap thumbnail = drawable.getBitmap(); |
| 2781 | 3104 |
| 2782 // Kobo uses a custom intent extra for sharing thumbnails. | 3105 // Kobo uses a custom intent extra for sharing thumbnails. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2828 } | 3151 } |
| 2829 } | 3152 } |
| 2830 | 3153 |
| 2831 if (isBookmark) { | 3154 if (isBookmark) { |
| 2832 return R.drawable.ic_menu_bookmark_remove; | 3155 return R.drawable.ic_menu_bookmark_remove; |
| 2833 } else { | 3156 } else { |
| 2834 return R.drawable.ic_menu_bookmark_add; | 3157 return R.drawable.ic_menu_bookmark_add; |
| 2835 } | 3158 } |
| 2836 } | 3159 } |
| 2837 | 3160 |
| 3161 private int resolveBookmarkTitleID(final boolean isBookmark) { | |
| 3162 return (isBookmark ? R.string.bookmark_remove : R.string.bookmark); | |
| 3163 } | |
| 3164 | |
| 3165 private int resolveReadingListIconID(final boolean isInReadingList) { | |
| 3166 return (isInReadingList ? R.drawable.ic_menu_reader_remove : R.drawable. ic_menu_reader_add); | |
| 3167 } | |
| 3168 | |
| 3169 private int resolveReadingListTitleID(final boolean isInReadingList) { | |
| 3170 return (isInReadingList ? R.string.reading_list_remove : R.string.overla y_share_reading_list_btn_label); | |
| 3171 } | |
| 3172 | |
| 2838 @Override | 3173 @Override |
| 2839 public boolean onOptionsItemSelected(MenuItem item) { | 3174 public boolean onOptionsItemSelected(MenuItem item) { |
| 2840 Tab tab = null; | 3175 Tab tab = null; |
| 2841 Intent intent = null; | 3176 Intent intent = null; |
| 2842 | 3177 |
| 2843 final int itemId = item.getItemId(); | 3178 final int itemId = item.getItemId(); |
| 2844 | 3179 |
| 2845 // Track the menu action. We don't know much about the context, but we c an use this to determine | 3180 // Track the menu action. We don't know much about the context, but we c an use this to determine |
| 2846 // the frequency of use for various actions. | 3181 // the frequency of use for various actions. |
| 2847 Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract. Method.MENU, getResources().getResourceEntryName(itemId)); | 3182 Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract. Method.MENU, getResources().getResourceEntryName(itemId)); |
| 2848 | 3183 |
| 2849 if (NewTabletUI.isEnabled(this)) { | 3184 if (NewTabletUI.isEnabled(this)) { |
| 2850 mBrowserToolbar.cancelEdit(); | 3185 mBrowserToolbar.cancelEdit(); |
| 2851 } | 3186 } |
| 2852 | 3187 |
| 2853 if (itemId == R.id.bookmark) { | 3188 if (itemId == R.id.bookmark) { |
| 2854 tab = Tabs.getInstance().getSelectedTab(); | 3189 tab = Tabs.getInstance().getSelectedTab(); |
| 2855 if (tab != null) { | 3190 if (tab != null) { |
| 2856 if (item.isChecked()) { | 3191 if (item.isChecked()) { |
| 2857 Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, Teleme tryContract.Method.MENU, "bookmark"); | 3192 Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, Teleme tryContract.Method.MENU, "bookmark"); |
| 2858 tab.removeBookmark(); | 3193 tab.removeBookmark(); |
| 2859 item.setIcon(resolveBookmarkIconID(false)); | 3194 item.setIcon(resolveBookmarkIconID(false)); |
| 3195 item.setTitle(resolveBookmarkTitleID(false)); | |
| 2860 } else { | 3196 } else { |
| 2861 Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, Telemetr yContract.Method.MENU, "bookmark"); | 3197 Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, Telemetr yContract.Method.MENU, "bookmark"); |
| 2862 tab.addBookmark(); | 3198 tab.addBookmark(); |
| 2863 item.setIcon(resolveBookmarkIconID(true)); | 3199 item.setIcon(resolveBookmarkIconID(true)); |
| 3200 item.setTitle(resolveBookmarkTitleID(true)); | |
| 2864 } | 3201 } |
| 2865 } | 3202 } |
| 2866 return true; | 3203 return true; |
| 3204 } | |
| 3205 | |
| 3206 if (itemId == R.id.reading_list) { | |
| 3207 tab = Tabs.getInstance().getSelectedTab(); | |
| 3208 if (tab != null) { | |
| 3209 if (item.isChecked()) { | |
| 3210 Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, Teleme tryContract.Method.MENU, "reading_list"); | |
| 3211 tab.removeFromReadingList(); | |
| 3212 item.setIcon(resolveReadingListIconID(false)); | |
| 3213 item.setTitle(resolveReadingListTitleID(false)); | |
| 3214 } else { | |
| 3215 Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, Telemetr yContract.Method.MENU, "reading_list"); | |
| 3216 tab.addToReadingList(); | |
| 3217 item.setIcon(resolveReadingListIconID(true)); | |
| 3218 item.setTitle(resolveReadingListTitleID(true)); | |
| 3219 } | |
| 3220 } | |
| 3221 return true; | |
| 2867 } | 3222 } |
| 2868 | 3223 |
| 2869 if (itemId == R.id.share) { | 3224 if (itemId == R.id.share) { |
| 2870 shareCurrentUrl(); | 3225 shareCurrentUrl(); |
| 2871 return true; | 3226 return true; |
| 2872 } | 3227 } |
| 2873 | 3228 |
| 2874 if (itemId == R.id.reload) { | 3229 if (itemId == R.id.reload) { |
| 2875 tab = Tabs.getInstance().getSelectedTab(); | 3230 tab = Tabs.getInstance().getSelectedTab(); |
| 2876 if (tab != null) | 3231 if (tab != null) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2914 final String URL = getResources().getString(R.string.help_link, VERS ION, OS, LOCALE); | 3269 final String URL = getResources().getString(R.string.help_link, VERS ION, OS, LOCALE); |
| 2915 Tabs.getInstance().loadUrlInTab(URL); | 3270 Tabs.getInstance().loadUrlInTab(URL); |
| 2916 return true; | 3271 return true; |
| 2917 } | 3272 } |
| 2918 | 3273 |
| 2919 if (itemId == R.id.addons) { | 3274 if (itemId == R.id.addons) { |
| 2920 Tabs.getInstance().loadUrlInTab(AboutPages.ADDONS); | 3275 Tabs.getInstance().loadUrlInTab(AboutPages.ADDONS); |
| 2921 return true; | 3276 return true; |
| 2922 } | 3277 } |
| 2923 | 3278 |
| 3279 if (itemId == R.id.logins) { | |
| 3280 Tabs.getInstance().loadUrlInTab(AboutPages.PASSWORDS); | |
| 3281 return true; | |
| 3282 } | |
| 3283 | |
| 2924 if (itemId == R.id.apps) { | 3284 if (itemId == R.id.apps) { |
| 2925 Tabs.getInstance().loadUrlInTab(AboutPages.APPS); | 3285 Tabs.getInstance().loadUrlInTab(AboutPages.APPS); |
| 2926 return true; | 3286 return true; |
| 2927 } | 3287 } |
| 2928 | 3288 |
| 2929 if (itemId == R.id.downloads) { | 3289 if (itemId == R.id.downloads) { |
| 2930 Tabs.getInstance().loadUrlInTab(AboutPages.DOWNLOADS); | 3290 Tabs.getInstance().loadUrlInTab(AboutPages.DOWNLOADS); |
| 2931 return true; | 3291 return true; |
| 2932 } | 3292 } |
| 2933 | 3293 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3059 /* | 3419 /* |
| 3060 * If the app has been launched a certain number of times, and we haven't as ked for feedback before, | 3420 * If the app has been launched a certain number of times, and we haven't as ked for feedback before, |
| 3061 * open a new tab with about:feedback when launching the app from the icon s hortcut. | 3421 * open a new tab with about:feedback when launching the app from the icon s hortcut. |
| 3062 */ | 3422 */ |
| 3063 @Override | 3423 @Override |
| 3064 protected void onNewIntent(Intent intent) { | 3424 protected void onNewIntent(Intent intent) { |
| 3065 String action = intent.getAction(); | 3425 String action = intent.getAction(); |
| 3066 | 3426 |
| 3067 final boolean isViewAction = Intent.ACTION_VIEW.equals(action); | 3427 final boolean isViewAction = Intent.ACTION_VIEW.equals(action); |
| 3068 final boolean isBookmarkAction = GeckoApp.ACTION_HOMESCREEN_SHORTCUT.equ als(action); | 3428 final boolean isBookmarkAction = GeckoApp.ACTION_HOMESCREEN_SHORTCUT.equ als(action); |
| 3429 final boolean isTabQueueAction = TabQueueHelper.LOAD_URLS_ACTION.equals( action); | |
| 3069 | 3430 |
| 3070 if (mInitialized && (isViewAction || isBookmarkAction)) { | 3431 if (mInitialized && (isViewAction || isBookmarkAction)) { |
| 3071 // Dismiss editing mode if the user is loading a URL from an externa l app. | 3432 // Dismiss editing mode if the user is loading a URL from an externa l app. |
| 3072 mBrowserToolbar.cancelEdit(); | 3433 mBrowserToolbar.cancelEdit(); |
| 3073 | 3434 |
| 3435 // Hide firstrun-pane if the user is loading a URL from an external app. | |
| 3436 hideFirstrunPager(); | |
| 3437 | |
| 3074 // GeckoApp.ACTION_HOMESCREEN_SHORTCUT means we're opening a bookmar k that | 3438 // GeckoApp.ACTION_HOMESCREEN_SHORTCUT means we're opening a bookmar k that |
| 3075 // was added to Android's homescreen. | 3439 // was added to Android's homescreen. |
| 3076 final TelemetryContract.Method method = | 3440 final TelemetryContract.Method method = |
| 3077 (isViewAction ? TelemetryContract.Method.INTENT : TelemetryContr act.Method.HOMESCREEN); | 3441 (isViewAction ? TelemetryContract.Method.INTENT : TelemetryContr act.Method.HOMESCREEN); |
| 3078 | 3442 |
| 3079 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, method); | 3443 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, method); |
| 3080 } | 3444 } |
| 3081 | 3445 |
| 3082 super.onNewIntent(intent); | 3446 super.onNewIntent(intent); |
| 3083 | 3447 |
| 3084 if (AppConstants.MOZ_ANDROID_BEAM && NfcAdapter.ACTION_NDEF_DISCOVERED.e quals(action)) { | 3448 if (AppConstants.MOZ_ANDROID_BEAM && NfcAdapter.ACTION_NDEF_DISCOVERED.e quals(action)) { |
| 3085 String uri = intent.getDataString(); | 3449 String uri = intent.getDataString(); |
| 3086 GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(uri)); | 3450 GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(uri)); |
| 3087 } | 3451 } |
| 3088 | 3452 |
| 3089 // Only solicit feedback when the app has been launched from the icon sh ortcut. | 3453 // Only solicit feedback when the app has been launched from the icon sh ortcut. |
| 3090 if (GuestSession.NOTIFICATION_INTENT.equals(action)) { | 3454 if (GuestSession.NOTIFICATION_INTENT.equals(action)) { |
| 3091 GuestSession.handleIntent(this, intent); | 3455 GuestSession.handleIntent(this, intent); |
| 3092 } | 3456 } |
| 3093 | 3457 |
| 3458 // If the user has clicked the tab queue notification then load the tabs . | |
| 3459 if(AppConstants.NIGHTLY_BUILD && AppConstants.MOZ_ANDROID_TAB_QUEUE && mInitialized && isTabQueueAction) { | |
| 3460 int queuedTabCount = TabQueueHelper.getTabQueueLength(this); | |
| 3461 TabQueueHelper.openQueuedUrls(this, mProfile, TabQueueHelper.FILE_NA ME); | |
| 3462 | |
| 3463 // If there's more than one tab then also show the tabs panel. | |
| 3464 if (queuedTabCount > 1) { | |
| 3465 showNormalTabs(); | |
| 3466 } | |
| 3467 } | |
| 3468 | |
| 3094 if (!mInitialized || !Intent.ACTION_MAIN.equals(action)) { | 3469 if (!mInitialized || !Intent.ACTION_MAIN.equals(action)) { |
| 3095 return; | 3470 return; |
| 3096 } | 3471 } |
| 3097 | 3472 |
| 3098 // Check to see how many times the app has been launched. | 3473 // Check to see how many times the app has been launched. |
| 3099 final String keyName = getPackageName() + ".feedback_launch_count"; | 3474 final String keyName = getPackageName() + ".feedback_launch_count"; |
| 3100 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskRe ads(); | 3475 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskRe ads(); |
| 3101 | 3476 |
| 3102 // Faster on main thread with an async apply(). | 3477 // Faster on main thread with an async apply(). |
| 3103 try { | 3478 try { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 3124 // Fennec alive during downloads. | 3499 // Fennec alive during downloads. |
| 3125 return new ServiceNotificationClient(getApplicationContext()); | 3500 return new ServiceNotificationClient(getApplicationContext()); |
| 3126 } | 3501 } |
| 3127 | 3502 |
| 3128 private void resetFeedbackLaunchCount() { | 3503 private void resetFeedbackLaunchCount() { |
| 3129 SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); | 3504 SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); |
| 3130 settings.edit().putInt(getPackageName() + ".feedback_launch_count", 0).a pply(); | 3505 settings.edit().putInt(getPackageName() + ".feedback_launch_count", 0).a pply(); |
| 3131 } | 3506 } |
| 3132 | 3507 |
| 3133 private void getLastUrl(final EventCallback callback) { | 3508 private void getLastUrl(final EventCallback callback) { |
| 3509 final BrowserDB db = getProfile().getDB(); | |
| 3134 (new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler( )) { | 3510 (new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler( )) { |
| 3135 @Override | 3511 @Override |
| 3136 public synchronized String doInBackground() { | 3512 public synchronized String doInBackground() { |
| 3137 // Get the most recent URL stored in browser history. | 3513 // Get the most recent URL stored in browser history. |
| 3138 String url = ""; | 3514 final Cursor c = db.getRecentHistory(getContentResolver(), 1); |
| 3139 Cursor c = null; | 3515 if (c == null) { |
| 3516 return ""; | |
| 3517 } | |
| 3140 try { | 3518 try { |
| 3141 c = BrowserDB.getRecentHistory(getContentResolver(), 1); | |
| 3142 if (c.moveToFirst()) { | 3519 if (c.moveToFirst()) { |
| 3143 url = c.getString(c.getColumnIndexOrThrow(Combined.URL)) ; | 3520 return c.getString(c.getColumnIndexOrThrow(Combined.URL) ); |
| 3144 } | 3521 } |
| 3522 return ""; | |
| 3145 } finally { | 3523 } finally { |
| 3146 if (c != null) | 3524 c.close(); |
| 3147 c.close(); | |
| 3148 } | 3525 } |
| 3149 return url; | |
| 3150 } | 3526 } |
| 3151 | 3527 |
| 3152 @Override | 3528 @Override |
| 3153 public void onPostExecute(String url) { | 3529 public void onPostExecute(String url) { |
| 3154 callback.sendSuccess(url); | 3530 callback.sendSuccess(url); |
| 3155 } | 3531 } |
| 3156 }).execute(); | 3532 }).execute(); |
| 3157 } | 3533 } |
| 3158 | 3534 |
| 3159 // HomePager.OnUrlOpenListener | 3535 // HomePager.OnUrlOpenListener |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3235 } | 3611 } |
| 3236 | 3612 |
| 3237 @Override | 3613 @Override |
| 3238 public int getLayout() { return R.layout.gecko_app; } | 3614 public int getLayout() { return R.layout.gecko_app; } |
| 3239 | 3615 |
| 3240 @Override | 3616 @Override |
| 3241 protected String getDefaultProfileName() throws NoMozillaDirectoryException { | 3617 protected String getDefaultProfileName() throws NoMozillaDirectoryException { |
| 3242 return GeckoProfile.getDefaultProfileName(this); | 3618 return GeckoProfile.getDefaultProfileName(this); |
| 3243 } | 3619 } |
| 3244 | 3620 |
| 3621 // For use from tests only. | |
| 3622 @RobocopTarget | |
| 3623 public ReadingListHelper getReadingListHelper() { | |
| 3624 return mReadingListHelper; | |
| 3625 } | |
| 3626 | |
| 3245 /** | 3627 /** |
| 3246 * Launch UI that lets the user update Firefox. | 3628 * Launch UI that lets the user update Firefox. |
| 3247 * | 3629 * |
| 3248 * This depends on the current channel: Release and Beta both direct to the | 3630 * This depends on the current channel: Release and Beta both direct to the |
| 3249 * Google Play Store. If updating is enabled, Aurora, Nightly, and custom | 3631 * Google Play Store. If updating is enabled, Aurora, Nightly, and custom |
| 3250 * builds open about:, which provides an update interface. | 3632 * builds open about:, which provides an update interface. |
| 3251 * | 3633 * |
| 3252 * If updating is not enabled, this simply logs an error. | 3634 * If updating is not enabled, this simply logs an error. |
| 3253 * | 3635 * |
| 3254 * @return true if update UI was launched. | 3636 * @return true if update UI was launched. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3334 dispatcher, | 3716 dispatcher, |
| 3335 osLocale, | 3717 osLocale, |
| 3336 appLocale, | 3718 appLocale, |
| 3337 previousSession); | 3719 previousSession); |
| 3338 } | 3720 } |
| 3339 | 3721 |
| 3340 public static interface Refreshable { | 3722 public static interface Refreshable { |
| 3341 public void refresh(); | 3723 public void refresh(); |
| 3342 } | 3724 } |
| 3343 } | 3725 } |
| OLD | NEW |