mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
Merge fx-team to m-c. a=merge
This commit is contained in:
commit
c7aa4e5782
@ -489,6 +489,7 @@
|
||||
@BINPATH@/components/nsInputListAutoComplete.js
|
||||
@BINPATH@/components/formautofill.manifest
|
||||
@BINPATH@/components/FormAutofillContentService.js
|
||||
@BINPATH@/components/FormAutofillStartup.js
|
||||
@BINPATH@/components/contentSecurityPolicy.manifest
|
||||
@BINPATH@/components/contentSecurityPolicy.js
|
||||
@BINPATH@/components/contentAreaDropListener.manifest
|
||||
|
@ -917,22 +917,6 @@
|
||||
cui-areatype="toolbar"
|
||||
aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
|
||||
|
||||
<!-- XXX Bug 1013989 will provide a label for the button -->
|
||||
<!-- This uses badged to be compatible with the social api code it shares.
|
||||
We may also want it to be badged in the future, for notification
|
||||
purposes. -->
|
||||
<toolbarbutton id="loop-call-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
persist="class"
|
||||
type="badged"
|
||||
removable="true"
|
||||
tooltiptext="&loopCallButton.tooltip;"
|
||||
oncommand="LoopUI.openCallPanel(event);"
|
||||
cui-areatype="toolbar"
|
||||
>
|
||||
</toolbarbutton>
|
||||
|
||||
|
||||
<toolbarbutton id="social-share-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&sharePageCmd.label;"
|
||||
|
@ -52,7 +52,7 @@ const kSubviewEvents = [
|
||||
* The current version. We can use this to auto-add new default widgets as necessary.
|
||||
* (would be const but isn't because of testing purposes)
|
||||
*/
|
||||
let kVersion = 0;
|
||||
let kVersion = 1;
|
||||
|
||||
/**
|
||||
* gPalette is a map of every widget that CustomizableUI.jsm knows about, keyed
|
||||
|
@ -898,6 +898,28 @@ const CustomizableWidgets = [{
|
||||
let win = aEvent.view;
|
||||
win.MailIntegration.sendLinkForWindow(win.content);
|
||||
}
|
||||
}, {
|
||||
id: "loop-call-button",
|
||||
type: "custom",
|
||||
// XXX Bug 1013989 will provide a label for the button
|
||||
label: "loop-call-button.label",
|
||||
tooltiptext: "loop-call-button.tooltiptext",
|
||||
defaultArea: CustomizableUI.AREA_NAVBAR,
|
||||
introducedInVersion: 1,
|
||||
onBuild: function(aDocument) {
|
||||
let node = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
node.setAttribute("id", this.id);
|
||||
node.classList.add("toolbarbutton-1");
|
||||
node.classList.add("chromeclass-toolbar-additional");
|
||||
node.setAttribute("type", "badged");
|
||||
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
||||
node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
||||
node.setAttribute("removable", "true");
|
||||
node.addEventListener("command", function(event) {
|
||||
aDocument.defaultView.LoopUI.openCallPanel(event);
|
||||
});
|
||||
return node;
|
||||
}
|
||||
}];
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -83,19 +83,19 @@ function updateUI() {
|
||||
document.querySelector("#type").classList.remove("hidden");
|
||||
|
||||
if (project.type == "runtimeApp") {
|
||||
let manifest = AppManager.getProjectManifestURL(project);
|
||||
let manifestURL = AppManager.getProjectManifestURL(project);
|
||||
document.querySelector("#type").textContent = manifest.type || "web";
|
||||
document.querySelector("#manifestURLHeader").classList.remove("hidden");
|
||||
document.querySelector("#manifestURL").textContent = manifest;
|
||||
document.querySelector("#manifestURL").textContent = manifestURL;
|
||||
} else {
|
||||
document.querySelector("#type").textContent = project.type + " " + (manifest.type || "web");
|
||||
}
|
||||
|
||||
if (project.type == "packaged") {
|
||||
let manifest = AppManager.getProjectManifestURL(project);
|
||||
if (manifest) {
|
||||
let manifestURL = AppManager.getProjectManifestURL(project);
|
||||
if (manifestURL) {
|
||||
document.querySelector("#manifestURLHeader").classList.remove("hidden");
|
||||
document.querySelector("#manifestURL").textContent = manifest;
|
||||
document.querySelector("#manifestURL").textContent = manifestURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,16 @@
|
||||
<h2>&prefs_editor_title;</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<label><span>&prefs_options_keybindings;</span>
|
||||
<select data-pref="devtools.editor.keymap">
|
||||
<option value="default">&prefs_options_keybindings_default;</option>
|
||||
<option value="vim">Vim</option>
|
||||
<option value="emacs">Emacs</option>
|
||||
<option value="sublime">Sublime</option>
|
||||
</select>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label><span>&prefs_options_tabsize;</span>
|
||||
<select data-pref="devtools.editor.tabsize">
|
||||
|
@ -632,7 +632,7 @@ let UI = {
|
||||
splitter.removeAttribute("hidden");
|
||||
|
||||
let iframe = document.createElement("iframe");
|
||||
document.querySelector("window").insertBefore(iframe, splitter.nextSibling);
|
||||
document.querySelector("notificationbox").insertBefore(iframe, splitter.nextSibling);
|
||||
let host = devtools.Toolbox.HostType.CUSTOM;
|
||||
let options = { customIframe: iframe };
|
||||
this.toolboxIframe = iframe;
|
||||
|
@ -181,10 +181,9 @@
|
||||
<iframe id="deck-panel-runtimedetails" flex="1" src="runtimedetails.xhtml"/>
|
||||
<iframe id="deck-panel-monitor" flex="1" lazysrc="monitor.xhtml"/>
|
||||
</deck>
|
||||
<splitter hidden="true" class="devtools-horizontal-splitter" orient="vertical"/>
|
||||
<!-- toolbox iframe will be inserted here -->
|
||||
</notificationbox>
|
||||
|
||||
<splitter hidden="true" class="devtools-horizontal-splitter" orient="vertical"/>
|
||||
|
||||
<!-- toolbox iframe will be inserted here -->
|
||||
|
||||
</window>
|
||||
|
@ -117,6 +117,8 @@
|
||||
<!ENTITY prefs_options_autocomplete_tooltip "Enable code autocompletion">
|
||||
<!ENTITY prefs_options_autoclosebrackets "Autoclose brackets">
|
||||
<!ENTITY prefs_options_autoclosebrackets_tooltip "Automatically insert closing brackets">
|
||||
<!ENTITY prefs_options_keybindings "Keybindings">
|
||||
<!ENTITY prefs_options_keybindings_default "Default">
|
||||
|
||||
<!-- Permissions Table -->
|
||||
<!ENTITY permissionstable_title "Permissions Table">
|
||||
|
@ -451,6 +451,7 @@
|
||||
@BINPATH@/components/nsInputListAutoComplete.js
|
||||
@BINPATH@/components/formautofill.manifest
|
||||
@BINPATH@/components/FormAutofillContentService.js
|
||||
@BINPATH@/components/FormAutofillStartup.js
|
||||
@BINPATH@/components/contentSecurityPolicy.manifest
|
||||
@BINPATH@/components/contentSecurityPolicy.js
|
||||
@BINPATH@/components/contentAreaDropListener.manifest
|
||||
|
@ -715,8 +715,6 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
||||
<!ENTITY getUserMedia.selectMicrophone.accesskey "M">
|
||||
<!ENTITY getUserMedia.allWindowsShared.message "All visible windows on your screen will be shared.">
|
||||
|
||||
<!ENTITY loopCallButton.tooltip "Invite someone to talk">
|
||||
|
||||
<!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">
|
||||
|
||||
<!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">
|
||||
|
@ -96,3 +96,6 @@ quit-button.tooltiptext.linux2 = Quit %1$S (%2$S)
|
||||
# LOCALIZATION NOTE(quit-button.tooltiptext.mac): %1$S is the brand name (e.g. Firefox),
|
||||
# %2$S is the keyboard shortcut
|
||||
quit-button.tooltiptext.mac = Quit %1$S (%2$S)
|
||||
|
||||
loop-call-button.label = Invite someone to talk
|
||||
loop-call-button.tooltiptext = Invite someone to talk
|
||||
|
@ -14,6 +14,8 @@ skip-if = buildapp == 'mulet'
|
||||
[test_bug477754.xul]
|
||||
[test_bug703150.xul]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_bug987230.xul]
|
||||
skip-if = os == 'linux' # No native mousedown event
|
||||
[test_popupSizeTo.xul]
|
||||
[test_resizer.xul]
|
||||
[test_stack.xul]
|
||||
|
115
layout/xul/test/test_bug987230.xul
Normal file
115
layout/xul/test/test_bug987230.xul
Normal file
@ -0,0 +1,115 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=987230
|
||||
-->
|
||||
<window title="Mozilla Bug 987230"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="SimpleTest.waitForFocus(nextTest, window)">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=987230"
|
||||
target="_blank">Mozilla Bug 987230</a>
|
||||
</body>
|
||||
|
||||
<vbox>
|
||||
<toolbar>
|
||||
<toolbarbutton id="toolbarbutton-anchor"
|
||||
label="Anchor"
|
||||
consumeanchor="toolbarbutton-anchor"
|
||||
onclick="onAnchorClick(event)"
|
||||
style="padding: 50px !important; list-style-image: url(chrome://branding/content/icon32.png)"/>
|
||||
</toolbar>
|
||||
<spacer flex="1"/>
|
||||
<hbox id="hbox-anchor"
|
||||
style="padding: 20px"
|
||||
onclick="onAnchorClick(event)">
|
||||
<hbox id="inner-anchor"
|
||||
consumeanchor="hbox-anchor"
|
||||
>
|
||||
Another anchor
|
||||
</hbox>
|
||||
</hbox>
|
||||
<spacer flex="1"/>
|
||||
</vbox>
|
||||
|
||||
<panel id="mypopup"
|
||||
type="arrow"
|
||||
onpopupshown="onMyPopupShown(event)"
|
||||
onpopuphidden="onMyPopupHidden(event)">This is a test popup</panel>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 987230 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
|
||||
let platform = navigator.platform.toLowerCase();
|
||||
let isWindows = platform.startsWith("win");
|
||||
let mouseDown = isWindows ? 2 : 1;
|
||||
let mouseUp = isWindows ? 4 : 2;
|
||||
let mouseMove = isWindows ? 1 : 5;
|
||||
let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
let scale = utils.screenPixelsPerCSSPixel;
|
||||
|
||||
|
||||
function synthesizeNativeMouseClick(aElement, aOffsetX, aOffsetY) {
|
||||
let rect = aElement.getBoundingClientRect();
|
||||
let win = aElement.ownerDocument.defaultView;
|
||||
let x = aOffsetX + win.mozInnerScreenX + rect.left;
|
||||
let y = aOffsetY + win.mozInnerScreenY + rect.top;
|
||||
|
||||
utils.sendNativeMouseEvent(x * scale, y * scale, mouseDown, 0, null);
|
||||
utils.sendNativeMouseEvent(x * scale, y * scale, mouseUp, 0, null);
|
||||
}
|
||||
|
||||
function onMyPopupHidden(e) {
|
||||
ok(true, "Popup hidden");
|
||||
if (outerAnchor.id == "toolbarbutton-anchor") {
|
||||
popupHasShown = false;
|
||||
outerAnchor = document.getElementById("hbox-anchor");
|
||||
anchor = document.getElementById("inner-anchor");
|
||||
nextTest();
|
||||
} else {
|
||||
//XXXgijs set mouse position back outside the iframe:
|
||||
let frameRect = window.frameElement.getBoundingClientRect();
|
||||
let outsideOfFrameX = (window.mozInnerScreenX + frameRect.width + 100) * scale;
|
||||
let outsideOfFrameY = Math.max(0, window.mozInnerScreenY - 100) * scale;
|
||||
|
||||
utils.sendNativeMouseEvent(outsideOfFrameX, outsideOfFrameY, mouseMove, 0, null);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
let popupHasShown = false;
|
||||
function onMyPopupShown(e) {
|
||||
popupHasShown = true;
|
||||
synthesizeNativeMouseClick(outerAnchor, 5, 5);
|
||||
}
|
||||
|
||||
function onAnchorClick(e) {
|
||||
info("click: " + e.target.id);
|
||||
ok(!popupHasShown, "Popup should only be shown once");
|
||||
popup.openPopup(anchor, "bottomcenter topright");
|
||||
}
|
||||
|
||||
let popup = document.getElementById("mypopup");
|
||||
let outerAnchor = document.getElementById("toolbarbutton-anchor");
|
||||
let anchor = document.getAnonymousElementByAttribute(outerAnchor, "class", "toolbarbutton-icon");
|
||||
|
||||
function nextTest(e) {
|
||||
synthesizeMouse(outerAnchor, 5, 5, {});
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
@ -5,28 +5,22 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.Build;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
|
||||
public class AndroidGamepadManager {
|
||||
// This is completely arbitrary.
|
||||
@ -334,7 +328,7 @@ public class AndroidGamepadManager {
|
||||
}
|
||||
|
||||
private static void addDeviceListener() {
|
||||
if (Build.VERSION.SDK_INT < 16) {
|
||||
if (Versions.preJB) {
|
||||
// Poll known gamepads to see if they've disappeared.
|
||||
sPollTimer = new Timer();
|
||||
sPollTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@ -378,7 +372,7 @@ public class AndroidGamepadManager {
|
||||
}
|
||||
|
||||
private static void removeDeviceListener() {
|
||||
if (Build.VERSION.SDK_INT < 16) {
|
||||
if (Versions.preJB) {
|
||||
if (sPollTimer != null) {
|
||||
sPollTimer.cancel();
|
||||
sPollTimer = null;
|
||||
|
@ -8,6 +8,8 @@ package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* A collection of constants that pertain to the build and runtime state of the
|
||||
* application. Typically these are sourced from build-time definitions (see
|
||||
@ -20,12 +22,57 @@ import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
@RobocopTarget
|
||||
public class AppConstants {
|
||||
public static final String ANDROID_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@";
|
||||
// Maintain a separate search package name so that we can speciailize it in the standalone search project
|
||||
public static final String SEARCH_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@";
|
||||
public static final String MANGLED_ANDROID_PACKAGE_NAME = "@MANGLED_ANDROID_PACKAGE_NAME@";
|
||||
|
||||
/**
|
||||
* Encapsulates access to compile-time version definitions, allowing
|
||||
* for dead code removal for particular APKs.
|
||||
*/
|
||||
public static final class Versions {
|
||||
public static final int MIN_SDK_VERSION = @MOZ_ANDROID_MIN_SDK_VERSION@;
|
||||
public static final int MAX_SDK_VERSION =
|
||||
#ifdef MOZ_ANDROID_MAX_SDK_VERSION
|
||||
@MOZ_ANDROID_MAX_SDK_VERSION@;
|
||||
#else
|
||||
999;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The SDK_INT >= N check can only pass if our MAX_SDK_VERSION is
|
||||
* _greater than or equal_ to that number, because otherwise we
|
||||
* won't be installed on the device.
|
||||
*
|
||||
* If MIN_SDK_VERSION is greater than or equal to the number, there
|
||||
* is no need to do the runtime check.
|
||||
*/
|
||||
public static final boolean feature10Plus = MIN_SDK_VERSION >= 10 || (MAX_SDK_VERSION >= 10 && Build.VERSION.SDK_INT >= 10);
|
||||
public static final boolean feature11Plus = MIN_SDK_VERSION >= 11 || (MAX_SDK_VERSION >= 11 && Build.VERSION.SDK_INT >= 11);
|
||||
public static final boolean feature12Plus = MIN_SDK_VERSION >= 12 || (MAX_SDK_VERSION >= 12 && Build.VERSION.SDK_INT >= 12);
|
||||
public static final boolean feature14Plus = MIN_SDK_VERSION >= 14 || (MAX_SDK_VERSION >= 14 && Build.VERSION.SDK_INT >= 14);
|
||||
public static final boolean feature15Plus = MIN_SDK_VERSION >= 15 || (MAX_SDK_VERSION >= 15 && Build.VERSION.SDK_INT >= 15);
|
||||
public static final boolean feature16Plus = MIN_SDK_VERSION >= 16 || (MAX_SDK_VERSION >= 16 && Build.VERSION.SDK_INT >= 16);
|
||||
public static final boolean feature17Plus = MIN_SDK_VERSION >= 17 || (MAX_SDK_VERSION >= 17 && Build.VERSION.SDK_INT >= 17);
|
||||
public static final boolean feature19Plus = MIN_SDK_VERSION >= 19 || (MAX_SDK_VERSION >= 19 && Build.VERSION.SDK_INT >= 19);
|
||||
|
||||
/*
|
||||
* If our MIN_SDK_VERSION is 14 or higher, we must be an ICS device.
|
||||
* If our MAX_SDK_VERSION is lower than ICS, we must not be an ICS device.
|
||||
* Otherwise, we need a range check.
|
||||
*/
|
||||
public static final boolean preJB = MAX_SDK_VERSION < 16 || (MIN_SDK_VERSION < 16 && Build.VERSION.SDK_INT < 16);
|
||||
public static final boolean preICS = MAX_SDK_VERSION < 14 || (MIN_SDK_VERSION < 14 && Build.VERSION.SDK_INT < 14);
|
||||
public static final boolean preHCMR2 = MAX_SDK_VERSION < 13 || (MIN_SDK_VERSION < 13 && Build.VERSION.SDK_INT < 13);
|
||||
public static final boolean preHCMR1 = MAX_SDK_VERSION < 12 || (MIN_SDK_VERSION < 12 && Build.VERSION.SDK_INT < 12);
|
||||
public static final boolean preHC = MAX_SDK_VERSION < 11 || (MIN_SDK_VERSION < 11 && Build.VERSION.SDK_INT < 11);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the Java class that launches the browser.
|
||||
*/
|
||||
public static final String BROWSER_INTENT_CLASS_NAME = "org.mozilla.gecko.BrowserApp";
|
||||
public static final String SEARCH_INTENT_CLASS_NAME = "org.mozilla.search.MainActivity";
|
||||
|
||||
public static final String GRE_MILESTONE = "@GRE_MILESTONE@";
|
||||
|
||||
@ -140,9 +187,11 @@ public class AppConstants {
|
||||
false;
|
||||
#endif
|
||||
|
||||
// Android Beam is only supported on API14+, so we don't even bother building
|
||||
// it if this APK doesn't include API14 support.
|
||||
public static final boolean MOZ_ANDROID_BEAM =
|
||||
#ifdef MOZ_ANDROID_BEAM
|
||||
true;
|
||||
Versions.feature14Plus;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
@ -5,16 +5,16 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.prompts.PromptService;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.prompts.PromptService;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.RectF;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.location.LocationListener;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
@ -79,7 +79,7 @@ public class BaseGeckoInterface implements GeckoAppShell.GeckoInterface {
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN : 0,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
if (Versions.feature11Plus) {
|
||||
window.getDecorView().setSystemUiVisibility(fullscreen ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ package org.mozilla.gecko;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.lang.Class;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.EnumSet;
|
||||
@ -15,11 +14,10 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
import java.util.Set;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.DynamicToolbar.PinReason;
|
||||
import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
|
||||
import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
|
||||
@ -53,8 +51,8 @@ import org.mozilla.gecko.home.HomePanelsManager;
|
||||
import org.mozilla.gecko.home.SearchEngine;
|
||||
import org.mozilla.gecko.menu.GeckoMenu;
|
||||
import org.mozilla.gecko.menu.GeckoMenuItem;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.prompts.Prompt;
|
||||
import org.mozilla.gecko.prompts.PromptListItem;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts;
|
||||
@ -66,10 +64,10 @@ import org.mozilla.gecko.util.Clipboard;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.NativeEventListener;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.MenuUtils;
|
||||
import org.mozilla.gecko.util.NativeEventListener;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.PrefUtils;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
@ -322,7 +320,7 @@ public class BrowserApp extends GeckoApp
|
||||
|
||||
// Check if this was a shortcut. Meta keys exists only on 11+.
|
||||
final Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
if (Build.VERSION.SDK_INT >= 11 && tab != null && event.isCtrlPressed()) {
|
||||
if (Versions.feature11Plus && tab != null && event.isCtrlPressed()) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_LEFT_BRACKET:
|
||||
tab.doBack();
|
||||
@ -556,25 +554,12 @@ public class BrowserApp extends GeckoApp
|
||||
final SuggestedSites suggestedSites = new SuggestedSites(appContext, distribution);
|
||||
BrowserDB.setSuggestedSites(suggestedSites);
|
||||
|
||||
// Shipping Native casting is optional and dependent on whether you've downloaded the support
|
||||
// and google play libraries
|
||||
if (AppConstants.MOZ_MEDIA_PLAYER) {
|
||||
try {
|
||||
Class<?> mediaManagerClass = Class.forName("org.mozilla.gecko.MediaPlayerManager");
|
||||
Method init = mediaManagerClass.getMethod("init", Context.class);
|
||||
init.invoke(null, this);
|
||||
} catch(Exception ex) {
|
||||
// Ignore failures
|
||||
Log.i(LOGTAG, "No native casting support", ex);
|
||||
}
|
||||
}
|
||||
|
||||
JavaAddonManager.getInstance().init(appContext);
|
||||
mSharedPreferencesHelper = new SharedPreferencesHelper(appContext);
|
||||
mOrderedBroadcastHelper = new OrderedBroadcastHelper(appContext);
|
||||
mBrowserHealthReporter = new BrowserHealthReporter();
|
||||
|
||||
if (AppConstants.MOZ_ANDROID_BEAM && Build.VERSION.SDK_INT >= 14) {
|
||||
if (AppConstants.MOZ_ANDROID_BEAM) {
|
||||
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
|
||||
if (nfc != null) {
|
||||
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
|
||||
@ -812,7 +797,7 @@ public class BrowserApp extends GeckoApp
|
||||
if (itemId == R.id.site_settings) {
|
||||
// This can be selected from either the browser menu or the contextmenu, depending on the size and version (v11+) of the phone.
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Permissions:Get", null));
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.CONTEXT_MENU, "site_settings");
|
||||
}
|
||||
return true;
|
||||
@ -838,7 +823,7 @@ public class BrowserApp extends GeckoApp
|
||||
Log.e(LOGTAG, "error building json arguments");
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Feeds:Subscribe", args.toString()));
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.CONTEXT_MENU, "subscribe");
|
||||
}
|
||||
}
|
||||
@ -858,7 +843,7 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:Add", args.toString()));
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.CONTEXT_MENU, "add_search_engine");
|
||||
}
|
||||
}
|
||||
@ -962,7 +947,7 @@ public class BrowserApp extends GeckoApp
|
||||
"Telemetry:Gather",
|
||||
"Updater:Launch");
|
||||
|
||||
if (AppConstants.MOZ_ANDROID_BEAM && Build.VERSION.SDK_INT >= 14) {
|
||||
if (AppConstants.MOZ_ANDROID_BEAM) {
|
||||
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
|
||||
if (nfc != null) {
|
||||
// null this out even though the docs say it's not needed,
|
||||
@ -2328,7 +2313,7 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
// Action providers are available only ICS+.
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
GeckoMenuItem share = (GeckoMenuItem) mMenu.findItem(R.id.share);
|
||||
GeckoActionProvider provider = GeckoActionProvider.getForType(GeckoActionProvider.DEFAULT_MIME_TYPE, this);
|
||||
share.setActionProvider(provider);
|
||||
@ -2409,11 +2394,17 @@ public class BrowserApp extends GeckoApp
|
||||
MenuItem enterGuestMode = aMenu.findItem(R.id.new_guest_session);
|
||||
MenuItem exitGuestMode = aMenu.findItem(R.id.exit_guest_session);
|
||||
|
||||
// Only show the "Quit" menu item on pre-ICS, television devices, or if the user has explicitly enabled the clear on shutdown pref.
|
||||
// Only show the "Quit" menu item on pre-ICS, television devices,
|
||||
// or if the user has explicitly enabled the clear on shutdown pref.
|
||||
// (We check the pref last to save the pref read.)
|
||||
// In ICS+, it's easy to kill an app through the task switcher.
|
||||
final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
|
||||
final Set<String> clearItems = PrefUtils.getStringSet(prefs, ClearOnShutdownPref.PREF, new HashSet<String>());
|
||||
aMenu.findItem(R.id.quit).setVisible(clearItems.size() > 0 || Build.VERSION.SDK_INT < 14 || HardwareUtils.isTelevision());
|
||||
final boolean visible = Versions.preICS ||
|
||||
HardwareUtils.isTelevision() ||
|
||||
!PrefUtils.getStringSet(GeckoSharedPrefs.forProfile(this),
|
||||
ClearOnShutdownPref.PREF,
|
||||
new HashSet<String>()).isEmpty();
|
||||
aMenu.findItem(R.id.quit).setVisible(visible);
|
||||
|
||||
if (tab == null || tab.getURL() == null) {
|
||||
bookmark.setEnabled(false);
|
||||
@ -2467,7 +2458,7 @@ public class BrowserApp extends GeckoApp
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, !isAboutHome(tab));
|
||||
|
||||
// Action providers are available only ICS+.
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
final GeckoActionProvider provider = ((GeckoMenuItem) share).getGeckoActionProvider();
|
||||
if (provider != null) {
|
||||
Intent shareIntent = provider.getIntent();
|
||||
@ -2771,7 +2762,7 @@ public class BrowserApp extends GeckoApp
|
||||
|
||||
super.onNewIntent(intent);
|
||||
|
||||
if (AppConstants.MOZ_ANDROID_BEAM && Build.VERSION.SDK_INT >= 10 && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
|
||||
if (AppConstants.MOZ_ANDROID_BEAM && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
|
||||
String uri = intent.getDataString();
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(uri));
|
||||
}
|
||||
|
@ -22,10 +22,12 @@ import com.google.android.gms.cast.MediaMetadata;
|
||||
import com.google.android.gms.cast.MediaStatus;
|
||||
import com.google.android.gms.cast.RemoteMediaPlayer;
|
||||
import com.google.android.gms.cast.RemoteMediaPlayer.MediaChannelResult;
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.GooglePlayServicesUtil;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
@ -137,6 +139,11 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
}
|
||||
|
||||
public ChromeCast(Context context, RouteInfo route) {
|
||||
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
|
||||
if (status != ConnectionResult.SUCCESS) {
|
||||
throw new IllegalStateException("Play services are required for Chromecast support (go status code " + status + ")");
|
||||
}
|
||||
|
||||
this.context = context;
|
||||
this.route = route;
|
||||
this.canMirror = route.supportsControlCategory(CastMediaControlIntent.categoryForCast(MIRROR_RECIEVER_APP_ID));
|
||||
|
@ -14,6 +14,7 @@ import java.util.Map.Entry;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
@ -29,7 +30,6 @@ import android.content.DialogInterface;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
|
||||
@ -1628,7 +1628,8 @@ public class ContactService implements GeckoEventListener {
|
||||
private static boolean isAutoAddGroup(Cursor cursor) {
|
||||
// For Honeycomb and up, the default group is the first one which has the AUTO_ADD flag set.
|
||||
// For everything below Honeycomb, use the default "System Group: My Contacts" group
|
||||
return (Build.VERSION.SDK_INT >= 11 && !cursor.isNull(GROUP_AUTO_ADD) &&
|
||||
return (Versions.feature11Plus &&
|
||||
!cursor.isNull(GROUP_AUTO_ADD) &&
|
||||
cursor.getInt(GROUP_AUTO_ADD) != 0);
|
||||
}
|
||||
|
||||
@ -1681,7 +1682,7 @@ public class ContactService implements GeckoEventListener {
|
||||
Groups.ACCOUNT_TYPE,
|
||||
Groups._ID,
|
||||
Groups.TITLE,
|
||||
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Groups.AUTO_ADD : Groups._ID)
|
||||
(Versions.feature11Plus ? Groups.AUTO_ADD : Groups._ID)
|
||||
};
|
||||
|
||||
if (selectArg != null) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
|
||||
import android.app.Notification;
|
||||
@ -15,7 +16,6 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Build;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
@ -87,7 +87,7 @@ public class DataReportingNotification {
|
||||
// Create and send notification.
|
||||
String notificationTitle = resources.getString(R.string.datareporting_notification_title);
|
||||
String notificationSummary;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (Versions.preJB) {
|
||||
notificationSummary = resources.getString(R.string.datareporting_notification_action);
|
||||
} else {
|
||||
// Display partial version of Big Style notification for supporting devices.
|
||||
|
@ -5,25 +5,24 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.widget.ArrowPopup;
|
||||
import org.mozilla.gecko.widget.DoorHanger;
|
||||
import org.mozilla.gecko.prompts.PromptInput;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.prompts.PromptInput;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.widget.ArrowPopup;
|
||||
import org.mozilla.gecko.widget.DoorHanger;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class DoorHangerPopup extends ArrowPopup
|
||||
implements GeckoEventListener,
|
||||
Tabs.OnTabsChangedListener,
|
||||
@ -311,13 +310,13 @@ public class DoorHangerPopup extends ArrowPopup
|
||||
// Make the popup focusable for accessibility. This gets done here
|
||||
// so the node can be accessibility focused, but on pre-ICS devices this
|
||||
// causes crashes, so it is done after the popup is shown.
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
setFocusable(true);
|
||||
}
|
||||
|
||||
show();
|
||||
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
if (Versions.preICS) {
|
||||
// Make the popup focusable for keyboard accessibility.
|
||||
setFocusable(true);
|
||||
}
|
||||
|
@ -5,19 +5,22 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@ -29,10 +32,6 @@ import android.view.accessibility.AccessibilityNodeProvider;
|
||||
import com.googlecode.eyesfree.braille.selfbraille.SelfBrailleClient;
|
||||
import com.googlecode.eyesfree.braille.selfbraille.WriteData;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class GeckoAccessibility {
|
||||
private static final String LOGTAG = "GeckoAccessibility";
|
||||
private static final int VIRTUAL_CURSOR_PREVIOUS = 1;
|
||||
@ -74,8 +73,7 @@ public class GeckoAccessibility {
|
||||
if (sEnabled)
|
||||
break;
|
||||
}
|
||||
if (sEnabled && sSelfBrailleClient == null &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (Versions.feature16Plus && sEnabled && sSelfBrailleClient == null) {
|
||||
sSelfBrailleClient = new SelfBrailleClient(GeckoAppShell.getContext(), false);
|
||||
}
|
||||
}
|
||||
@ -117,13 +115,13 @@ public class GeckoAccessibility {
|
||||
event.setItemCount(message.optInt("itemCount", -1));
|
||||
event.setCurrentItemIndex(message.optInt("currentItemIndex", -1));
|
||||
event.setBeforeText(message.optString("beforeText"));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (Versions.feature14Plus) {
|
||||
event.setToIndex(message.optInt("toIndex", -1));
|
||||
event.setScrollable(message.optBoolean("scrollable"));
|
||||
event.setScrollX(message.optInt("scrollX", -1));
|
||||
event.setScrollY(message.optInt("scrollY", -1));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
if (Versions.feature15Plus) {
|
||||
event.setMaxScrollX(message.optInt("maxScrollX", -1));
|
||||
event.setMaxScrollY(message.optInt("maxScrollY", -1));
|
||||
}
|
||||
@ -153,7 +151,7 @@ public class GeckoAccessibility {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (Versions.preJB) {
|
||||
// Before Jelly Bean we send events directly from here while spoofing the source by setting
|
||||
// the package and class name manually.
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@ -247,7 +245,7 @@ public class GeckoAccessibility {
|
||||
|
||||
public static void setDelegate(LayerView layerview) {
|
||||
// Only use this delegate in Jelly Bean.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (Versions.feature16Plus) {
|
||||
layerview.setAccessibilityDelegate(new GeckoAccessibilityDelegate());
|
||||
layerview.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.util.regex.Pattern;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.favicons.Favicons;
|
||||
@ -78,7 +79,6 @@ import android.hardware.SensorEventListener;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
@ -295,13 +295,15 @@ public abstract class GeckoApp
|
||||
|
||||
@Override
|
||||
public void invalidateOptionsMenu() {
|
||||
if (mMenu == null)
|
||||
if (mMenu == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
onPrepareOptionsMenu(mMenu);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11)
|
||||
if (Versions.feature11Plus) {
|
||||
super.invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -315,10 +317,11 @@ public abstract class GeckoApp
|
||||
|
||||
@Override
|
||||
public MenuInflater getMenuInflater() {
|
||||
if (Build.VERSION.SDK_INT >= 11)
|
||||
if (Versions.feature11Plus) {
|
||||
return new GeckoMenuInflater(this);
|
||||
else
|
||||
} else {
|
||||
return super.getMenuInflater();
|
||||
}
|
||||
}
|
||||
|
||||
public MenuPanel getMenuPanel() {
|
||||
@ -369,7 +372,7 @@ public abstract class GeckoApp
|
||||
|
||||
@Override
|
||||
public View onCreatePanelView(int featureId) {
|
||||
if (Build.VERSION.SDK_INT >= 11 && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (mMenuPanel == null) {
|
||||
mMenuPanel = new MenuPanel(this, null);
|
||||
} else {
|
||||
@ -385,7 +388,7 @@ public abstract class GeckoApp
|
||||
|
||||
@Override
|
||||
public boolean onCreatePanelMenu(int featureId, Menu menu) {
|
||||
if (Build.VERSION.SDK_INT >= 11 && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (mMenuPanel == null) {
|
||||
mMenuPanel = (MenuPanel) onCreatePanelView(featureId);
|
||||
}
|
||||
@ -404,8 +407,9 @@ public abstract class GeckoApp
|
||||
|
||||
@Override
|
||||
public boolean onPreparePanel(int featureId, View view, Menu menu) {
|
||||
if (Build.VERSION.SDK_INT >= 11 && featureId == Window.FEATURE_OPTIONS_PANEL)
|
||||
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
return onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
return super.onPreparePanel(featureId, view, menu);
|
||||
}
|
||||
@ -417,7 +421,7 @@ public abstract class GeckoApp
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FullScreen:Exit", null));
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11 && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
|
||||
if (mMenu == null) {
|
||||
// getMenuPanel() will force the creation of the menu as well
|
||||
MenuPanel panel = getMenuPanel();
|
||||
@ -463,7 +467,7 @@ public abstract class GeckoApp
|
||||
|
||||
@Override
|
||||
public void onOptionsMenuClosed(Menu menu) {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
if (Versions.feature11Plus) {
|
||||
mMenuPanel.removeAllViews();
|
||||
mMenuPanel.addView((GeckoMenu) mMenu);
|
||||
}
|
||||
@ -1049,8 +1053,9 @@ public abstract class GeckoApp
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN : 0,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11)
|
||||
if (Versions.feature11Plus) {
|
||||
window.getDecorView().setSystemUiVisibility(fullscreen ? 1 : 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1341,7 +1346,7 @@ public abstract class GeckoApp
|
||||
|
||||
if (mCameraView == null) {
|
||||
// Pre-ICS devices need the camera surface in a visible layout.
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (Versions.preICS) {
|
||||
mCameraView = new SurfaceView(this);
|
||||
((SurfaceView)mCameraView).getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
@ -1737,7 +1742,7 @@ public abstract class GeckoApp
|
||||
|
||||
// Try to make it fully transparent.
|
||||
if (mCameraView != null && (mCameraView instanceof SurfaceView)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.feature11Plus) {
|
||||
mCameraView.setAlpha(0.0f);
|
||||
}
|
||||
ViewGroup mCameraLayout = (ViewGroup) findViewById(R.id.camera_layout);
|
||||
@ -2577,7 +2582,7 @@ public abstract class GeckoApp
|
||||
}
|
||||
|
||||
private void setSystemUiVisible(final boolean visible) {
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
if (Versions.preICS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
|
||||
import org.mozilla.gecko.favicons.decoders.FaviconDecoder;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
@ -88,7 +89,6 @@ import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@ -832,7 +832,7 @@ public class GeckoAppShell
|
||||
|
||||
@JNITarget
|
||||
static public int getPreferredIconSize() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
if (Versions.feature11Plus) {
|
||||
ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
|
||||
return am.getLauncherLargeIconSize();
|
||||
} else {
|
||||
@ -1829,7 +1829,7 @@ public class GeckoAppShell
|
||||
}
|
||||
|
||||
// disable on KitKat (bug 957694)
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Versions.feature19Plus) {
|
||||
Log.w(LOGTAG, "Blocking plugins because of Tegra (bug 957694)");
|
||||
return null;
|
||||
}
|
||||
|
@ -5,15 +5,22 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.gfx.InputConnectionHandler;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.Editable;
|
||||
@ -30,14 +37,6 @@ import android.util.Log;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
// interface for the IC thread
|
||||
interface GeckoEditableClient {
|
||||
void sendEvent(GeckoEvent event);
|
||||
@ -251,8 +250,8 @@ final class GeckoEditable
|
||||
try {
|
||||
if (mKeyMap == null) {
|
||||
mKeyMap = KeyCharacterMap.load(
|
||||
Build.VERSION.SDK_INT < 11 ? KeyCharacterMap.ALPHA :
|
||||
KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||
Versions.preHC ? KeyCharacterMap.ALPHA :
|
||||
KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// KeyCharacterMap.UnavailableExcepton is not found on Gingerbread;
|
||||
@ -488,8 +487,9 @@ final class GeckoEditable
|
||||
}
|
||||
int tpUnderlineColor = 0;
|
||||
float tpUnderlineThickness = 0.0f;
|
||||
// These TextPaint fields only exist on Android ICS+ and are not in the SDK
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
|
||||
// These TextPaint fields only exist on Android ICS+ and are not in the SDK.
|
||||
if (Versions.feature14Plus) {
|
||||
tpUnderlineColor = (Integer)getField(tp, "underlineColor", 0);
|
||||
tpUnderlineThickness = (Float)getField(tp, "underlineThickness", 0.0f);
|
||||
}
|
||||
|
@ -5,14 +5,17 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.gfx.DisplayPortMetrics;
|
||||
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
||||
import org.mozilla.gecko.mozglue.JNITarget;
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
import org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions;
|
||||
import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI;
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
@ -21,17 +24,12 @@ import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorManager;
|
||||
import android.location.Address;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
|
||||
/* We're not allowed to hold on to most events given to us
|
||||
* so we save the parts of the events we want to use in GeckoEvent.
|
||||
* Fields have different meanings depending on the event type.
|
||||
@ -331,7 +329,7 @@ public class GeckoEvent {
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
return true;
|
||||
default:
|
||||
if (Build.VERSION.SDK_INT >= 12) {
|
||||
if (Versions.feature12Plus) {
|
||||
return KeyEvent.isGamepadButton(keyCode);
|
||||
}
|
||||
return GeckoEvent.isGamepadButton(keyCode);
|
||||
@ -340,7 +338,7 @@ public class GeckoEvent {
|
||||
|
||||
/**
|
||||
* This method is a replacement for the the KeyEvent.isGamepadButton method to be
|
||||
* compatible with Build.VERSION.SDK_INT < 12. This is an implementantion of the
|
||||
* compatible with Build.VERSION.SDK_INT < 12. This is an implementation of the
|
||||
* same method isGamepadButton available after SDK 12.
|
||||
* @param keyCode int with the key code (Android key constant from KeyEvent).
|
||||
* @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}.
|
||||
|
@ -10,6 +10,7 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.gfx.InputConnectionHandler;
|
||||
import org.mozilla.gecko.util.Clipboard;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
@ -18,7 +19,6 @@ import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
|
||||
|
||||
import android.R;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
@ -953,10 +953,10 @@ class GeckoInputConnection
|
||||
if (typeHint != null &&
|
||||
(typeHint.equalsIgnoreCase("date") ||
|
||||
typeHint.equalsIgnoreCase("time") ||
|
||||
(Build.VERSION.SDK_INT >= 11 && (typeHint.equalsIgnoreCase("datetime") ||
|
||||
typeHint.equalsIgnoreCase("month") ||
|
||||
typeHint.equalsIgnoreCase("week") ||
|
||||
typeHint.equalsIgnoreCase("datetime-local"))))) {
|
||||
(Versions.feature11Plus && (typeHint.equalsIgnoreCase("datetime") ||
|
||||
typeHint.equalsIgnoreCase("month") ||
|
||||
typeHint.equalsIgnoreCase("week") ||
|
||||
typeHint.equalsIgnoreCase("datetime-local"))))) {
|
||||
state = IME_STATE_DISABLED;
|
||||
}
|
||||
|
||||
|
@ -5,17 +5,15 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.view.inputmethod.InputMethodInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
final public class InputMethods {
|
||||
public static final String METHOD_ANDROID_LATINIME = "com.android.inputmethod.latin/.LatinIME";
|
||||
public static final String METHOD_ATOK = "com.justsystems.atokmobile.service/.AtokInputMethodService";
|
||||
@ -55,8 +53,9 @@ final public class InputMethods {
|
||||
|
||||
public static boolean needsSoftResetWorkaround(String inputMethod) {
|
||||
// Stock latin IME on Android 4.2 and above
|
||||
return Build.VERSION.SDK_INT >= 17 && (METHOD_ANDROID_LATINIME.equals(inputMethod) ||
|
||||
METHOD_GOOGLE_LATINIME.equals(inputMethod));
|
||||
return Versions.feature17Plus &&
|
||||
(METHOD_ANDROID_LATINIME.equals(inputMethod) ||
|
||||
METHOD_GOOGLE_LATINIME.equals(inputMethod));
|
||||
}
|
||||
|
||||
public static boolean shouldCommitCharAsKey(String inputMethod) {
|
||||
@ -67,8 +66,9 @@ final public class InputMethods {
|
||||
// SwiftKey is a gesture keyboard, but it doesn't seem to need any special-casing
|
||||
// to do AwesomeBar auto-spacing.
|
||||
String inputMethod = getCurrentInputMethod(context);
|
||||
return (Build.VERSION.SDK_INT >= 17 && (METHOD_ANDROID_LATINIME.equals(inputMethod) ||
|
||||
METHOD_GOOGLE_LATINIME.equals(inputMethod))) ||
|
||||
return (Versions.feature17Plus &&
|
||||
(METHOD_ANDROID_LATINIME.equals(inputMethod) ||
|
||||
METHOD_GOOGLE_LATINIME.equals(inputMethod))) ||
|
||||
METHOD_SWYPE.equals(inputMethod) ||
|
||||
METHOD_SWYPE_BETA.equals(inputMethod) ||
|
||||
METHOD_TOUCHPAL_KEYBOARD.equals(inputMethod);
|
||||
|
@ -5,11 +5,15 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.app.Application;
|
||||
import android.graphics.Bitmap;
|
||||
@ -19,7 +23,6 @@ import android.graphics.Rect;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.DisplayMetrics;
|
||||
@ -28,9 +31,6 @@ import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LightweightTheme implements GeckoEventListener {
|
||||
private static final String LOGTAG = "GeckoLightweightTheme";
|
||||
|
||||
@ -253,7 +253,7 @@ public class LightweightTheme implements GeckoEventListener {
|
||||
ViewParent parent;
|
||||
View curView = view;
|
||||
do {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
if (Versions.feature11Plus) {
|
||||
offsetX += (int) curView.getTranslationX() - curView.getScrollX();
|
||||
offsetY += (int) curView.getTranslationY() - curView.getScrollY();
|
||||
} else {
|
||||
|
@ -6,6 +6,7 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.mozglue.JNITarget;
|
||||
import org.mozilla.gecko.util.NativeEventListener;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
|
||||
@ -41,7 +42,7 @@ interface GeckoMediaPlayer {
|
||||
* from Gecko to the correct caster based on the id of the display
|
||||
*/
|
||||
class MediaPlayerManager implements NativeEventListener,
|
||||
GeckoAppShell.AppStateListener {
|
||||
GeckoAppShell.AppStateListener {
|
||||
private static final String LOGTAG = "GeckoMediaPlayerManager";
|
||||
|
||||
private static final boolean SHOW_DEBUG = false;
|
||||
@ -63,9 +64,11 @@ class MediaPlayerManager implements NativeEventListener,
|
||||
private final HashMap<String, GeckoMediaPlayer> displays = new HashMap<String, GeckoMediaPlayer>();
|
||||
private static MediaPlayerManager instance;
|
||||
|
||||
@JNITarget
|
||||
public static void init(Context context) {
|
||||
if (instance != null) {
|
||||
debug("MediaPlayerManager initialized twice");
|
||||
return;
|
||||
}
|
||||
|
||||
instance = new MediaPlayerManager(context);
|
||||
@ -92,6 +95,7 @@ class MediaPlayerManager implements NativeEventListener,
|
||||
"MediaPlayer:Message");
|
||||
}
|
||||
|
||||
@JNITarget
|
||||
public static void onDestroy() {
|
||||
if (instance == null) {
|
||||
return;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.favicons.Favicons;
|
||||
@ -15,7 +16,6 @@ import android.content.ComponentCallbacks2;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@ -89,8 +89,8 @@ class MemoryMonitor extends BroadcastReceiver {
|
||||
|
||||
public void onTrimMemory(int level) {
|
||||
Log.d(LOGTAG, "onTrimMemory() notification received with level " + level);
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
// this won't even get called pre-ICS
|
||||
if (Versions.preICS) {
|
||||
// This won't even get called pre-ICS.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5,18 +5,19 @@
|
||||
|
||||
package org.mozilla.gecko.animation;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Transformation;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
class AnimatorProxy {
|
||||
private static final WeakHashMap<View, AnimatorProxy> PROXIES =
|
||||
new WeakHashMap<View, AnimatorProxy>();
|
||||
@ -42,7 +43,7 @@ class AnimatorProxy {
|
||||
|
||||
public static AnimatorProxy create(View view) {
|
||||
AnimatorProxy proxy = PROXIES.get(view);
|
||||
boolean needsAnimationProxy = (Build.VERSION.SDK_INT < 11);
|
||||
final boolean needsAnimationProxy = Versions.preHC;
|
||||
|
||||
// If the view's animation proxy has been overridden from somewhere else, we need to
|
||||
// create a new AnimatorProxy for the view.
|
||||
|
@ -5,9 +5,13 @@
|
||||
|
||||
package org.mozilla.gecko.animation;
|
||||
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.os.Build;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.view.Choreographer;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -16,9 +20,6 @@ import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PropertyAnimator implements Runnable {
|
||||
private static final String LOGTAG = "GeckoPropertyAnimator";
|
||||
|
||||
@ -163,7 +164,7 @@ public class PropertyAnimator implements Runnable {
|
||||
// in the current view tree. OnPreDrawListener seems broken
|
||||
// on pre-Honeycomb devices, start animation immediatelly
|
||||
// in this case.
|
||||
if (Build.VERSION.SDK_INT >= 11 && treeObserver != null && treeObserver.isAlive()) {
|
||||
if (Versions.feature11Plus && treeObserver != null && treeObserver.isAlive()) {
|
||||
treeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
@ -186,7 +187,6 @@ public class PropertyAnimator implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the animation, optionally snapping to the end position.
|
||||
* onPropertyAnimationEnd is only called when snapping to the end position.
|
||||
@ -201,10 +201,11 @@ public class PropertyAnimator implements Runnable {
|
||||
|
||||
ViewCompat.setHasTransientState(element.view, false);
|
||||
|
||||
if (shouldEnableHardwareLayer(element))
|
||||
if (shouldEnableHardwareLayer(element)) {
|
||||
element.view.setLayerType(View.LAYER_TYPE_NONE, null);
|
||||
else
|
||||
} else {
|
||||
element.view.setDrawingCacheEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
mElementsList.clear();
|
||||
@ -226,19 +227,23 @@ public class PropertyAnimator implements Runnable {
|
||||
}
|
||||
|
||||
private boolean shouldEnableHardwareLayer(ElementHolder element) {
|
||||
if (!mUseHardwareLayer)
|
||||
if (Versions.preHC) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11)
|
||||
if (!mUseHardwareLayer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(element.view instanceof ViewGroup))
|
||||
if (!(element.view instanceof ViewGroup)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (element.property == Property.ALPHA ||
|
||||
element.property == Property.TRANSLATION_Y ||
|
||||
element.property == Property.TRANSLATION_X)
|
||||
element.property == Property.TRANSLATION_X) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -269,10 +274,11 @@ public class PropertyAnimator implements Runnable {
|
||||
|
||||
private static abstract class FramePoster {
|
||||
public static FramePoster create(Runnable r) {
|
||||
if (Build.VERSION.SDK_INT >= 16)
|
||||
if (Versions.feature16Plus) {
|
||||
return new FramePosterPostJB(r);
|
||||
else
|
||||
return new FramePosterPreJB(r);
|
||||
}
|
||||
|
||||
return new FramePosterPreJB(r);
|
||||
}
|
||||
|
||||
public abstract void postFirstAnimationFrame();
|
||||
@ -284,8 +290,8 @@ public class PropertyAnimator implements Runnable {
|
||||
// Default refresh rate in ms.
|
||||
private static final int INTERVAL = 10;
|
||||
|
||||
private Handler mHandler;
|
||||
private Runnable mRunnable;
|
||||
private final Handler mHandler;
|
||||
private final Runnable mRunnable;
|
||||
|
||||
public FramePosterPreJB(Runnable r) {
|
||||
mHandler = new Handler();
|
||||
@ -309,8 +315,8 @@ public class PropertyAnimator implements Runnable {
|
||||
}
|
||||
|
||||
private static class FramePosterPostJB extends FramePoster {
|
||||
private Choreographer mChoreographer;
|
||||
private Choreographer.FrameCallback mCallback;
|
||||
private final Choreographer mChoreographer;
|
||||
private final Choreographer.FrameCallback mCallback;
|
||||
|
||||
public FramePosterPostJB(final Runnable r) {
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
|
@ -4,12 +4,13 @@
|
||||
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@ -94,7 +95,7 @@ public abstract class AbstractTransactionalProvider extends ContentProvider {
|
||||
*/
|
||||
@SuppressWarnings("static-method")
|
||||
protected boolean shouldUseTransactions() {
|
||||
return Build.VERSION.SDK_INT >= 11;
|
||||
return Versions.feature11Plus;
|
||||
}
|
||||
|
||||
private boolean isInBatch() {
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.db.PerProfileDatabases.DatabaseHelperFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* Abstract class containing methods needed to make a SQLite-based content
|
||||
@ -42,7 +42,7 @@ public abstract class PerProfileDatabaseProvider<T extends SQLiteOpenHelper> ext
|
||||
@Override
|
||||
public T makeDatabaseHelper(Context context, String databasePath) {
|
||||
final T helper = createDatabaseHelper(context, databasePath);
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
if (Versions.feature16Plus) {
|
||||
helper.setWriteAheadLoggingEnabled(true);
|
||||
}
|
||||
return helper;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.db.BrowserContract.CommonColumns;
|
||||
import org.mozilla.gecko.db.BrowserContract.SyncColumns;
|
||||
import org.mozilla.gecko.db.PerProfileDatabases.DatabaseHelperFactory;
|
||||
@ -12,7 +13,6 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@ -50,7 +50,7 @@ public abstract class SharedBrowserDatabaseProvider extends AbstractPerProfileDa
|
||||
@Override
|
||||
public BrowserDatabaseHelper makeDatabaseHelper(Context context, String databasePath) {
|
||||
final BrowserDatabaseHelper helper = new BrowserDatabaseHelper(context, databasePath);
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
if (Versions.feature16Plus) {
|
||||
helper.setWriteAheadLoggingEnabled(true);
|
||||
}
|
||||
return helper;
|
||||
|
@ -8,6 +8,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.db.BrowserContract.Clients;
|
||||
import org.mozilla.gecko.db.BrowserContract.Tabs;
|
||||
|
||||
@ -171,7 +172,7 @@ public class TabsProvider extends PerProfileDatabaseProvider<TabsProvider.TabsDa
|
||||
|
||||
if (shouldUseTransactions()) {
|
||||
// Modern Android allows WAL to be enabled through a mode flag.
|
||||
if (Build.VERSION.SDK_INT < 16) {
|
||||
if (Versions.preJB) {
|
||||
db.enableWriteAheadLogging();
|
||||
}
|
||||
db.setLockingEnabled(false);
|
||||
|
@ -5,23 +5,22 @@
|
||||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.PrefsHelper;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
import org.mozilla.gecko.ZoomConstraints;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.util.FloatUtils;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
@ -294,7 +293,7 @@ class JavaPanZoomController
|
||||
/** This function MUST be called on the UI thread */
|
||||
@Override
|
||||
public boolean onKeyEvent(KeyEvent event) {
|
||||
if (Build.VERSION.SDK_INT <= 11) {
|
||||
if (Versions.preHCMR1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -314,7 +313,7 @@ class JavaPanZoomController
|
||||
/** This function MUST be called on the UI thread */
|
||||
@Override
|
||||
public boolean onMotionEvent(MotionEvent event) {
|
||||
if (Build.VERSION.SDK_INT <= 11) {
|
||||
if (Versions.preHCMR1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.mozilla.gecko.AndroidGamepadManager;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAccessibility;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
@ -30,7 +31,6 @@ import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@ -110,7 +110,7 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener
|
||||
mFullScreenState = FullScreenState.NONE;
|
||||
|
||||
mTouchInterceptors = new ArrayList<TouchEventInterceptor>();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (Versions.feature14Plus) {
|
||||
mOverscroll = new OverscrollEdgeEffect(this);
|
||||
} else {
|
||||
mOverscroll = null;
|
||||
|
@ -5,11 +5,12 @@
|
||||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.Build;
|
||||
import android.widget.EdgeEffect;
|
||||
import android.view.View;
|
||||
import android.widget.EdgeEffect;
|
||||
|
||||
|
||||
public class OverscrollEdgeEffect implements Overscroll {
|
||||
@ -57,7 +58,7 @@ public class OverscrollEdgeEffect implements Overscroll {
|
||||
}
|
||||
|
||||
private void invalidate() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (Versions.feature16Plus) {
|
||||
mView.postInvalidateOnAnimation();
|
||||
} else {
|
||||
mView.postInvalidateDelayed(10);
|
||||
@ -118,7 +119,7 @@ public class OverscrollEdgeEffect implements Overscroll {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean draw(final EdgeEffect edge, final Canvas canvas, final float translateX, final float translateY, final float rotation) {
|
||||
private static boolean draw(final EdgeEffect edge, final Canvas canvas, final float translateX, final float translateY, final float rotation) {
|
||||
final int state = canvas.save();
|
||||
canvas.translate(translateX, translateY);
|
||||
canvas.rotate(rotation);
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
package org.mozilla.gecko.home;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
@ -21,19 +21,15 @@ import org.mozilla.gecko.widget.EllipsisTextView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class HomeBanner extends LinearLayout
|
||||
implements GeckoEventListener {
|
||||
@ -133,7 +129,7 @@ public class HomeBanner extends LinearLayout
|
||||
public void setVisibility(int visibility) {
|
||||
// On pre-Honeycomb devices, setting the visibility to GONE won't actually
|
||||
// hide the view unless we clear animations first.
|
||||
if (Build.VERSION.SDK_INT < 11 && visibility == View.GONE) {
|
||||
if (Versions.preHC && visibility == View.GONE) {
|
||||
clearAnimation();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.Telemetry;
|
||||
import org.mozilla.gecko.TelemetryContract;
|
||||
@ -20,7 +21,6 @@ import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
@ -197,7 +197,7 @@ public class HomePager extends ViewPager {
|
||||
}
|
||||
|
||||
// Only animate on post-HC devices, when a non-null animator is given
|
||||
final boolean shouldAnimate = (animator != null && Build.VERSION.SDK_INT >= 11);
|
||||
final boolean shouldAnimate = Versions.feature11Plus && animator != null;
|
||||
|
||||
final HomeAdapter adapter = new HomeAdapter(mContext, fm);
|
||||
adapter.setOnAddPanelListener(mAddPanelListener);
|
||||
|
@ -4,15 +4,16 @@
|
||||
|
||||
package org.mozilla.gecko.menu;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Xml;
|
||||
import android.view.InflateException;
|
||||
@ -21,18 +22,14 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GeckoMenuInflater extends MenuInflater {
|
||||
private static final String LOGTAG = "GeckoMenuInflater";
|
||||
|
||||
public class GeckoMenuInflater extends MenuInflater {
|
||||
private static final String TAG_MENU = "menu";
|
||||
private static final String TAG_ITEM = "item";
|
||||
private static final int NO_ID = 0;
|
||||
|
||||
private Context mContext;
|
||||
private final Context mContext;
|
||||
|
||||
// Private class to hold the parsed menu item.
|
||||
// Private class to hold the parsed menu item.
|
||||
private class ParsedItem {
|
||||
public int id;
|
||||
public int order;
|
||||
@ -73,16 +70,16 @@ public class GeckoMenuInflater extends MenuInflater {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseMenu(XmlResourceParser parser, AttributeSet attrs, Menu menu)
|
||||
private void parseMenu(XmlResourceParser parser, AttributeSet attrs, Menu menu)
|
||||
throws XmlPullParserException, IOException {
|
||||
ParsedItem item = null;
|
||||
|
||||
|
||||
String tag;
|
||||
int eventType = parser.getEventType();
|
||||
|
||||
do {
|
||||
tag = parser.getName();
|
||||
|
||||
|
||||
switch (eventType) {
|
||||
case XmlPullParser.START_TAG:
|
||||
if (tag.equals(TAG_ITEM)) {
|
||||
@ -136,12 +133,13 @@ public class GeckoMenuInflater extends MenuInflater {
|
||||
item.enabled = a.getBoolean(R.styleable.MenuItem_android_enabled, true);
|
||||
item.hasSubMenu = false;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11)
|
||||
if (Versions.feature11Plus) {
|
||||
item.showAsAction = a.getInt(R.styleable.MenuItem_android_showAsAction, 0);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
|
||||
public void setValues(ParsedItem item, MenuItem menuItem) {
|
||||
menuItem.setChecked(item.checked)
|
||||
.setVisible(item.visible)
|
||||
@ -149,7 +147,8 @@ public class GeckoMenuInflater extends MenuInflater {
|
||||
.setCheckable(item.checkable)
|
||||
.setIcon(item.iconRes);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11)
|
||||
if (Versions.feature11Plus) {
|
||||
menuItem.setShowAsAction(item.showAsAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
package org.mozilla.gecko.menu;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.widget.GeckoActionProvider;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.view.ActionProvider;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuItem;
|
||||
@ -17,13 +17,11 @@ import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
|
||||
public class GeckoMenuItem implements MenuItem {
|
||||
private static final String LOGTAG = "GeckoMenuItem";
|
||||
|
||||
public static final int SHOW_AS_ACTION_NEVER = 0;
|
||||
public static final int SHOW_AS_ACTION_IF_ROOM = 1;
|
||||
public static final int SHOW_AS_ACTION_ALWAYS = 2;
|
||||
|
||||
// A View that can show a MenuItem should be able to initialize from
|
||||
// A View that can show a MenuItem should be able to initialize from
|
||||
// the properties of the MenuItem.
|
||||
public static interface Layout {
|
||||
public void initialize(GeckoMenuItem item);
|
||||
@ -35,8 +33,8 @@ public class GeckoMenuItem implements MenuItem {
|
||||
public void onShowAsActionChanged(GeckoMenuItem item);
|
||||
}
|
||||
|
||||
private int mId;
|
||||
private int mOrder;
|
||||
private final int mId;
|
||||
private final int mOrder;
|
||||
private View mActionView;
|
||||
private int mActionEnum;
|
||||
private CharSequence mTitle;
|
||||
@ -48,7 +46,7 @@ public class GeckoMenuItem implements MenuItem {
|
||||
private Drawable mIcon;
|
||||
private int mIconRes;
|
||||
private GeckoActionProvider mActionProvider;
|
||||
private GeckoMenu mMenu;
|
||||
private final GeckoMenu mMenu;
|
||||
private GeckoSubMenu mSubMenu;
|
||||
private MenuItem.OnMenuItemClickListener mMenuItemClickListener = null;
|
||||
private OnShowAsActionChangedListener mShowAsActionChangedListener;
|
||||
@ -78,7 +76,7 @@ public class GeckoMenuItem implements MenuItem {
|
||||
}
|
||||
|
||||
public boolean hasActionProvider() {
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
if (Versions.preICS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ package org.mozilla.gecko.menu;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
@ -18,17 +19,14 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.os.Build;
|
||||
|
||||
public class MenuItemActionView extends LinearLayout
|
||||
implements GeckoMenuItem.Layout,
|
||||
View.OnClickListener {
|
||||
private static final String LOGTAG = "GeckoMenuItemActionView";
|
||||
|
||||
private MenuItemDefault mMenuItem;
|
||||
private MenuItemActionBar mMenuButton;
|
||||
private List<ImageButton> mActionButtons;
|
||||
private List<View.OnClickListener> mActionButtonListeners = new ArrayList<View.OnClickListener>();
|
||||
private final MenuItemDefault mMenuItem;
|
||||
private final MenuItemActionBar mMenuButton;
|
||||
private final List<ImageButton> mActionButtons;
|
||||
private final List<View.OnClickListener> mActionButtonListeners = new ArrayList<View.OnClickListener>();
|
||||
|
||||
public MenuItemActionView(Context context) {
|
||||
this(context, null);
|
||||
@ -43,12 +41,12 @@ public class MenuItemActionView extends LinearLayout
|
||||
super(context, attrs);
|
||||
|
||||
// Set these explicitly, since setting a style isn't supported for LinearLayouts until V11.
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
if (Versions.feature11Plus) {
|
||||
setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
|
||||
setDividerDrawable(getResources().getDrawable(R.drawable.divider_vertical));
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
setDividerPadding(0);
|
||||
}
|
||||
|
||||
@ -78,8 +76,9 @@ public class MenuItemActionView extends LinearLayout
|
||||
|
||||
@Override
|
||||
public void initialize(GeckoMenuItem item) {
|
||||
if (item == null)
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMenuItem.initialize(item);
|
||||
mMenuButton.initialize(item);
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
package org.mozilla.gecko.menu;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.ViewGroup;
|
||||
@ -41,8 +41,10 @@ public class MenuPanel extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public boolean dispatchPopulateAccessibilityEvent (AccessibilityEvent event) {
|
||||
if (Build.VERSION.SDK_INT >= 14) // Build.VERSION_CODES.ICE_CREAM_SANDWICH
|
||||
if (Versions.feature14Plus) {
|
||||
onPopulateAccessibilityEvent(event);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package org.mozilla.gecko.preferences;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.BrowserLocaleManager;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.LocaleManager;
|
||||
@ -18,7 +19,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceFragment;
|
||||
@ -108,7 +108,7 @@ public class GeckoPreferenceFragment extends PreferenceFragment {
|
||||
}
|
||||
|
||||
final PreferenceActivity activity = (PreferenceActivity) getActivity();
|
||||
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) && activity.isMultiPane()) {
|
||||
if (Versions.feature11Plus && activity.isMultiPane()) {
|
||||
// In a multi-pane activity, the title is "Settings", and the action
|
||||
// bar is along the top of the screen. We don't want to change those.
|
||||
activity.showBreadCrumbs(newTitle, newTitle);
|
||||
@ -118,7 +118,7 @@ public class GeckoPreferenceFragment extends PreferenceFragment {
|
||||
Log.v(LOGTAG, "Setting activity title to " + newTitle);
|
||||
activity.setTitle(newTitle);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
final ActionBar actionBar = activity.getActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setTitle(newTitle);
|
||||
@ -175,7 +175,7 @@ public class GeckoPreferenceFragment extends PreferenceFragment {
|
||||
// The resource was invalid. Use the default resource.
|
||||
Log.e(LOGTAG, "Failed to find resource: " + resourceName + ". Displaying default settings.");
|
||||
|
||||
boolean isMultiPane = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) &&
|
||||
boolean isMultiPane = Versions.feature11Plus &&
|
||||
((PreferenceActivity) activity).isMultiPane();
|
||||
resid = isMultiPane ? R.xml.preferences_customize_tablet : R.xml.preferences;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.BrowserApp;
|
||||
import org.mozilla.gecko.BrowserLocaleManager;
|
||||
import org.mozilla.gecko.DataReportingNotification;
|
||||
@ -52,7 +53,6 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
@ -153,7 +153,7 @@ OnSharedPreferenceChangeListener
|
||||
}
|
||||
}
|
||||
private void updateActionBarTitle(int title) {
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
final String newTitle = getString(title);
|
||||
if (newTitle != null) {
|
||||
Log.v(LOGTAG, "Setting action bar title to " + newTitle);
|
||||
@ -190,7 +190,7 @@ OnSharedPreferenceChangeListener
|
||||
// If we're a multi-pane view, the activity title is really
|
||||
// the header bar above the fragment.
|
||||
// Find out which fragment we're showing, and use that.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && isMultiPane()) {
|
||||
if (Versions.feature11Plus && isMultiPane()) {
|
||||
int title = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE, -1);
|
||||
if (res == R.xml.preferences) {
|
||||
// This should only occur when res == R.xml.preferences,
|
||||
@ -227,7 +227,7 @@ OnSharedPreferenceChangeListener
|
||||
BrowserLocaleManager.getInstance().updateConfiguration(getApplicationContext(), newLocale);
|
||||
this.lastLocale = newLocale;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 11 && isMultiPane()) {
|
||||
if (Versions.feature11Plus && isMultiPane()) {
|
||||
// This takes care of the left pane.
|
||||
invalidateHeaders();
|
||||
|
||||
@ -301,7 +301,7 @@ OnSharedPreferenceChangeListener
|
||||
// (or set it) before super.onCreate() is called so Android can display
|
||||
// the correct Fragment resource.
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.feature11Plus) {
|
||||
if (!getIntent().hasExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT)) {
|
||||
// Set up the default fragment if there is no explicit fragment to show.
|
||||
setupTopLevelFragmentIntent();
|
||||
@ -316,7 +316,7 @@ OnSharedPreferenceChangeListener
|
||||
// all) in the action bar.
|
||||
updateActionBarTitle(R.string.settings_title);
|
||||
|
||||
if (Build.VERSION.SDK_INT < 13) {
|
||||
if (android.os.Build.VERSION.SDK_INT < 13) {
|
||||
// Affected by Bug 1015209 -- no detach/attach.
|
||||
// If we try rejigging fragments, we'll crash, so don't
|
||||
// enable locale switching at all.
|
||||
@ -333,7 +333,7 @@ OnSharedPreferenceChangeListener
|
||||
// For versions of Android lower than Honeycomb, use xml resources instead of
|
||||
// Fragments because of an Android bug in ActionBar (described in bug 866352 and
|
||||
// fixed in bug 833625).
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
// Write prefs to our custom GeckoSharedPrefs file.
|
||||
getPreferenceManager().setSharedPreferencesName(GeckoSharedPrefs.APP_PREFS_NAME);
|
||||
|
||||
@ -381,7 +381,7 @@ OnSharedPreferenceChangeListener
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
final ActionBar actionBar = getActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setHomeButtonEnabled(true);
|
||||
@ -455,7 +455,7 @@ OnSharedPreferenceChangeListener
|
||||
return;
|
||||
|
||||
mInitialized = true;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
mPrefsRequestId = setupPreferences(screen);
|
||||
}
|
||||
@ -483,7 +483,7 @@ OnSharedPreferenceChangeListener
|
||||
@Override
|
||||
public void onPause() {
|
||||
// Symmetric with onResume.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.feature11Plus) {
|
||||
if (isMultiPane()) {
|
||||
SharedPreferences prefs = GeckoSharedPrefs.forApp(this);
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||
@ -505,7 +505,7 @@ OnSharedPreferenceChangeListener
|
||||
((GeckoApplication) getApplication()).onActivityResume(this);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.feature11Plus) {
|
||||
// Watch prefs, otherwise we don't reliably get told when they change.
|
||||
// See documentation for onSharedPreferenceChange for more.
|
||||
// Inexplicably only needed on tablet.
|
||||
@ -1233,7 +1233,7 @@ OnSharedPreferenceChangeListener
|
||||
public void prefValue(String prefName, final boolean value) {
|
||||
final Preference pref = getField(prefName);
|
||||
final CheckBoxPrefSetter prefSetter;
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
if (Versions.preICS) {
|
||||
prefSetter = new CheckBoxPrefSetter();
|
||||
} else {
|
||||
prefSetter = new TwoStatePrefSetter();
|
||||
@ -1283,7 +1283,7 @@ OnSharedPreferenceChangeListener
|
||||
final Preference pref = getField(prefName);
|
||||
final CheckBoxPrefSetter prefSetter;
|
||||
if (PREFS_GEO_REPORTING.equals(prefName)) {
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
if (Versions.preICS) {
|
||||
prefSetter = new CheckBoxPrefSetter();
|
||||
} else {
|
||||
prefSetter = new TwoStatePrefSetter();
|
||||
@ -1338,7 +1338,7 @@ OnSharedPreferenceChangeListener
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
intent.putExtra("resource", resource);
|
||||
} else {
|
||||
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, GeckoPreferenceFragment.class.getName());
|
||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
@ -17,7 +18,6 @@ import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.os.Build;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -85,7 +85,7 @@ public class IconGridInput extends PromptInput implements OnItemClickListener {
|
||||
// Despite what the docs say, setItemChecked was not moved into the AbsListView class until sometime between
|
||||
// Android 2.3.7 and Android 4.0.3. For other versions the item won't be visually highlighted, BUT we really only
|
||||
// mSelected will still be set so that we default to its behavior.
|
||||
if (Build.VERSION.SDK_INT >= 11 && mSelected > -1) {
|
||||
if (Versions.feature11Plus && mSelected > -1) {
|
||||
view.setItemChecked(mSelected, true);
|
||||
}
|
||||
|
||||
|
@ -10,13 +10,13 @@ import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.widget.AllCapsTextView;
|
||||
import org.mozilla.gecko.widget.DateTimePicker;
|
||||
import org.mozilla.gecko.widget.FloatingHintEditText;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.text.Html;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
@ -229,7 +229,7 @@ public class PromptInput {
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
if (Build.VERSION.SDK_INT < 11 && mType.equals("date")) {
|
||||
if (Versions.preHC && mType.equals("date")) {
|
||||
// We can't use the custom DateTimePicker with a sdk older than 11.
|
||||
// Fallback on the native DatePicker.
|
||||
DatePicker dp = (DatePicker)mView;
|
||||
@ -278,7 +278,7 @@ public class PromptInput {
|
||||
}
|
||||
|
||||
public View getView(final Context context) throws UnsupportedOperationException {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (Versions.preHC) {
|
||||
spinner = new Spinner(context);
|
||||
} else {
|
||||
spinner = new Spinner(context, Spinner.MODE_DIALOG);
|
||||
@ -291,7 +291,8 @@ public class PromptInput {
|
||||
spinner.setAdapter(adapter);
|
||||
spinner.setSelection(mSelected);
|
||||
}
|
||||
} catch(Exception ex) { }
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(mLabel)) {
|
||||
LinearLayout container = new LinearLayout(context);
|
||||
|
@ -5,30 +5,24 @@
|
||||
|
||||
package org.mozilla.gecko.prompts;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TabWidget;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class TabInput extends PromptInput implements AdapterView.OnItemClickListener {
|
||||
public static final String INPUT_TYPE = "tabs";
|
||||
public static final String LOGTAG = "GeckoTabInput";
|
||||
@ -76,7 +70,7 @@ public class TabInput extends PromptInput implements AdapterView.OnItemClickList
|
||||
});
|
||||
|
||||
// On older android versions, we use a custom style for the tabs.
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
TextView textview = (TextView) inflater.inflate(R.layout.tab_prompt_tab, null);
|
||||
textview.setText(title);
|
||||
spec.setIndicator(textview);
|
||||
|
@ -14,6 +14,7 @@ import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.config.AccountPickler;
|
||||
import org.mozilla.gecko.sync.config.ClientRecordTerminator;
|
||||
import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
|
||||
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
|
||||
|
||||
@ -77,6 +78,10 @@ public class SyncAccountDeletedService extends IntentService {
|
||||
Logger.info(LOG_TAG, "Account named " + accountName + " being removed; " +
|
||||
"deleting client record from server.");
|
||||
deleteClientRecord(context, accountName, params.password, params.serverURL);
|
||||
|
||||
// Delete client database and non-local tabs.
|
||||
Logger.info(LOG_TAG, "Deleting the entire clients database and non-local tabs");
|
||||
FennecTabsRepository.deleteNonLocalClientsAndTabs(context);
|
||||
}
|
||||
|
||||
public static void deletePickle(final Context context) {
|
||||
|
@ -33,6 +33,8 @@ import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
|
||||
public class FennecTabsRepository extends Repository {
|
||||
private static final String LOG_TAG = "FennecTabsRepository";
|
||||
|
||||
protected final ClientsDataDelegate clientsDataDelegate;
|
||||
|
||||
public FennecTabsRepository(ClientsDataDelegate clientsDataDelegate) {
|
||||
@ -351,4 +353,35 @@ public class FennecTabsRepository extends Repository {
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all non-local clients and remote tabs.
|
||||
*
|
||||
* This function doesn't delete non-local clients due to bug in TabsProvider. Refer Bug 1025128.
|
||||
*
|
||||
* Upon remote tabs deletion, the clients without tabs are not shown in UI.
|
||||
*/
|
||||
public static void deleteNonLocalClientsAndTabs(Context context) {
|
||||
final String nonLocalTabsSelection = BrowserContract.Tabs.CLIENT_GUID + " IS NOT NULL";
|
||||
|
||||
ContentProviderClient tabsProvider = context.getContentResolver()
|
||||
.acquireContentProviderClient(BrowserContractHelpers.TABS_CONTENT_URI);
|
||||
if (tabsProvider == null) {
|
||||
Logger.warn(LOG_TAG, "Unable to create tabsProvider!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Logger.info(LOG_TAG, "Clearing all non-local tabs for default profile.");
|
||||
tabsProvider.delete(BrowserContractHelpers.TABS_CONTENT_URI, nonLocalTabsSelection, null);
|
||||
} catch (RemoteException e) {
|
||||
Logger.warn(LOG_TAG, "Error while deleting", e);
|
||||
} finally {
|
||||
try {
|
||||
tabsProvider.release();
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Got exception releasing tabsProvider!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.tabspanel;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoAppShell.AppStateListener;
|
||||
@ -25,7 +26,6 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@ -42,7 +42,6 @@ public class TabsPanel extends LinearLayout
|
||||
implements GeckoPopupMenu.OnMenuItemClickListener,
|
||||
LightweightTheme.OnChangeListener,
|
||||
IconTabWidget.OnTabChangedListener {
|
||||
@SuppressWarnings("unused")
|
||||
private static final String LOGTAG = "Gecko" + TabsPanel.class.getSimpleName();
|
||||
|
||||
public static enum Panel {
|
||||
@ -508,7 +507,7 @@ public class TabsPanel extends LinearLayout
|
||||
public void prepareTabsAnimation(PropertyAnimator animator) {
|
||||
// Not worth doing this on pre-Honeycomb without proper
|
||||
// hardware accelerated animations.
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -539,7 +538,7 @@ public class TabsPanel extends LinearLayout
|
||||
}
|
||||
|
||||
public void finishTabsAnimation() {
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,24 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const TAG = "AndroidLogTest";
|
||||
|
||||
const VERBOSE_MESSAGE = "This is a verbose message.";
|
||||
const DEBUG_MESSAGE = "This is a debug message.";
|
||||
const INFO_MESSAGE = "This is an info message.";
|
||||
const WARNING_MESSAGE = "This is a warning message.";
|
||||
const ERROR_MESSAGE = "This is an error message.";
|
||||
|
||||
// Number of bytes we expect to log. This isn't equivalent to the number
|
||||
// of characters, although the difference is consistent, so we can calculate it
|
||||
// from the lengths of the messages and tag. We include the length of "Gecko"
|
||||
// because the module prepends it to the tag.
|
||||
const VERBOSE_BYTES = "Gecko".length + TAG.length + VERBOSE_MESSAGE.length + 3;
|
||||
const DEBUG_BYTES = "Gecko".length + TAG.length + DEBUG_MESSAGE.length + 3;
|
||||
const INFO_BYTES = "Gecko".length + TAG.length + INFO_MESSAGE.length + 3;
|
||||
const WARNING_BYTES = "Gecko".length + TAG.length + WARNING_MESSAGE.length + 3;
|
||||
const ERROR_BYTES = "Gecko".length + TAG.length + ERROR_MESSAGE.length + 3;
|
||||
|
||||
add_task(function test_AndroidLog() {
|
||||
Components.utils.import("resource://gre/modules/AndroidLog.jsm");
|
||||
|
||||
@ -14,22 +32,30 @@ add_task(function test_AndroidLog() {
|
||||
do_check_true("w" in AndroidLog && typeof AndroidLog.w == "function");
|
||||
do_check_true("e" in AndroidLog && typeof AndroidLog.e == "function");
|
||||
|
||||
// I don't know how to check that these messages actually make it to the log,
|
||||
// but at least we can ensure that they don't cause the test process to crash
|
||||
// Ensure that the functions don't cause the test process to crash
|
||||
// (because of some change to the native object being accessed via ctypes)
|
||||
// and return the right values (the number of bytes--not characters--logged).
|
||||
do_check_eq(48, AndroidLog.v("AndroidLogTest", "This is a verbose message."));
|
||||
do_check_eq(46, AndroidLog.d("AndroidLogTest", "This is a debug message."));
|
||||
do_check_eq(46, AndroidLog.i("AndroidLogTest", "This is an info message."));
|
||||
do_check_eq(48, AndroidLog.w("AndroidLogTest", "This is a warning message."));
|
||||
do_check_eq(47, AndroidLog.e("AndroidLogTest", "This is an error message."));
|
||||
// and return the right values (the number of bytes logged).
|
||||
// XXX Ensure that these messages actually make it to the log (bug 1046096).
|
||||
do_check_eq(VERBOSE_BYTES, AndroidLog.v(TAG, VERBOSE_MESSAGE));
|
||||
do_check_eq(DEBUG_BYTES, AndroidLog.d(TAG, DEBUG_MESSAGE));
|
||||
do_check_eq(INFO_BYTES, AndroidLog.i(TAG, INFO_MESSAGE));
|
||||
do_check_eq(WARNING_BYTES, AndroidLog.w(TAG, WARNING_MESSAGE));
|
||||
do_check_eq(ERROR_BYTES, AndroidLog.e(TAG, ERROR_MESSAGE));
|
||||
|
||||
// Ensure the functions work when bound with null value for thisArg parameter.
|
||||
do_check_eq(48, AndroidLog.v.bind(null, "AndroidLogTest")("This is a verbose message."));
|
||||
do_check_eq(46, AndroidLog.d.bind(null, "AndroidLogTest")("This is a debug message."));
|
||||
do_check_eq(46, AndroidLog.i.bind(null, "AndroidLogTest")("This is an info message."));
|
||||
do_check_eq(48, AndroidLog.w.bind(null, "AndroidLogTest")("This is a warning message."));
|
||||
do_check_eq(47, AndroidLog.e.bind(null, "AndroidLogTest")("This is an error message."));
|
||||
do_check_eq(VERBOSE_BYTES, AndroidLog.v.bind(null, TAG)(VERBOSE_MESSAGE));
|
||||
do_check_eq(DEBUG_BYTES, AndroidLog.d.bind(null, TAG)(DEBUG_MESSAGE));
|
||||
do_check_eq(INFO_BYTES, AndroidLog.i.bind(null, TAG)(INFO_MESSAGE));
|
||||
do_check_eq(WARNING_BYTES, AndroidLog.w.bind(null, TAG)(WARNING_MESSAGE));
|
||||
do_check_eq(ERROR_BYTES, AndroidLog.e.bind(null, TAG)(ERROR_MESSAGE));
|
||||
|
||||
// Ensure the functions work when the module object is "bound" to a tag.
|
||||
let Log = AndroidLog.bind(TAG);
|
||||
do_check_eq(VERBOSE_BYTES, Log.v(VERBOSE_MESSAGE));
|
||||
do_check_eq(DEBUG_BYTES, Log.d(DEBUG_MESSAGE));
|
||||
do_check_eq(INFO_BYTES, Log.i(INFO_MESSAGE));
|
||||
do_check_eq(WARNING_BYTES, Log.w(WARNING_MESSAGE));
|
||||
do_check_eq(ERROR_BYTES, Log.e(ERROR_MESSAGE));
|
||||
|
||||
// Ensure the functions work when the tag length is greater than the maximum
|
||||
// tag length.
|
||||
|
@ -11,6 +11,7 @@ import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.BrowserApp;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
@ -39,16 +40,12 @@ import org.mozilla.gecko.widget.ThemedRelativeLayout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MotionEvent;
|
||||
@ -219,7 +216,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
|
||||
tabsButton = (ShapedButton) findViewById(R.id.tabs);
|
||||
tabsCounter = (TabCounter) findViewById(R.id.tabs_counter);
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
if (Versions.feature11Plus) {
|
||||
tabsCounter.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
||||
@ -1004,7 +1001,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
urlBarEntry.setLayoutParams(urlBarEntryShrunkenLayoutParams);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
showEditingOnPreHoneycomb(entryTranslation, curveTranslation);
|
||||
} else {
|
||||
showEditingWithPhoneAnimation(animator, entryTranslation, curveTranslation);
|
||||
@ -1133,7 +1130,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
// not selected so clear the selection by clearing focus.
|
||||
urlEditLayout.clearFocus();
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
stopEditingOnPreHoneycomb();
|
||||
} else if (HardwareUtils.isTablet()) {
|
||||
stopEditingOnTablet();
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
package org.mozilla.gecko.toolbar;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
@ -11,7 +13,6 @@ import android.graphics.Path;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Build;
|
||||
|
||||
class CanvasDelegate {
|
||||
Paint mPaint;
|
||||
@ -50,7 +51,7 @@ class CanvasDelegate {
|
||||
if (path != null && !path.isEmpty()) {
|
||||
// ICS added double-buffering, which made it easier for drawing the Path directly over the DST.
|
||||
// In pre-ICS, drawPath() doesn't seem to use ARGB_8888 mode for performance, hence transparency is not preserved.
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
if (Versions.feature14Plus) {
|
||||
mPaint.setXfermode(mMode);
|
||||
canvas.drawPath(path, mPaint);
|
||||
} else {
|
||||
|
@ -5,19 +5,18 @@
|
||||
|
||||
package org.mozilla.gecko.toolbar;
|
||||
|
||||
import org.mozilla.gecko.animation.Rotate3DAnimation;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.animation.Rotate3DAnimation;
|
||||
import org.mozilla.gecko.widget.ThemedTextSwitcher;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationSet;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.AnimationSet;
|
||||
import android.widget.ViewSwitcher;
|
||||
|
||||
public class TabCounter extends ThemedTextSwitcher
|
||||
@ -53,7 +52,7 @@ public class TabCounter extends ThemedTextSwitcher
|
||||
removeAllViews();
|
||||
setFactory(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
if (Versions.feature16Plus) {
|
||||
// This adds the TextSwitcher to the a11y node tree, where we in turn
|
||||
// could make it return an empty info node. If we don't do this the
|
||||
// TextSwitcher's child TextViews get picked up, and we don't want
|
||||
|
@ -5,47 +5,41 @@
|
||||
|
||||
package org.mozilla.gecko.toolbar;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.mozilla.gecko.AboutPages;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator;
|
||||
import org.mozilla.gecko.animation.ViewHelper;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.BrowserApp;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.SiteIdentity;
|
||||
import org.mozilla.gecko.SiteIdentity.SecurityMode;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator;
|
||||
import org.mozilla.gecko.animation.ViewHelper;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.ForwardButtonAnimation;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.widget.ThemedLinearLayout;
|
||||
import org.mozilla.gecko.widget.ThemedTextView;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.TranslateAnimation;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@code ToolbarDisplayLayout} is the UI for when the toolbar is in
|
||||
@ -152,7 +146,7 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout
|
||||
mPrivateDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext_private));
|
||||
|
||||
mFavicon = (ImageButton) findViewById(R.id.favicon);
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
if (Versions.feature16Plus) {
|
||||
mFavicon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||
}
|
||||
mFaviconSize = Math.round(res.getDimension(R.dimen.browser_toolbar_favicon_size));
|
||||
|
@ -5,19 +5,17 @@
|
||||
|
||||
package org.mozilla.gecko.toolbar;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.CustomEditText;
|
||||
import org.mozilla.gecko.InputMethods;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.OnCommitListener;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.OnDismissListener;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.OnFilterListener;
|
||||
import org.mozilla.gecko.CustomEditText;
|
||||
import org.mozilla.gecko.CustomEditText.OnKeyPreImeListener;
|
||||
import org.mozilla.gecko.InputMethods;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.text.Editable;
|
||||
import android.text.NoCopySpan;
|
||||
import android.text.Selection;
|
||||
@ -29,7 +27,6 @@ import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
@ -547,8 +544,8 @@ public class ToolbarEditText extends CustomEditText
|
||||
}
|
||||
|
||||
if ((keyCode == KeyEvent.KEYCODE_DEL ||
|
||||
(Build.VERSION.SDK_INT >= 11 &&
|
||||
keyCode == KeyEvent.KEYCODE_FORWARD_DEL)) &&
|
||||
(Versions.feature11Plus &&
|
||||
keyCode == KeyEvent.KEYCODE_FORWARD_DEL)) &&
|
||||
removeAutocomplete(getText())) {
|
||||
// Delete autocomplete text when backspacing or forward deleting.
|
||||
return true;
|
||||
|
@ -16,17 +16,18 @@
|
||||
|
||||
package org.mozilla.gecko.toolbar;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.ImageView;
|
||||
|
||||
/**
|
||||
* Progress view used for page loads.
|
||||
@ -42,8 +43,6 @@ public class ToolbarProgressView extends ImageView {
|
||||
private static final int STEPS = 10;
|
||||
private static final int DELAY = 40;
|
||||
|
||||
private static final boolean PRE_HONEYCOMB = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
|
||||
|
||||
private int mTargetProgress;
|
||||
private int mIncrement;
|
||||
private Rect mBounds;
|
||||
@ -99,7 +98,7 @@ public class ToolbarProgressView extends ImageView {
|
||||
public void setVisibility(int visibility) {
|
||||
// On GB/Froyo, setting the visibility to GONE/HIDDEN alone does not
|
||||
// work with translations. Calling clearAnimation acts as a workaround.
|
||||
if (PRE_HONEYCOMB && visibility != VISIBLE) {
|
||||
if (Versions.preHC && visibility != VISIBLE) {
|
||||
clearAnimation();
|
||||
}
|
||||
|
||||
@ -111,7 +110,7 @@ public class ToolbarProgressView extends ImageView {
|
||||
// On GB/Froyo, setting the animation after hiding the view causes it
|
||||
// to reappear. As a workaround, disallow setAnimation from being
|
||||
// called if the view is not shown.
|
||||
if (PRE_HONEYCOMB && isShown()) {
|
||||
if (Versions.preHC && isShown()) {
|
||||
super.setAnimation(animation);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import java.util.Set;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.ActivityHandlerHelper;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
@ -31,8 +32,6 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
public class EventListener implements NativeEventListener {
|
||||
@ -204,11 +203,11 @@ public class EventListener implements NativeEventListener {
|
||||
}
|
||||
|
||||
public static void uninstallApk(final Activity context, NativeJSObject message) {
|
||||
String packageName = message.getString("apkPackageName");
|
||||
Uri packageUri = Uri.parse("package:" + packageName);
|
||||
final String packageName = message.getString("apkPackageName");
|
||||
final Uri packageUri = Uri.parse("package:" + packageName);
|
||||
|
||||
Intent intent;
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
final Intent intent;
|
||||
if (Versions.preICS) {
|
||||
intent = new Intent(Intent.ACTION_DELETE, packageUri);
|
||||
} else {
|
||||
intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.widget;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
|
||||
@ -12,7 +13,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@ -127,9 +127,9 @@ public abstract class ArrowPopup extends PopupWindow {
|
||||
if (mAnchor == null || anchorLocation[1] < 0) {
|
||||
final View decorView = ((Activity) mContext).getWindow().getDecorView();
|
||||
|
||||
// Bug in android code causes the window layout parameters to be ignored
|
||||
// Bug in Android code causes the window layout parameters to be ignored
|
||||
// when using showAtLocation() in Gingerbread phones.
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
setWidth(decorView.getWidth());
|
||||
setHeight(decorView.getHeight());
|
||||
}
|
||||
|
@ -16,10 +16,15 @@
|
||||
|
||||
package org.mozilla.gecko.widget;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
@ -35,16 +40,9 @@ import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.NumberPicker;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DateTimePicker extends FrameLayout {
|
||||
|
||||
private static final boolean DEBUG = true;
|
||||
private static final String LOGTAG = "GeckoDateTimePicker";
|
||||
private static final String DATE_FORMAT = "MM/dd/yyyy";
|
||||
private static final int DEFAULT_START_YEAR = 1;
|
||||
private static final int DEFAULT_END_YEAR = 9999;
|
||||
// Minimal screen width (in inches) for which we can show the calendar;
|
||||
@ -97,11 +95,14 @@ public class DateTimePicker extends FrameLayout {
|
||||
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
|
||||
updateInputState();
|
||||
mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
|
||||
boolean newBehavior = (Build.VERSION.SDK_INT > 10);
|
||||
final boolean newBehavior = Versions.feature11Plus;
|
||||
if (newBehavior) {
|
||||
if (DEBUG) Log.d(LOGTAG, "Sdk version > 10, using new behavior");
|
||||
//The native date picker widget on these sdks increment
|
||||
//the next field when one field reach the maximum
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "SDK version > 10, using new behavior");
|
||||
}
|
||||
|
||||
// The native date picker widget on these SDKs increments
|
||||
// the next field when one field reaches the maximum.
|
||||
if (picker == mDaySpinner && mDayEnabled) {
|
||||
int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||
int old = mTempDate.get(Calendar.DAY_OF_MONTH);
|
||||
@ -118,7 +119,7 @@ public class DateTimePicker extends FrameLayout {
|
||||
mTempDate.set(Calendar.YEAR,newVal);
|
||||
// Changing the year shouldn't change the month. (in case of non-leap year a Feb 29)
|
||||
// change the day instead;
|
||||
if (month != mTempDate.get(Calendar.MONTH)){
|
||||
if (month != mTempDate.get(Calendar.MONTH)) {
|
||||
mTempDate.set(Calendar.MONTH, month);
|
||||
mTempDate.set(Calendar.DAY_OF_MONTH,
|
||||
mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
|
||||
@ -184,7 +185,7 @@ public class DateTimePicker extends FrameLayout {
|
||||
}
|
||||
|
||||
private void setTempDate(int field, int oldVal, int newVal, int min, int max) {
|
||||
if (oldVal == max && newVal == min ) {
|
||||
if (oldVal == max && newVal == min) {
|
||||
mTempDate.add(field, 1);
|
||||
} else if (oldVal == min && newVal == max) {
|
||||
mTempDate.add(field, -1);
|
||||
@ -216,6 +217,7 @@ public class DateTimePicker extends FrameLayout {
|
||||
if (mState == PickersState.DATETIME) {
|
||||
return;
|
||||
}
|
||||
|
||||
setHourShown(false);
|
||||
setMinuteShown(false);
|
||||
if (mState == PickersState.WEEK) {
|
||||
@ -233,9 +235,10 @@ public class DateTimePicker extends FrameLayout {
|
||||
|
||||
public DateTimePicker(Context context, String dateFormat, String dateTimeValue, PickersState state) {
|
||||
super(context);
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
throw new UnsupportedOperationException("Custom DateTimePicker is only available for SDK > 10");
|
||||
}
|
||||
|
||||
setCurrentLocale(Locale.getDefault());
|
||||
mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
|
||||
mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
|
||||
@ -257,13 +260,22 @@ public class DateTimePicker extends FrameLayout {
|
||||
display.getMetrics(dm);
|
||||
mScreenWidth = display.getWidth() / dm.densityDpi;
|
||||
mScreenHeight = display.getHeight() / dm.densityDpi;
|
||||
if (DEBUG) Log.d(LOGTAG, "screen width: " + mScreenWidth + " screen height: " + mScreenHeight);
|
||||
|
||||
// If we're displaying a date, the screen is wide enought (and if we're using a sdk where the calendar view exists)
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "screen width: " + mScreenWidth + " screen height: " + mScreenHeight);
|
||||
}
|
||||
|
||||
// If we're displaying a date, the screen is wide enough
|
||||
// (and if we're using an SDK where the calendar view exists)
|
||||
// then display a calendar.
|
||||
if ((mState == PickersState.DATE || mState == PickersState.DATETIME) &&
|
||||
Build.VERSION.SDK_INT > 10 && mScreenWidth >= SCREEN_SIZE_THRESHOLD) {
|
||||
if (DEBUG) Log.d(LOGTAG,"SDK > 10 and screen wide enough, displaying calendar");
|
||||
if (Versions.feature11Plus &&
|
||||
(mState == PickersState.DATE || mState == PickersState.DATETIME) &&
|
||||
mScreenWidth >= SCREEN_SIZE_THRESHOLD) {
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG,"SDK > 10 and screen wide enough, displaying calendar");
|
||||
}
|
||||
|
||||
mCalendar = new CalendarView(context);
|
||||
mCalendar.setVisibility(GONE);
|
||||
|
||||
@ -286,9 +298,9 @@ public class DateTimePicker extends FrameLayout {
|
||||
|
||||
mPickers.addView(mCalendar);
|
||||
} else {
|
||||
// If the screen is more wide than high, we are displaying daye and time spinners,
|
||||
// and if there is no calendar displayed,
|
||||
// we should display the fields in one row.
|
||||
// If the screen is more wide than high, we are displaying day and
|
||||
// time spinners, and if there is no calendar displayed, we should
|
||||
// display the fields in one row.
|
||||
if (mScreenWidth > mScreenHeight && mState == PickersState.DATETIME) {
|
||||
mSpinners.setOrientation(LinearLayout.HORIZONTAL);
|
||||
}
|
||||
@ -349,11 +361,13 @@ public class DateTimePicker extends FrameLayout {
|
||||
|
||||
// The order in which the spinners are displayed are locale-dependent
|
||||
reorderDateSpinners();
|
||||
|
||||
// Set the date to the initial date. Since this date can come from the user,
|
||||
// it can fire an exception (out-of-bound date)
|
||||
try {
|
||||
updateDate(mTempDate);
|
||||
} catch (Exception ex) { }
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
// Display only the pickers needed for the current state.
|
||||
displayPickers();
|
||||
@ -495,13 +509,17 @@ public class DateTimePicker extends FrameLayout {
|
||||
}
|
||||
|
||||
public void toggleCalendar(boolean shown) {
|
||||
if ((mState != PickersState.DATE && mState != PickersState.DATETIME) ||
|
||||
Build.VERSION.SDK_INT < 11 || mScreenWidth < SCREEN_SIZE_THRESHOLD) {
|
||||
if (DEBUG) Log.d(LOGTAG,"Cannot display calendar on this device, in this state" +
|
||||
": screen width :"+mScreenWidth);
|
||||
if (Versions.preHC ||
|
||||
(mState != PickersState.DATE && mState != PickersState.DATETIME) ||
|
||||
mScreenWidth < SCREEN_SIZE_THRESHOLD) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "Cannot display calendar on this device, in this state" +
|
||||
": screen width :" + mScreenWidth);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (shown){
|
||||
|
||||
if (shown) {
|
||||
mCalendarEnabled = true;
|
||||
mCalendar.setVisibility(VISIBLE);
|
||||
setYearShown(false);
|
||||
@ -622,12 +640,12 @@ public class DateTimePicker extends FrameLayout {
|
||||
private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
|
||||
if (oldCalendar == null) {
|
||||
return Calendar.getInstance(locale);
|
||||
} else {
|
||||
final long currentTimeMillis = oldCalendar.getTimeInMillis();
|
||||
Calendar newCalendar = Calendar.getInstance(locale);
|
||||
newCalendar.setTimeInMillis(currentTimeMillis);
|
||||
return newCalendar;
|
||||
}
|
||||
|
||||
final long currentTimeMillis = oldCalendar.getTimeInMillis();
|
||||
Calendar newCalendar = Calendar.getInstance(locale);
|
||||
newCalendar.setTimeInMillis(currentTimeMillis);
|
||||
return newCalendar;
|
||||
}
|
||||
|
||||
public void updateDate(Calendar calendar) {
|
||||
@ -643,6 +661,4 @@ public class DateTimePicker extends FrameLayout {
|
||||
updateSpinners();
|
||||
notifyDateChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.mozilla.gecko.widget;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
@ -350,7 +352,7 @@ public class GeckoSwipeRefreshLayout extends ViewGroup {
|
||||
* scroll up. Override this if the child view is a custom view.
|
||||
*/
|
||||
public boolean canChildScrollUp() {
|
||||
if (android.os.Build.VERSION.SDK_INT < 14) {
|
||||
if (Versions.preICS) {
|
||||
if (mTarget instanceof AbsListView) {
|
||||
final AbsListView absListView = (AbsListView) mTarget;
|
||||
return absListView.getChildCount() > 0
|
||||
|
@ -5,21 +5,19 @@
|
||||
|
||||
package org.mozilla.gecko.widget;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.animation.ViewHelper;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.ViewFlipper;
|
||||
import android.util.Log;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
/* This extends the normal ViewFlipper only to fix bug 956075 on < 3.0 devices.
|
||||
* i.e. It ignores touch events on the ViewFlipper when its hidden. */
|
||||
|
||||
public class GeckoViewFlipper extends ViewFlipper {
|
||||
private static final String LOGTAG = "GeckoViewFlipper";
|
||||
private Rect mRect = new Rect();
|
||||
|
||||
public GeckoViewFlipper(Context context) {
|
||||
@ -32,7 +30,7 @@ public class GeckoViewFlipper extends ViewFlipper {
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (Versions.preHC) {
|
||||
// Fix bug 956075. Don't allow touching this View if its hidden.
|
||||
getHitRect(mRect);
|
||||
mRect.offset((int) ViewHelper.getTranslationX(this), (int) ViewHelper.getTranslationY(this));
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
@ -4,6 +4,9 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
// Define elements that bound phone number containers.
|
||||
const PHONE_NUMBER_CONTAINERS = "td,div";
|
||||
|
||||
var SelectionHandler = {
|
||||
HANDLE_TYPE_START: "START",
|
||||
HANDLE_TYPE_MIDDLE: "MIDDLE",
|
||||
@ -317,42 +320,6 @@ var SelectionHandler = {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._isPhoneNumber(selection.toString())) {
|
||||
let anchorNode = selection.anchorNode;
|
||||
let anchorOffset = selection.anchorOffset;
|
||||
let focusNode = null;
|
||||
let focusOffset = null;
|
||||
while (this._isPhoneNumber(selection.toString().trim())) {
|
||||
focusNode = selection.focusNode;
|
||||
focusOffset = selection.focusOffset;
|
||||
selection.modify("extend", "forward", "word");
|
||||
// if we hit the end of the text on the page, we can't advance the selection
|
||||
if (focusNode == selection.focusNode && focusOffset == selection.focusOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// reverse selection
|
||||
selection.collapse(focusNode, focusOffset);
|
||||
selection.extend(anchorNode, anchorOffset);
|
||||
|
||||
anchorNode = focusNode;
|
||||
anchorOffset = focusOffset
|
||||
|
||||
while (this._isPhoneNumber(selection.toString().trim())) {
|
||||
focusNode = selection.focusNode;
|
||||
focusOffset = selection.focusOffset;
|
||||
selection.modify("extend", "backward", "word");
|
||||
// if we hit the end of the text on the page, we can't advance the selection
|
||||
if (focusNode == selection.focusNode && focusOffset == selection.focusOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
selection.collapse(focusNode, focusOffset);
|
||||
selection.extend(anchorNode, anchorOffset);
|
||||
}
|
||||
|
||||
// Add a listener to end the selection if it's removed programatically
|
||||
selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
|
||||
this._activeType = this.TYPE_SELECTION;
|
||||
@ -389,7 +356,16 @@ var SelectionHandler = {
|
||||
if (aOptions.mode == this.SELECT_AT_POINT) {
|
||||
// Clear any ranges selected outside SelectionHandler, by code such as Find-In-Page.
|
||||
this._contentWindow.getSelection().removeAllRanges();
|
||||
return this._domWinUtils.selectAtPoint(aOptions.x, aOptions.y, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE);
|
||||
if (!this._domWinUtils.selectAtPoint(aOptions.x, aOptions.y, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform additional phone-number "smart selection".
|
||||
if (this._isPhoneNumber(this._getSelection().toString())) {
|
||||
this._selectSmartPhoneNumber();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aOptions.mode != this.SELECT_ALL) {
|
||||
@ -429,6 +405,71 @@ var SelectionHandler = {
|
||||
return true;
|
||||
},
|
||||
|
||||
/*
|
||||
* Called to expand a selection that appears to represent a phone number. This enhances the basic
|
||||
* SELECT_WORDNOSPACE logic employed in performSelection() in response to long-tap / selecting text.
|
||||
*/
|
||||
_selectSmartPhoneNumber: function() {
|
||||
this._extendPhoneNumberSelection("forward");
|
||||
this._reversePhoneNumberSelectionDir();
|
||||
|
||||
this._extendPhoneNumberSelection("backward");
|
||||
this._reversePhoneNumberSelectionDir();
|
||||
},
|
||||
|
||||
/*
|
||||
* Extend the current phone number selection in the requested direction.
|
||||
*/
|
||||
_extendPhoneNumberSelection: function(direction) {
|
||||
let selection = this._getSelection();
|
||||
|
||||
// Extend the phone number selection until we find a boundry.
|
||||
while (true) {
|
||||
// Save current focus position, and extend the selection.
|
||||
let focusNode = selection.focusNode;
|
||||
let focusOffset = selection.focusOffset;
|
||||
selection.modify("extend", direction, "character");
|
||||
|
||||
// If the selection doesn't change, (can't extend further), we're done.
|
||||
if (selection.focusNode == focusNode && selection.focusOffset == focusOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't extend past a valid phone number.
|
||||
if (!this._isPhoneNumber(selection.toString().trim())) {
|
||||
// Backout the undesired selection extend, and we're done.
|
||||
selection.collapse(selection.anchorNode, selection.anchorOffset);
|
||||
selection.extend(focusNode, focusOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't extend the selection into a new container.
|
||||
if (selection.focusNode != focusNode) {
|
||||
let nextContainer = (selection.focusNode instanceof Text) ?
|
||||
selection.focusNode.parentNode : selection.focusNode;
|
||||
if (nextContainer.mozMatchesSelector &&
|
||||
nextContainer.mozMatchesSelector(PHONE_NUMBER_CONTAINERS)) {
|
||||
// Backout the undesired selection extend, and we're done.
|
||||
selection.collapse(selection.anchorNode, selection.anchorOffset);
|
||||
selection.extend(focusNode, focusOffset);
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Reverse the the selection direction, swapping anchorNode <-+-> focusNode.
|
||||
*/
|
||||
_reversePhoneNumberSelectionDir: function(direction) {
|
||||
let selection = this._getSelection();
|
||||
|
||||
let anchorNode = selection.anchorNode;
|
||||
let anchorOffset = selection.anchorOffset;
|
||||
selection.collapse(selection.focusNode, selection.focusOffset);
|
||||
selection.extend(anchorNode, anchorOffset);
|
||||
},
|
||||
|
||||
/* Return true if the current selection (given by aPositions) is near to where the coordinates passed in */
|
||||
_selectionNearClick: function(aX, aY, aPositions) {
|
||||
let distance = 0;
|
||||
|
@ -380,6 +380,7 @@
|
||||
@BINPATH@/components/nsInputListAutoComplete.js
|
||||
@BINPATH@/components/formautofill.manifest
|
||||
@BINPATH@/components/FormAutofillContentService.js
|
||||
@BINPATH@/components/FormAutofillStartup.js
|
||||
@BINPATH@/components/contentSecurityPolicy.manifest
|
||||
@BINPATH@/components/contentSecurityPolicy.js
|
||||
@BINPATH@/components/contentAreaDropListener.manifest
|
||||
|
@ -27,6 +27,12 @@
|
||||
* // Bind a function with a tag to replace a bespoke dump/log/debug function:
|
||||
* let debug = Log.d.bind(null, "MyModule");
|
||||
* debug("This is a debug message.");
|
||||
* // Outputs "D/GeckoMyModule(#####): This is a debug message."
|
||||
*
|
||||
* // Or "bind" the module object to a tag to automatically tag messages:
|
||||
* Log = Log.bind("MyModule");
|
||||
* Log.d("This is a debug message.");
|
||||
* // Outputs "D/GeckoMyModule(#####): This is a debug message."
|
||||
*
|
||||
* Note: the module automatically prepends "Gecko" to the tag you specify,
|
||||
* since all tags used by Fennec code should start with that string; and it
|
||||
@ -67,6 +73,17 @@ let AndroidLog = {
|
||||
i: (tag, msg) => __android_log_write(ANDROID_LOG_INFO, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
|
||||
w: (tag, msg) => __android_log_write(ANDROID_LOG_WARN, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
|
||||
e: (tag, msg) => __android_log_write(ANDROID_LOG_ERROR, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
|
||||
|
||||
bind: function(tag) {
|
||||
return {
|
||||
MAX_TAG_LENGTH: MAX_TAG_LENGTH,
|
||||
v: AndroidLog.v.bind(null, tag),
|
||||
d: AndroidLog.d.bind(null, tag),
|
||||
i: AndroidLog.i.bind(null, tag),
|
||||
w: AndroidLog.w.bind(null, tag),
|
||||
e: AndroidLog.e.bind(null, tag),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof Components == "undefined") {
|
||||
|
@ -260,11 +260,13 @@ nsAutoCompleteController::HandleEnter(bool aIsPopupSelection, bool *_retval)
|
||||
if (!mInput)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
|
||||
// allow the event through unless there is something selected in the popup
|
||||
mInput->GetPopupOpen(_retval);
|
||||
input->GetPopupOpen(_retval);
|
||||
if (*_retval) {
|
||||
nsCOMPtr<nsIAutoCompletePopup> popup;
|
||||
mInput->GetPopup(getter_AddRefs(popup));
|
||||
input->GetPopup(getter_AddRefs(popup));
|
||||
|
||||
if (popup) {
|
||||
int32_t selectedIndex;
|
||||
@ -287,8 +289,10 @@ nsAutoCompleteController::HandleEscape(bool *_retval)
|
||||
if (!mInput)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
|
||||
// allow the event through if the popup is closed
|
||||
mInput->GetPopupOpen(_retval);
|
||||
input->GetPopupOpen(_retval);
|
||||
|
||||
// Stop all searches in case they are async.
|
||||
StopSearch();
|
||||
@ -986,16 +990,18 @@ nsAutoCompleteController::ClosePopup()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
|
||||
bool isOpen = false;
|
||||
mInput->GetPopupOpen(&isOpen);
|
||||
input->GetPopupOpen(&isOpen);
|
||||
if (!isOpen)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompletePopup> popup;
|
||||
mInput->GetPopup(getter_AddRefs(popup));
|
||||
input->GetPopup(getter_AddRefs(popup));
|
||||
NS_ENSURE_TRUE(popup != nullptr, NS_ERROR_FAILURE);
|
||||
popup->SetSelectedIndex(-1);
|
||||
return mInput->SetPopupOpen(false);
|
||||
return input->SetPopupOpen(false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1114,9 +1120,11 @@ nsAutoCompleteController::StartSearches()
|
||||
if (mTimer || !mInput)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
|
||||
// Get the timeout for delayed searches.
|
||||
uint32_t timeout;
|
||||
mInput->GetTimeout(&timeout);
|
||||
input->GetTimeout(&timeout);
|
||||
|
||||
uint32_t immediateSearchesCount = mImmediateSearchesCount;
|
||||
if (timeout == 0) {
|
||||
@ -1442,10 +1450,12 @@ nsAutoCompleteController::CompleteDefaultIndex(int32_t aResultIndex)
|
||||
if (mDefaultIndexCompleted || mBackspaced || mSearchString.Length() == 0 || !mInput)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
|
||||
int32_t selectionStart;
|
||||
mInput->GetSelectionStart(&selectionStart);
|
||||
input->GetSelectionStart(&selectionStart);
|
||||
int32_t selectionEnd;
|
||||
mInput->GetSelectionEnd(&selectionEnd);
|
||||
input->GetSelectionEnd(&selectionEnd);
|
||||
|
||||
// Don't try to automatically complete to the first result if there's already
|
||||
// a selection or the cursor isn't at the end of the input
|
||||
@ -1454,7 +1464,7 @@ nsAutoCompleteController::CompleteDefaultIndex(int32_t aResultIndex)
|
||||
return NS_OK;
|
||||
|
||||
bool shouldComplete;
|
||||
mInput->GetCompleteDefaultIndex(&shouldComplete);
|
||||
input->GetCompleteDefaultIndex(&shouldComplete);
|
||||
if (!shouldComplete)
|
||||
return NS_OK;
|
||||
|
||||
@ -1554,6 +1564,7 @@ nsresult
|
||||
nsAutoCompleteController::GetFinalDefaultCompleteValue(nsAString &_retval)
|
||||
{
|
||||
MOZ_ASSERT(mInput, "Must have a valid input");
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
nsIAutoCompleteResult *result;
|
||||
int32_t defaultIndex = -1;
|
||||
nsresult rv = GetDefaultCompleteResult(-1, &result, &defaultIndex);
|
||||
@ -1561,7 +1572,7 @@ nsAutoCompleteController::GetFinalDefaultCompleteValue(nsAString &_retval)
|
||||
|
||||
result->GetValueAt(defaultIndex, _retval);
|
||||
nsAutoString inputValue;
|
||||
mInput->GetTextValue(inputValue);
|
||||
input->GetTextValue(inputValue);
|
||||
if (!_retval.Equals(inputValue, nsCaseInsensitiveStringComparator())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1584,6 +1595,7 @@ nsAutoCompleteController::CompleteValue(nsString &aValue)
|
||||
* contained in mSearchString. */
|
||||
{
|
||||
MOZ_ASSERT(mInput, "Must have a valid input");
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
const int32_t mSearchStringLength = mSearchString.Length();
|
||||
int32_t endSelect = aValue.Length(); // By default, select all of aValue.
|
||||
|
||||
@ -1593,7 +1605,7 @@ nsAutoCompleteController::CompleteValue(nsString &aValue)
|
||||
// aValue is empty (we were asked to clear mInput), or mSearchString
|
||||
// matches the beginning of aValue. In either case we can simply
|
||||
// autocomplete to aValue.
|
||||
mInput->SetTextValue(aValue);
|
||||
input->SetTextValue(aValue);
|
||||
} else {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
|
||||
@ -1613,22 +1625,22 @@ nsAutoCompleteController::CompleteValue(nsString &aValue)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mInput->SetTextValue(mSearchString +
|
||||
Substring(aValue, mSearchStringLength + findIndex,
|
||||
endSelect));
|
||||
input->SetTextValue(mSearchString +
|
||||
Substring(aValue, mSearchStringLength + findIndex,
|
||||
endSelect));
|
||||
|
||||
endSelect -= findIndex; // We're skipping this many characters of aValue.
|
||||
} else {
|
||||
// Autocompleting something other than a URI from the middle.
|
||||
// Use the format "searchstring >> full string" to indicate to the user
|
||||
// what we are going to replace their search string with.
|
||||
mInput->SetTextValue(mSearchString + NS_LITERAL_STRING(" >> ") + aValue);
|
||||
input->SetTextValue(mSearchString + NS_LITERAL_STRING(" >> ") + aValue);
|
||||
|
||||
endSelect = mSearchString.Length() + 4 + aValue.Length();
|
||||
}
|
||||
}
|
||||
|
||||
mInput->SelectTextRange(mSearchStringLength, endSelect);
|
||||
input->SelectTextRange(mSearchStringLength, endSelect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -112,4 +112,18 @@ this.FormAutofill = {
|
||||
|
||||
this.integration = combined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes a requestAutocomplete message asynchronously.
|
||||
*
|
||||
* @param aData
|
||||
* Provided to FormAutofillIntegration.createRequestAutocompleteUI.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves Structured data received from the requestAutocomplete UI.
|
||||
*/
|
||||
processRequestAutocomplete: Task.async(function* (aData) {
|
||||
let ui = yield FormAutofill.integration.createRequestAutocompleteUI(aData);
|
||||
return yield ui.show();
|
||||
}),
|
||||
};
|
||||
|
@ -95,8 +95,37 @@ FormHandler.prototype = {
|
||||
return "disabled";
|
||||
}
|
||||
|
||||
let ui = yield FormAutofill.integration.createRequestAutocompleteUI(data);
|
||||
let result = yield ui.show();
|
||||
// Access the frame message manager of the window starting the request.
|
||||
let rootDocShell = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.sameTypeRootTreeItem
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
let frameMM = rootDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
||||
// We need to set up a temporary message listener for our result before we
|
||||
// send the request to the parent process. At present, there is no check
|
||||
// for reentrancy (bug 1020459), thus it is possible that we'll receive a
|
||||
// message for a different request, but this will not be normally allowed.
|
||||
let promiseRequestAutocompleteResult = new Promise((resolve, reject) => {
|
||||
frameMM.addMessageListener("FormAutofill:RequestAutocompleteResult",
|
||||
function onResult(aMessage) {
|
||||
frameMM.removeMessageListener(
|
||||
"FormAutofill:RequestAutocompleteResult", onResult);
|
||||
// Exceptions in the parent process are serialized and propagated in
|
||||
// the response message that we received.
|
||||
if ("exception" in aMessage.data) {
|
||||
reject(aMessage.data.exception);
|
||||
} else {
|
||||
resolve(aMessage.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Send the message to the parent process, and wait for the result. This
|
||||
// will throw an exception if one occurred in the parent process.
|
||||
frameMM.sendAsyncMessage("FormAutofill:RequestAutocomplete", data);
|
||||
let result = yield promiseRequestAutocompleteResult;
|
||||
if (result.canceled) {
|
||||
return "cancel";
|
||||
}
|
||||
|
64
toolkit/components/formautofill/FormAutofillStartup.js
Normal file
64
toolkit/components/formautofill/FormAutofillStartup.js
Normal file
@ -0,0 +1,64 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Handles startup in the parent process.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofill",
|
||||
"resource://gre/modules/FormAutofill.jsm");
|
||||
|
||||
/**
|
||||
* Handles startup in the parent process.
|
||||
*/
|
||||
function FormAutofillStartup() {
|
||||
}
|
||||
|
||||
FormAutofillStartup.prototype = {
|
||||
classID: Components.ID("{51c95b3d-7431-467b-8d50-383f158ce9e5}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIFrameMessageListener,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
]),
|
||||
|
||||
// nsIObserver
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
// This method is called by the "profile-after-change" category on startup,
|
||||
// which is called before any web page loads. At this time, we need to
|
||||
// register a global message listener in the parent process preemptively,
|
||||
// because we can receive requests from child processes at any time. For
|
||||
// performance reasons, we use this object as a message listener, so that we
|
||||
// don't have to load the FormAutoFill module at startup.
|
||||
let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
globalMM.addMessageListener("FormAutofill:RequestAutocomplete", this);
|
||||
},
|
||||
|
||||
// nsIFrameMessageListener
|
||||
receiveMessage: function (aMessage) {
|
||||
// Process the "FormAutofill:RequestAutocomplete" message. Any exception
|
||||
// raised in the parent process is caught and serialized into the reply
|
||||
// message that is sent to the requesting child process.
|
||||
FormAutofill.processRequestAutocomplete(aMessage.data)
|
||||
.catch(ex => { exception: ex })
|
||||
.then(result => {
|
||||
// The browser message manager in the parent will send the reply to the
|
||||
// associated frame message manager in the child.
|
||||
let browserMM = aMessage.target.messageManager;
|
||||
browserMM.sendAsyncMessage("FormAutofill:RequestAutocompleteResult",
|
||||
result);
|
||||
})
|
||||
.catch(Cu.reportError);
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FormAutofillStartup]);
|
@ -1,2 +1,7 @@
|
||||
component {ed9c2c3c-3f86-4ae5-8e31-10f71b0f19e6} FormAutofillContentService.js
|
||||
contract @mozilla.org/formautofill/content-service;1 {ed9c2c3c-3f86-4ae5-8e31-10f71b0f19e6}
|
||||
component {51c95b3d-7431-467b-8d50-383f158ce9e5} FormAutofillStartup.js
|
||||
contract @mozilla.org/formautofill/startup;1 {51c95b3d-7431-467b-8d50-383f158ce9e5}
|
||||
#ifdef NIGHTLY_BUILD
|
||||
category profile-after-change FormAutofillStartup @mozilla.org/formautofill/startup;1
|
||||
#endif
|
||||
|
@ -4,13 +4,14 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
'test/browser/browser.ini',
|
||||
]
|
||||
if CONFIG['NIGHTLY_BUILD']:
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
'test/browser/browser.ini',
|
||||
]
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += [
|
||||
'test/chrome/chrome.ini',
|
||||
]
|
||||
MOCHITEST_CHROME_MANIFESTS += [
|
||||
'test/chrome/chrome.ini',
|
||||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/xpcshell/xpcshell.ini',
|
||||
@ -23,8 +24,12 @@ XPIDL_SOURCES += [
|
||||
XPIDL_MODULE = 'toolkit_formautofill'
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'formautofill.manifest',
|
||||
'FormAutofillContentService.js',
|
||||
'FormAutofillStartup.js',
|
||||
]
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'formautofill.manifest',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
|
@ -13,3 +13,11 @@
|
||||
// xpcshell specific test initialization here. If you need shared functions or
|
||||
// initialization that are not specific to xpcshell, consider adding them to
|
||||
// "head_common.js" in the parent folder instead.
|
||||
|
||||
add_task_in_parent_process(function* test_xpcshell_initialize_profile() {
|
||||
// We need to send the profile-after-change notification manually to the
|
||||
// startup component to ensure it has been initialized.
|
||||
Cc["@mozilla.org/formautofill/startup;1"]
|
||||
.getService(Ci.nsIObserver)
|
||||
.observe(null, "profile-after-change", "");
|
||||
});
|
||||
|
@ -134,17 +134,20 @@ function* check_autocomplete(test) {
|
||||
|
||||
// Check to see the expected uris and titles match up (in any order)
|
||||
if (test.matches) {
|
||||
// Do not modify the test original matches.
|
||||
let matches = test.matches.slice();
|
||||
|
||||
for (let i = 0; i < controller.matchCount; i++) {
|
||||
let value = controller.getValueAt(i);
|
||||
let comment = controller.getCommentAt(i);
|
||||
do_log_info("Looking for '" + value + "', '" + comment + "' in expected results...");
|
||||
let j;
|
||||
for (j = 0; j < test.matches.length; j++) {
|
||||
for (j = 0; j < matches.length; j++) {
|
||||
// Skip processed expected results
|
||||
if (test.matches[j] == undefined)
|
||||
if (matches[j] == undefined)
|
||||
continue;
|
||||
|
||||
let { uri, title, tags } = test.matches[j];
|
||||
let { uri, title, tags } = matches[j];
|
||||
if (tags)
|
||||
title += " \u2013 " + tags.sort().join(", ");
|
||||
|
||||
@ -153,7 +156,7 @@ function* check_autocomplete(test) {
|
||||
if (stripPrefix(uri.spec) == stripPrefix(value) && title == comment) {
|
||||
do_log_info("Got a match at index " + j + "!");
|
||||
// Make it undefined so we don't process it again
|
||||
test.matches[j] = undefined;
|
||||
matches[j] = undefined;
|
||||
if (uri.spec.startsWith("moz-action:")) {
|
||||
let style = controller.getStyleAt(i);
|
||||
Assert.ok(style.contains("action"));
|
||||
@ -163,15 +166,15 @@ function* check_autocomplete(test) {
|
||||
}
|
||||
|
||||
// We didn't hit the break, so we must have not found it
|
||||
if (j == test.matches.length)
|
||||
if (j == matches.length)
|
||||
do_throw("Didn't find the current result ('" + value + "', '" + comment + "') in matches");
|
||||
}
|
||||
|
||||
Assert.equal(controller.matchCount, test.matches.length,
|
||||
Assert.equal(controller.matchCount, matches.length,
|
||||
"Got as many results as expected");
|
||||
|
||||
// If we expect results, make sure we got matches.
|
||||
do_check_eq(controller.searchStatus, test.matches.length ?
|
||||
do_check_eq(controller.searchStatus, matches.length ?
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH :
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ add_task(function* test_swap_protocol() {
|
||||
{ uri: uri6, title: "title" }
|
||||
];
|
||||
|
||||
// Disable autoFill to avoid handling the first result.
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill", "false");
|
||||
|
||||
do_log_info("http://www.site matches all site");
|
||||
@ -45,7 +46,7 @@ add_task(function* test_swap_protocol() {
|
||||
search: "http://www.site",
|
||||
matches: allMatches
|
||||
});
|
||||
/*
|
||||
|
||||
do_log_info("http://site matches all site");
|
||||
yield check_autocomplete({
|
||||
search: "http://site",
|
||||
@ -55,7 +56,7 @@ add_task(function* test_swap_protocol() {
|
||||
do_log_info("ftp://ftp.site matches itself");
|
||||
yield check_autocomplete({
|
||||
search: "ftp://ftp.site",
|
||||
matches: { uri: uri3, title: "title"}
|
||||
matches: [ { uri: uri3, title: "title" } ]
|
||||
});
|
||||
|
||||
do_log_info("ftp://site matches all site");
|
||||
@ -144,6 +145,6 @@ add_task(function* test_swap_protocol() {
|
||||
search: "http://www.www",
|
||||
matches: [ { uri: uri8, title: "title" } ]
|
||||
});
|
||||
*/
|
||||
|
||||
yield cleanup();
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
@ -19,7 +19,14 @@ Object.defineProperty(this, "QRErrorCorrectLevel", {
|
||||
get: () => require("./encoder/index").QRErrorCorrectLevel
|
||||
});
|
||||
Object.defineProperty(this, "decoder", {
|
||||
get: () => require("./decoder/index")
|
||||
get: () => {
|
||||
// Some applications don't ship the decoder, see moz.build
|
||||
try {
|
||||
return require("./decoder/index");
|
||||
} catch(e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@ -86,6 +93,9 @@ exports.encodeToDataURI = function(message, quality, version) {
|
||||
* the QR code.
|
||||
*/
|
||||
exports.decodeFromURI = function(URI) {
|
||||
if (!decoder) {
|
||||
return promise.reject();
|
||||
}
|
||||
let deferred = promise.defer();
|
||||
decoder.decodeFromURI(URI, deferred.resolve, deferred.reject);
|
||||
return deferred.promise;
|
||||
@ -99,5 +109,8 @@ exports.decodeFromURI = function(URI) {
|
||||
* The data inside the QR code
|
||||
*/
|
||||
exports.decodeFromCanvas = function(canvas) {
|
||||
if (!decoder) {
|
||||
throw new Error("Decoder not available");
|
||||
}
|
||||
return decoder.decodeFromCanvas(canvas);
|
||||
};
|
||||
|
@ -5,10 +5,15 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += [
|
||||
'decoder',
|
||||
'encoder'
|
||||
]
|
||||
|
||||
# Save file size on Fennec until there are active plans to use the decoder there
|
||||
if CONFIG['MOZ_BUILD_APP'] != 'mobile/android':
|
||||
DIRS += [
|
||||
'decoder'
|
||||
]
|
||||
|
||||
JS_MODULES_PATH = 'modules/devtools/qrcode'
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
|
@ -294,11 +294,6 @@ nsUXThemeData::UpdateNativeThemeInfo()
|
||||
sIsDefaultWindowsTheme = false;
|
||||
sThemeId = LookAndFeel::eWindowsTheme_Generic;
|
||||
|
||||
if (!IsAppThemed()) {
|
||||
sThemeId = LookAndFeel::eWindowsTheme_Classic;
|
||||
return;
|
||||
}
|
||||
|
||||
HIGHCONTRAST highContrastInfo;
|
||||
highContrastInfo.cbSize = sizeof(HIGHCONTRAST);
|
||||
if (SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &highContrastInfo, 0)) {
|
||||
@ -307,6 +302,11 @@ nsUXThemeData::UpdateNativeThemeInfo()
|
||||
sIsHighContrastOn = false;
|
||||
}
|
||||
|
||||
if (!IsAppThemed()) {
|
||||
sThemeId = LookAndFeel::eWindowsTheme_Classic;
|
||||
return;
|
||||
}
|
||||
|
||||
WCHAR themeFileName[MAX_PATH + 1];
|
||||
WCHAR themeColor[MAX_PATH + 1];
|
||||
if (FAILED(GetCurrentThemeName(themeFileName,
|
||||
|
Loading…
Reference in New Issue
Block a user