Bug 1042196 - Provide a wifi button on error pages. r=mfinkle

This commit is contained in:
Wes Johnston 2014-08-25 16:19:25 -07:00
Родитель 43e2232e2c
Коммит 4ab5278cbd
5 изменённых файлов: 163 добавлений и 48 удалений

Просмотреть файл

@ -6,6 +6,9 @@
package org.mozilla.gecko; package org.mozilla.gecko;
import org.mozilla.gecko.mozglue.JNITarget; import org.mozilla.gecko.mozglue.JNITarget;
import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.EventCallback;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@ -31,7 +34,7 @@ import android.util.Log;
* connection type defined in Network Information API version 3. * connection type defined in Network Information API version 3.
*/ */
public class GeckoNetworkManager extends BroadcastReceiver { public class GeckoNetworkManager extends BroadcastReceiver implements NativeEventListener {
private static final String LOGTAG = "GeckoNetworkManager"; private static final String LOGTAG = "GeckoNetworkManager";
static private final GeckoNetworkManager sInstance = new GeckoNetworkManager(); static private final GeckoNetworkManager sInstance = new GeckoNetworkManager();
@ -93,6 +96,8 @@ public class GeckoNetworkManager extends BroadcastReceiver {
if (mShouldNotify) { if (mShouldNotify) {
startListening(); startListening();
} }
EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener)this, "Wifi:Enable");
} }
private void startListening() { private void startListening() {
@ -112,6 +117,25 @@ public class GeckoNetworkManager extends BroadcastReceiver {
if (mShouldNotify) { if (mShouldNotify) {
stopListening(); stopListening();
} }
EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEventListener)this, "Wifi:Enable");
}
@Override
public void handleMessage(final String event, final NativeJSObject message,
final EventCallback callback) {
if (event.equals("Wifi:Enable")) {
final WifiManager mgr = (WifiManager) mApplicationContext.getSystemService(Context.WIFI_SERVICE);
if (!mgr.isWifiEnabled()) {
mgr.setWifiEnabled(true);
} else {
// If Wifi is enabled, maybe you need to select a network
Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mApplicationContext.startActivity(intent);
}
}
} }
private void stopListening() { private void stopListening() {

Просмотреть файл

@ -299,24 +299,24 @@
</div> </div>
<div id="errorDescriptionsContainer"> <div id="errorDescriptionsContainer">
<div id="ed_generic">&generic.longDesc;</div> <div id="ed_generic">&generic.longDesc;</div>
<div id="ed_dnsNotFound">&dnsNotFound.longDesc2;</div> <div id="ed_dnsNotFound">&dnsNotFound.longDesc3;</div>
<div id="ed_fileNotFound">&fileNotFound.longDesc;</div> <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
<div id="ed_malformedURI">&malformedURI.longDesc;</div> <div id="ed_malformedURI">&malformedURI.longDesc;</div>
<div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div> <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
<div id="ed_connectionFailure">&connectionFailure.longDesc;</div> <div id="ed_connectionFailure">&connectionFailure.longDesc;</div>
<div id="ed_netTimeout">&netTimeout.longDesc;</div> <div id="ed_netTimeout">&netTimeout.longDesc2;</div>
<div id="ed_redirectLoop">&redirectLoop.longDesc;</div> <div id="ed_redirectLoop">&redirectLoop.longDesc;</div>
<div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div> <div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div>
<div id="ed_netReset">&netReset.longDesc;</div> <div id="ed_netReset">&netReset.longDesc2;</div>
<div id="ed_notCached">&notCached.longDesc;</div> <div id="ed_notCached">&notCached.longDesc;</div>
<!-- Change longDesc from netOffline to connectionFailure, <!-- Change longDesc from netOffline to connectionFailure,
suggesting user to check their wifi/cell_data connection --> suggesting user to check their wifi/cell_data connection -->
<div id="ed_netOffline">&connectionFailure.longDesc;</div> <div id="ed_netOffline">&connectionFailure.longDesc2;</div>
<div id="ed_netInterrupt">&netInterrupt.longDesc;</div> <div id="ed_netInterrupt">&netInterrupt.longDesc2;</div>
<div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div> <div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
<div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc2;</div> <div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc3;</div>
<div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div> <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
<div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div> <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
<div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div> <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>

Просмотреть файл

@ -5,7 +5,9 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components; const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Messaging.jsm"); Cu.import("resource://gre/modules/Messaging.jsm");
Cu.import("resource://gre/modules/UITelemetry.jsm");
this.EXPORTED_SYMBOLS = ["NetErrorHelper"]; this.EXPORTED_SYMBOLS = ["NetErrorHelper"];
@ -59,3 +61,73 @@ NetErrorHelper.prototype = {
} }
}, },
} }
handlers.wifi = {
// This registers itself with the nsIObserverService as a weak ref,
// so we have to implement GetWeakReference as well.
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
GetWeakReference: function() {
return Cu.getWeakReference(this);
},
onPageShown: function(browser) {
// If we have a connection, don't bother showing the wifi toggle.
let network = Cc["@mozilla.org/network/network-link-service;1"].getService(Ci.nsINetworkLinkService);
if (network.isLinkUp && network.linkStatusKnown) {
let nodes = browser.contentDocument.querySelectorAll("#wifi");
for (let i = 0; i < nodes.length; i++) {
nodes[i].style.display = "none";
}
}
},
handleClick: function(event) {
let node = event.target;
while(node && node.id !== "wifi") {
node = node.parentNode;
}
if (!node) {
return;
}
UITelemetry.addEvent("neterror.1", "button", "wifitoggle");
// Show indeterminate progress while we wait for the network.
node.disabled = true;
node.classList.add("inProgress");
this.node = Cu.getWeakReference(node);
Services.obs.addObserver(this, "network:link-status-changed", true);
sendMessageToJava({
type: "Wifi:Enable"
});
},
observe: function(subject, topic, data) {
let node = this.node.get();
if (!node) {
return;
}
// Remove the progress bar
node.disabled = false;
node.classList.remove("inProgress");
let network = Cc["@mozilla.org/network/network-link-service;1"].getService(Ci.nsINetworkLinkService);
if (network.isLinkUp && network.linkStatusKnown) {
// If everything worked, reload the page
UITelemetry.addEvent("neterror.1", "button", "wifitoggle.reload");
Services.obs.removeObserver(this, "network:link-status-changed");
// Even at this point, Android sometimes lies about the real state of the network and this reload request fails.
// Add a 500ms delay before refreshing the page.
node.ownerDocument.defaultView.setTimeout(function() {
node.ownerDocument.location.reload(false);
}, 500);
}
}
}

Просмотреть файл

@ -7,6 +7,8 @@ body {
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100%; height: 100%;
--moz-vertical-spacing: 10px;
--moz-background-height: 32px;
} }
body { body {
@ -14,7 +16,7 @@ body {
background-image: linear-gradient(-45deg, #dfe8ee, #dfe8ee 33%, background-image: linear-gradient(-45deg, #dfe8ee, #dfe8ee 33%,
#ecf0f3 33%, #ecf0f3 66%, #ecf0f3 33%, #ecf0f3 66%,
#dfe8ee 66%, #dfe8ee); #dfe8ee 66%, #dfe8ee);
background-size: 64px 32px; background-size: 64px var(--moz-background-height);
background-repeat: repeat-x; background-repeat: repeat-x;
background-color: #f1f1f1; background-color: #f1f1f1;
@ -30,15 +32,22 @@ body {
ul { ul {
/* Shove the list indicator so that its left aligned, but use outside so that text /* Shove the list indicator so that its left aligned, but use outside so that text
* doesn't don't wrap the text around it */ * doesn't don't wrap the text around it */
padding: 1em; padding: 0 1em;
margin: 0; margin: 0;
list-style: round outside none; list-style: round outside none;
} }
li:not(:last-of-type), #errorShortDesc,
#errorLongDesc, li:not(:last-of-type) {
#errorLongContent { /* Margins between the li and buttons below it won't be collapsed. Remove the bottom margin here. */
padding-bottom: 10px; margin: var(--moz-vertical-spacing) 0;
}
li > button {
/* Removing the normal padding on the li so this stretched edge to edge. */
margin-left: -1em;
margin-right: -1em;
width: calc(100% + 2em);
} }
/* Push the #ignoreWarningButton to the bottom on the blocked site page */ /* Push the #ignoreWarningButton to the bottom on the blocked site page */
@ -47,7 +56,9 @@ li:not(:last-of-type),
} }
h1 { h1 {
padding: 1rem 0; margin: 0;
/* Since this has an underline, use padding for vertical spacing rather than margin */
padding: var(--moz-vertical-spacing) 0;
font-weight: 300; font-weight: 300;
border-bottom: 1px solid #e0e2e5; border-bottom: 1px solid #e0e2e5;
} }
@ -55,27 +66,39 @@ h1 {
h2 { h2 {
font-size: small; font-size: small;
padding: 0; padding: 0;
margin: 0; margin: var(--moz-vertical-spacing) 0;
} }
p { p {
margin-top: 0; margin: var(--moz-vertical-spacing) 0;
} }
button { button {
/* Force buttons to display: block here to try and enfoce collapsing margins */
display: block;
width: 100%; width: 100%;
border: none; border: none;
padding: 1rem; padding: 1rem;
font-family: sans-serif; font-family: sans-serif;
background-color: #e0e2e5; background-color: #e0e2e5;
font-size: 1rem; /* Not sure why this has to be specified. See bug 892843. */
font-weight: 300; font-weight: 300;
border-radius: 2px; border-radius: 2px;
background-image: none; background-image: none;
margin: var(--moz-vertical-spacing) 0 0;
} }
button + button { button.inProgress {
margin-top: 1em; background-image: linear-gradient(-45deg, #dfe8ee, #dfe8ee 33%,
#ecf0f3 33%, #ecf0f3 66%,
#dfe8ee 66%, #dfe8ee);
background-size: 37px 5px;
background-repeat: repeat-x;
animation: progress 6s linear infinite;
}
@keyframes progress {
from { background-position: 0 100%; }
to { background-position: 100% 100%; }
} }
.certerror { .certerror {
@ -96,11 +119,11 @@ button + button {
/* If the page is greater than 550px center the content. /* If the page is greater than 550px center the content.
* This number should be kept in sync with the media query for tablets below */ * This number should be kept in sync with the media query for tablets below */
max-width: 550px; max-width: 550px;
margin-left: auto; margin: 0 auto;
margin-right: auto; transform: translateY(var(--moz-background-height));
padding-top: 1rem; padding-bottom: var(--moz-vertical-spacing);
min-height: calc(100% - 1rem); min-height: calc(100% - var(--moz-background-height) - var(--moz-vertical-spacing));
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@ -113,7 +136,7 @@ button + button {
* *
* This shows an arrow to the right of the h2 element, and hides the content when collapsed="true". */ * This shows an arrow to the right of the h2 element, and hides the content when collapsed="true". */
.expander { .expander {
margin: 1rem 0; margin: var(--moz-vertical-spacing) 0;
background-image: url("chrome://browser/skin/images/dropmarker.svg"); background-image: url("chrome://browser/skin/images/dropmarker.svg");
background-repeat: no-repeat; background-repeat: no-repeat;
/* dropmarker.svg is 10x7. Ensure that its centered in the middle of an 18x18 box */ /* dropmarker.svg is 10x7. Ensure that its centered in the middle of an 18x18 box */
@ -122,12 +145,6 @@ button + button {
padding-left: 18px; padding-left: 18px;
} }
.expander:first-of-type {
/* Double the margin here so that the space above the first expander
* is the same as the space between multiple expanders */
margin-top: 20px;
}
div[collapsed="true"] > .expander { div[collapsed="true"] > .expander {
background-image: url("chrome://browser/skin/images/dropmarker-right.svg"); background-image: url("chrome://browser/skin/images/dropmarker-right.svg");
/* dropmarker.svg is 7x10. Ensure that its centered in the middle of an 18x18 box */ /* dropmarker.svg is 7x10. Ensure that its centered in the middle of an 18x18 box */
@ -174,10 +191,6 @@ div[collapsed="true"] > .expander + * {
width: auto; width: auto;
} }
button + button {
margin-top: 0;
}
/* If the tablet is tall as well, add some padding to make content feel a bit more centered */ /* If the tablet is tall as well, add some padding to make content feel a bit more centered */
@media (min-height: 550px) { @media (min-height: 550px) {
#errorPageContainer { #errorPageContainer {
@ -185,6 +198,4 @@ div[collapsed="true"] > .expander + * {
min-height: calc(100% - 64px); min-height: calc(100% - 64px);
} }
} }
} }

Просмотреть файл

@ -11,18 +11,20 @@
<!-- Specific error messages --> <!-- Specific error messages -->
<!ENTITY connectionFailure.title "Unable to connect"> <!ENTITY connectionFailure.title "Unable to connect">
<!ENTITY connectionFailure.longDesc "&sharedLongDesc2;"> <!ENTITY connectionFailure.longDesc2 "&sharedLongDesc3;">
<!ENTITY deniedPortAccess.title "This address is restricted"> <!ENTITY deniedPortAccess.title "This address is restricted">
<!ENTITY deniedPortAccess.longDesc ""> <!ENTITY deniedPortAccess.longDesc "">
<!ENTITY dnsNotFound.title "Server not found"> <!ENTITY dnsNotFound.title "Server not found">
<!ENTITY dnsNotFound.longDesc2 " <!ENTITY dnsNotFound.longDesc3 "
<ul> <ul>
<li>Check the address for typing errors such as <li>Check the address for typing errors such as
<strong>ww</strong>.example.com instead of <strong>ww</strong>.example.com instead of
<strong>www</strong>.example.com</li> <strong>www</strong>.example.com</li>
<li>If you are unable to load any pages, check your device's data or Wi-Fi connection.</li> <li>If you are unable to load any pages, check your device's data or Wi-Fi connection.
<button id='wifi'>Enable Wi-Fi</button>
</li>
</ul> </ul>
"> ">
@ -51,15 +53,17 @@
"> ">
<!ENTITY netInterrupt.title "The connection was interrupted"> <!ENTITY netInterrupt.title "The connection was interrupted">
<!ENTITY netInterrupt.longDesc "&sharedLongDesc2;"> <!ENTITY netInterrupt.longDesc2 "&sharedLongDesc3;">
<!ENTITY notCached.title "Document Expired"> <!ENTITY notCached.title "Document Expired">
<!ENTITY notCached.longDesc "<p>The requested document is not available in &brandShortName;'s cache.</p><ul><li>As a security precaution, &brandShortName; does not automatically re-request sensitive documents.</li><li>Click Try Again to re-request the document from the website.</li></ul>"> <!ENTITY notCached.longDesc "<p>The requested document is not available in &brandShortName;'s cache.</p><ul><li>As a security precaution, &brandShortName; does not automatically re-request sensitive documents.</li><li>Click Try Again to re-request the document from the website.</li></ul>">
<!ENTITY netOffline.title "Offline mode"> <!ENTITY netOffline.title "Offline mode">
<!ENTITY netOffline.longDesc2 " <!ENTITY netOffline.longDesc3 "
<ul> <ul>
<li>Try again. &brandShortName; will attempt to open a connection and reload the page.</li> <li>Try again. &brandShortName; will attempt to open a connection and reload the page.
<button id='wifi'>Enable Wi-Fi</button>
</li>
</ul> </ul>
"> ">
@ -78,10 +82,10 @@
"> ">
<!ENTITY netReset.title "The connection was reset"> <!ENTITY netReset.title "The connection was reset">
<!ENTITY netReset.longDesc "&sharedLongDesc2;"> <!ENTITY netReset.longDesc2 "&sharedLongDesc3;">
<!ENTITY netTimeout.title "The connection has timed out"> <!ENTITY netTimeout.title "The connection has timed out">
<!ENTITY netTimeout.longDesc "&sharedLongDesc2;"> <!ENTITY netTimeout.longDesc2 "&sharedLongDesc3;">
<!ENTITY unknownProtocolFound.title "The address wasn't understood"> <!ENTITY unknownProtocolFound.title "The address wasn't understood">
<!ENTITY unknownProtocolFound.longDesc " <!ENTITY unknownProtocolFound.longDesc "
@ -100,10 +104,12 @@
"> ">
<!ENTITY proxyResolveFailure.title "Unable to find the proxy server"> <!ENTITY proxyResolveFailure.title "Unable to find the proxy server">
<!ENTITY proxyResolveFailure.longDesc2 " <!ENTITY proxyResolveFailure.longDesc3 "
<ul> <ul>
<li>Check the proxy settings to make sure that they are correct.</li> <li>Check the proxy settings to make sure that they are correct.</li>
<li>Check to make sure your device has a working data or Wi-Fi connection.</li> <li>Check to make sure your device has a working data or Wi-Fi connection.
<button id='wifi'>Enable Wi-Fi</button>
</li>
</ul> </ul>
"> ">
@ -142,10 +148,12 @@ be temporary, and you can try again later.</li>
</ul> </ul>
"> ">
<!ENTITY sharedLongDesc2 " <!ENTITY sharedLongDesc3 "
<ul> <ul>
<li>The site could be temporarily unavailable or too busy. Try again in a few moments.</li> <li>The site could be temporarily unavailable or too busy. Try again in a few moments.</li>
<li>If you are unable to load any pages, check your mobile device's data or Wi-Fi connection.</li> <li>If you are unable to load any pages, check your mobile device's data or Wi-Fi connection.
<button id='wifi'>Enable Wi-Fi</button>
</li>
</ul> </ul>
"> ">