Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: mobile/android/base/BrowserApp.java

Issue 29322687: Issue 2807 - MOBILE3901_2015070622_RELBRANCH merge conflicts (Closed)
Patch Set: Created July 20, 2015, 4:53 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld