зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to m-i
This commit is contained in:
Коммит
95c5bfc8b9
|
@ -66,6 +66,16 @@ WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
|
|||
endif
|
||||
endif #LIBXUL_SDK
|
||||
|
||||
UA_UPDATE_FILE = ua-update.json
|
||||
|
||||
$(UA_UPDATE_FILE): % : %.in
|
||||
# strip out comment lines, which are not valid in JSON
|
||||
sed -e "/^ *\\/\\//d" -e "/^ *$$/d" $^ > $@
|
||||
|
||||
UA_UPDATE_FILES = $(UA_UPDATE_FILE)
|
||||
UA_UPDATE_DEST = $(FINAL_TARGET)
|
||||
INSTALL_TARGETS += UA_UPDATE
|
||||
|
||||
# Make sure the standalone glue doesn't try to get libxpcom.so from b2g/app.
|
||||
NSDISTMODE = copy
|
||||
|
||||
|
|
|
@ -736,6 +736,11 @@ pref("memory_info_dumper.watch_fifo.enabled", true);
|
|||
pref("memory_info_dumper.watch_fifo.directory", "/data/local");
|
||||
|
||||
pref("general.useragent.enable_overrides", true);
|
||||
// See ua-update.json.in for the packaged UA override list
|
||||
pref("general.useragent.updates.enabled", true);
|
||||
pref("general.useragent.updates.url", "");
|
||||
pref("general.useragent.updates.interval", 604800); // 1 week
|
||||
pref("general.useragent.updates.retry", 86400); // 1 day
|
||||
|
||||
// Make <audio> and <video> talk to the AudioChannelService.
|
||||
pref("media.useAudioChannelService", true);
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
// Comments must be on their own lines and must start with "//"
|
||||
|
||||
// Send these sites a custom user-agent. Bugs to remove each override after
|
||||
// evangelism are included.
|
||||
{
|
||||
// bug 802981, maps.google.com
|
||||
"maps.google.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826330, uol.com.br
|
||||
"uol.com.br": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826332, live.com
|
||||
"live.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826335, globo.com
|
||||
"globo.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826338, yahoo.com
|
||||
"yahoo.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826342, mercadolivre.com.br
|
||||
"mercadolivre.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826343, ig.com.br
|
||||
"ig.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826344, abril.com.br
|
||||
"abril.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826347, msn.com
|
||||
"msn.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826348, linkedin.com
|
||||
"linkedin.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826353, itau.com.br
|
||||
"itau.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826504, orkut.com.br
|
||||
"orkut.com.br": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826510, r7.com
|
||||
"r7.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826514, estadao.com.br
|
||||
"estadao.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826517, letras.mus.br
|
||||
"letras.mus.br": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826711, bb.com.br
|
||||
"bb.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826712, orkut.com
|
||||
"orkut.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 826715, noticias.uol.com.br
|
||||
"noticias.uol.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826720, olx.com.br
|
||||
"olx.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826736, bancobrasil.com.br
|
||||
"bancobrasil.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826845, techtudo.com.br
|
||||
"techtudo.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 826958, ebay.com
|
||||
"ebay.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827622, bing.com
|
||||
"bing.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827625, pagseguro.uol.com.br
|
||||
"pagseguro.uol.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827626, magazineluiza.com.br
|
||||
"magazineluiza.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827627, bol.uol.com.br
|
||||
"bol.uol.com.br": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 827628, groupon.com.br
|
||||
"groupon.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827630, vagalume.com.br
|
||||
"vagalume.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827631, climatempo.com.br
|
||||
"climatempo.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827632, tecmundo.com.br
|
||||
"tecmundo.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827633, hao123.com
|
||||
"hao123.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827576, lancenet.com.br
|
||||
"lancenet.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827573, webmotors.com.br
|
||||
"webmotors.com.br": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827661, mercadolibre.com.co
|
||||
"mercadolibre.com.co": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827664, elespectador.com
|
||||
"elespectador.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827668, scribd.com
|
||||
"scribd.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827670, elpais.com.co
|
||||
"elpais.com.co": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 827672, olx.com.co
|
||||
"olx.com.co": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827674, avianca.com
|
||||
"avianca.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827678, marca.com
|
||||
"marca.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828354, gazeta.pl
|
||||
"gazeta.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828360, sport.pl
|
||||
"sport.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828364, nk.pl
|
||||
"nk.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828366, wyborcza.biz
|
||||
"wyborcza.biz": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828369, money.pl
|
||||
"money.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828371, ingbank.pl
|
||||
"ingbank.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828376, plotek.pl
|
||||
"plotek.pl": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 828378, wyborcza.pl
|
||||
"wyborcza.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828380, deser.pl
|
||||
"deser.pl": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828386, ebay.es
|
||||
"ebay.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828392, infojobs.net
|
||||
"infojobs.net": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828399, antena3.com
|
||||
"antena3.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828401, ingdirect.es
|
||||
"ingdirect.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828403, fotocasa.es
|
||||
"fotocasa.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828406, orange.es
|
||||
"orange.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828414, paginasamarillas.es
|
||||
"paginasamarillas.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828416, loteriasyapuestas.es
|
||||
"loteriasyapuestas.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828418, bbva.es
|
||||
"bbva.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828422, publico.es
|
||||
"publico.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828425, mercadolibre.com.ve
|
||||
"mercadolibre.com.ve": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828433, olx.com.ve
|
||||
"olx.com.ve": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828439, movistar.com.ve
|
||||
"movistar.com.ve": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828445, bumeran.com.ve
|
||||
"bumeran.com.ve": "\\(Mobile#(Android; Mobile",
|
||||
// bug 828448, petardas.com
|
||||
"petardas.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 827869, mail.google.com
|
||||
"mail.google.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843109, enfemenino.com
|
||||
"enfemenino.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843112, movil.bankinter.es
|
||||
"movil.bankinter.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843114, einforma.com
|
||||
"einforma.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843116, wwwhatsnew.com
|
||||
"wwwhatsnew.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843119, askthebuilder.com
|
||||
"askthebuilder.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843121, tor.com
|
||||
"tor.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843124, maruccisports.com
|
||||
"maruccisports.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843126, es.playstation.com
|
||||
"es.playstation.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 843129, 11870.com
|
||||
"11870.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843200, iphonejuegosgratis.com
|
||||
"iphonejuegosgratis.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843132, comunio.es
|
||||
"comunio.es": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843134, news.google.com
|
||||
"news.google.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843136, deviantart.com
|
||||
"deviantart.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843137, nytimes.com
|
||||
"nytimes.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843139, consumersearch.com
|
||||
"consumersearch.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843141, foodily.com
|
||||
"foodily.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843197, icanhas.cheezburger.com
|
||||
"icanhas.cheezburger.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843151, citibank.com
|
||||
"citibank.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843153, games.com
|
||||
"games.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843156, orbitz.com
|
||||
"orbitz.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843158, starwoodhotels.com
|
||||
"starwoodhotels.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843160, ehow.com
|
||||
"ehow.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843162, urbanspoon.com
|
||||
"urbanspoon.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843165, virginatlantic.com
|
||||
"virginatlantic.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843168, cheaptickets.com
|
||||
"cheaptickets.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843172, zimbio.com
|
||||
"zimbio.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843176, tylted.com
|
||||
"tylted.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843178, txt2nite.com
|
||||
"txt2nite.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843181, slashgear.com
|
||||
"slashgear.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 843186, chevrolet.com
|
||||
"chevrolet.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 848854, deadline.com
|
||||
"deadline.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 866577, 3g.qq.com
|
||||
"3g.qq.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878222, arukereso.hu
|
||||
"arukereso.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878228, blikk.hu
|
||||
"blikk.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878230, citromail.hu
|
||||
"citromail.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878232, hazipatika.com
|
||||
"hazipatika.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878234, hvg.hu
|
||||
"hvg.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878236, jofogas.hu
|
||||
"jofogas.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878238, koponyeg.hu
|
||||
"koponyeg.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878240, kuruc.info
|
||||
"kuruc.info": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878242, nemzetisport.hu
|
||||
"nemzetisport.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878244, nlcafe.hu
|
||||
"nlcafe.hu": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 878246, port.hu
|
||||
"port.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878249, portfolio.hu
|
||||
"portfolio.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878253, vatera.hu
|
||||
"vatera.hu": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878255, 24sata.hr
|
||||
"24sata.hr": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878256, bet365.com
|
||||
"bet365.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878258, blackhatteam.com
|
||||
"blackhatteam.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878260, cdm.me
|
||||
"cdm.me": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878262, download.com
|
||||
"download.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878264, haber.ba
|
||||
"haber.ba": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878268, jutarnji.hr
|
||||
"jutarnji.hr": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878271, kurir-info.rs
|
||||
"kurir-info.rs": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878273, livescore.com
|
||||
"livescore.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878275, mondo.rs
|
||||
"mondo.rs": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878277, naslovi.net
|
||||
"naslovi.net": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878284, softonic.com
|
||||
"softonic.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878286, yandex.ru
|
||||
"yandex.ru": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878630, ask.com
|
||||
"ask.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878632, banorte.com
|
||||
"banorte.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878634, buenastareas.com
|
||||
"buenastareas.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878635, cnn.com
|
||||
"cnn.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
|
||||
// bug 878637, eluniversal.com.mx
|
||||
"eluniversal.com.mx": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878640, hootsuite.com
|
||||
"hootsuite.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878642, mercadolibre.com.mx
|
||||
"mercadolibre.com.mx": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878645, olx.com.mx
|
||||
"olx.com.mx": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878647, sat.gob.mx
|
||||
"sat.gob.mx": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878649, univision.com
|
||||
"univision.com": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878653, redstarbelgrade.info
|
||||
"redstarbelgrade.info": "\\(Mobile#(Android; Mobile",
|
||||
// bug 878655, vesti-online.com
|
||||
"vesti-online.com": "\\(Mobile#(Android; Mobile"
|
||||
}
|
|
@ -1342,3 +1342,56 @@ let SensorsListener = {
|
|||
|
||||
SensorsListener.init();
|
||||
#endif
|
||||
|
||||
// Calling this observer will cause a shutdown an a profile reset.
|
||||
// Use eg. : Services.obs.notifyObservers(null, 'b2g-reset-profile', null);
|
||||
Services.obs.addObserver(function resetProfile(subject, topic, data) {
|
||||
Services.obs.removeObserver(resetProfile, topic);
|
||||
|
||||
// Listening for 'profile-before-change2' which is late in the shutdown
|
||||
// sequence, but still has xpcom access.
|
||||
Services.obs.addObserver(function clearProfile(subject, topic, data) {
|
||||
Services.obs.removeObserver(clearProfile, topic);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let json = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
|
||||
json.initWithPath('/system/b2g/webapps/webapps.json');
|
||||
let toRemove = json.exists()
|
||||
// This is a user build, just rm -r /data/local /data/b2g/mozilla
|
||||
? ['/data/local', '/data/b2g/mozilla']
|
||||
// This is an eng build. We clear the profile and a set of files
|
||||
// under /data/local.
|
||||
: ['/data/b2g/mozilla',
|
||||
'/data/local/permissions.sqlite',
|
||||
'/data/local/storage',
|
||||
'/data/local/OfflineCache'];
|
||||
|
||||
toRemove.forEach(function(dir) {
|
||||
try {
|
||||
let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
|
||||
file.initWithPath(dir);
|
||||
file.remove(true);
|
||||
} catch(e) { dump(e); }
|
||||
});
|
||||
#else
|
||||
// Desktop builds.
|
||||
let profile = Services.dirsvc.get('ProfD', Ci.nsIFile);
|
||||
|
||||
// We don't want to remove everything from the profile, since this
|
||||
// would prevent us from starting up.
|
||||
let whitelist = ['defaults', 'extensions', 'settings.json',
|
||||
'user.js', 'webapps'];
|
||||
let enumerator = profile.directoryEntries;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let file = enumerator.getNext().QueryInterface(Ci.nsIFile);
|
||||
if (whitelist.indexOf(file.leafName) == -1) {
|
||||
file.remove(true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
},
|
||||
'profile-before-change2', false);
|
||||
|
||||
let appStartup = Cc['@mozilla.org/toolkit/app-startup;1']
|
||||
.getService(Ci.nsIAppStartup);
|
||||
appStartup.quit(Ci.nsIAppStartup.eForceQuit);
|
||||
}, 'b2g-reset-profile', false);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "d9e4d98a9fba0dec670fe2446bea31e464add944",
|
||||
"revision": "8547bf51868f3521d96129d4e9060cf98a0bd23e",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
@BINPATH@/mozsqlt3@DLL_SUFFIX@
|
||||
#endif
|
||||
@BINPATH@/blocklist.xml
|
||||
@BINPATH@/ua-update.json
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
@BINPATH@/run-mozilla.sh
|
||||
|
|
|
@ -1119,18 +1119,25 @@ var gBrowserInit = {
|
|||
// If the user manually opens the download manager before the timeout, the
|
||||
// downloads will start right away, and getting the service again won't hurt.
|
||||
setTimeout(function() {
|
||||
let DownloadsCommon =
|
||||
Cu.import("resource:///modules/DownloadsCommon.jsm", {}).DownloadsCommon;
|
||||
if (DownloadsCommon.useJSTransfer) {
|
||||
// Open the data link without initalizing nsIDownloadManager.
|
||||
DownloadsCommon.initializeAllDataLinks();
|
||||
} else {
|
||||
// Initalizing nsIDownloadManager will trigger the data link.
|
||||
Services.downloads;
|
||||
try {
|
||||
let DownloadsCommon =
|
||||
Cu.import("resource:///modules/DownloadsCommon.jsm", {}).DownloadsCommon;
|
||||
if (DownloadsCommon.useJSTransfer) {
|
||||
// Open the data link without initalizing nsIDownloadManager.
|
||||
DownloadsCommon.initializeAllDataLinks();
|
||||
let DownloadsTaskbar =
|
||||
Cu.import("resource:///modules/DownloadsTaskbar.jsm", {}).DownloadsTaskbar;
|
||||
DownloadsTaskbar.registerIndicator(window);
|
||||
} else {
|
||||
// Initalizing nsIDownloadManager will trigger the data link.
|
||||
Services.downloads;
|
||||
let DownloadTaskbarProgress =
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
||||
}
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
let DownloadTaskbarProgress =
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
||||
}, 10000);
|
||||
|
||||
// The object handling the downloads indicator is also initialized here in the
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
|
||||
/* 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 the download progress indicator in the taskbar.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"DownloadsTaskbar",
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gWinTaskbar", function () {
|
||||
if (!("@mozilla.org/windows-taskbar;1" in Cc)) {
|
||||
return null;
|
||||
}
|
||||
let winTaskbar = Cc["@mozilla.org/windows-taskbar;1"]
|
||||
.getService(Ci.nsIWinTaskbar);
|
||||
return winTaskbar.available && winTaskbar;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gMacTaskbarProgress", function () {
|
||||
return ("@mozilla.org/widget/macdocksupport;1" in Cc) &&
|
||||
Cc["@mozilla.org/widget/macdocksupport;1"]
|
||||
.getService(Ci.nsITaskbarProgress);
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadsTaskbar
|
||||
|
||||
/**
|
||||
* Handles the download progress indicator in the taskbar.
|
||||
*/
|
||||
this.DownloadsTaskbar = {
|
||||
/**
|
||||
* Underlying DownloadSummary providing the aggregate download information, or
|
||||
* null if the indicator has never been initialized.
|
||||
*/
|
||||
_summary: null,
|
||||
|
||||
/**
|
||||
* nsITaskbarProgress object to which download information is dispatched.
|
||||
* This can be null if the indicator has never been initialized or if the
|
||||
* indicator is currently hidden on Windows.
|
||||
*/
|
||||
_taskbarProgress: null,
|
||||
|
||||
/**
|
||||
* This method is called after a new browser window is opened, and ensures
|
||||
* that the download progress indicator is displayed in the taskbar.
|
||||
*
|
||||
* On Windows, the indicator is attached to the first browser window that
|
||||
* calls this method. When the window is closed, the indicator is moved to
|
||||
* another browser window, if available, in no particular order. When there
|
||||
* are no browser windows visible, the indicator is hidden.
|
||||
*
|
||||
* On Mac OS X, the indicator is initialized globally when this method is
|
||||
* called for the first time. Subsequent calls have no effect.
|
||||
*
|
||||
* @param aBrowserWindow
|
||||
* nsIDOMWindow object of the newly opened browser window to which the
|
||||
* indicator may be attached.
|
||||
*/
|
||||
registerIndicator: function (aBrowserWindow)
|
||||
{
|
||||
if (!this._taskbarProgress) {
|
||||
if (gMacTaskbarProgress) {
|
||||
// On Mac OS X, we have to register the global indicator only once.
|
||||
this._taskbarProgress = gMacTaskbarProgress;
|
||||
// Free the XPCOM reference on shutdown, to prevent detecting a leak.
|
||||
Services.obs.addObserver(() => {
|
||||
this._taskbarProgress = null;
|
||||
gMacTaskbarProgress = null;
|
||||
}, "quit-application-granted", false);
|
||||
} else if (gWinTaskbar) {
|
||||
// On Windows, the indicator is currently hidden because we have no
|
||||
// previous browser window, thus we should attach the indicator now.
|
||||
this._attachIndicator(aBrowserWindow);
|
||||
} else {
|
||||
// The taskbar indicator is not available on this platform.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the DownloadSummary object will be created asynchronously.
|
||||
if (!this._summary) {
|
||||
Downloads.getSummary(Downloads.ALL).then(summary => {
|
||||
// In case the method is re-entered, we simply ignore redundant
|
||||
// invocations of the callback, instead of keeping separate state.
|
||||
if (this._summary) {
|
||||
return;
|
||||
}
|
||||
this._summary = summary;
|
||||
return this._summary.addView(this);
|
||||
}).then(null, Cu.reportError);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* On Windows, attaches the taskbar indicator to the specified browser window.
|
||||
*/
|
||||
_attachIndicator: function (aWindow)
|
||||
{
|
||||
// Activate the indicator on the specified window.
|
||||
let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIXULWindow).docShell;
|
||||
this._taskbarProgress = gWinTaskbar.getTaskbarProgress(docShell);
|
||||
|
||||
// If the DownloadSummary object has already been created, we should update
|
||||
// the state of the new indicator, otherwise it will be updated as soon as
|
||||
// the DownloadSummary view is registered.
|
||||
if (this._summary) {
|
||||
this.onSummaryChanged();
|
||||
}
|
||||
|
||||
aWindow.addEventListener("unload", () => {
|
||||
// Locate another browser window, excluding the one being closed.
|
||||
let browserWindow = RecentWindow.getMostRecentBrowserWindow();
|
||||
if (browserWindow) {
|
||||
// Move the progress indicator to the other browser window.
|
||||
this._attachIndicator(browserWindow);
|
||||
} else {
|
||||
// The last browser window has been closed. We remove the reference to
|
||||
// the taskbar progress object so that the indicator will be registered
|
||||
// again on the next browser window that is opened.
|
||||
this._taskbarProgress = null;
|
||||
}
|
||||
}, false);
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadSummary view
|
||||
|
||||
onSummaryChanged: function ()
|
||||
{
|
||||
// If the last browser window has been closed, we have no indicator anymore.
|
||||
if (!this._taskbarProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) {
|
||||
this._taskbarProgress.setProgressState(
|
||||
Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0);
|
||||
} else {
|
||||
// For a brief moment before completion, some download components may
|
||||
// report more transferred bytes than the total number of bytes. Thus,
|
||||
// ensure that we never break the expectations of the progress indicator.
|
||||
let progressCurrentBytes = Math.min(this._summary.progressTotalBytes,
|
||||
this._summary.progressCurrentBytes);
|
||||
this._taskbarProgress.setProgressState(
|
||||
Ci.nsITaskbarProgress.STATE_NORMAL,
|
||||
progressCurrentBytes,
|
||||
this._summary.progressTotalBytes);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -13,5 +13,6 @@ EXTRA_COMPONENTS += [
|
|||
EXTRA_JS_MODULES += [
|
||||
'DownloadsCommon.jsm',
|
||||
'DownloadsLogger.jsm',
|
||||
'DownloadsTaskbar.jsm',
|
||||
]
|
||||
|
||||
|
|
|
@ -215,34 +215,27 @@
|
|||
accesskey="&newWindowsAsTabs.accesskey;"
|
||||
preference="browser.link.open_newwindow"
|
||||
onsyncfrompreference="return gMainPane.readLinkTarget();"
|
||||
onsynctopreference="return gMainPane.writeLinkTarget();"
|
||||
class="indent"/>
|
||||
onsynctopreference="return gMainPane.writeLinkTarget();"/>
|
||||
|
||||
<checkbox id="warnCloseMultiple" label="&warnCloseMultipleTabs.label;"
|
||||
accesskey="&warnCloseMultipleTabs.accesskey;"
|
||||
preference="browser.tabs.warnOnClose"
|
||||
class="indent"/>
|
||||
preference="browser.tabs.warnOnClose"/>
|
||||
|
||||
<checkbox id="warnOpenMany" label="&warnOpenManyTabs.label;"
|
||||
accesskey="&warnOpenManyTabs.accesskey;"
|
||||
preference="browser.tabs.warnOnOpen"
|
||||
class="indent"/>
|
||||
preference="browser.tabs.warnOnOpen"/>
|
||||
|
||||
<checkbox id="restoreOnDemand" label="&restoreTabsOnDemand.label;"
|
||||
accesskey="&restoreTabsOnDemand.accesskey;"
|
||||
preference="browser.sessionstore.restore_on_demand"
|
||||
class="indent"/>
|
||||
preference="browser.sessionstore.restore_on_demand"/>
|
||||
|
||||
<checkbox id="switchToNewTabs" label="&switchToNewTabs.label;"
|
||||
accesskey="&switchToNewTabs.accesskey;"
|
||||
preference="browser.tabs.loadInBackground"
|
||||
class="indent"/>
|
||||
preference="browser.tabs.loadInBackground"/>
|
||||
|
||||
#ifdef XP_WIN
|
||||
<checkbox id="showTabsInTaskbar" label="&showTabsInTaskbar.label;"
|
||||
accesskey="&showTabsInTaskbar.accesskey;"
|
||||
preference="browser.taskbar.previews.enable"
|
||||
class="indent"/>
|
||||
preference="browser.taskbar.previews.enable"/>
|
||||
#endif
|
||||
|
||||
</groupbox>
|
||||
|
|
|
@ -22,6 +22,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_dbg_breakpoints-pane.js \
|
||||
browser_dbg_chrome-debugging.js \
|
||||
browser_dbg_clean-exit.js \
|
||||
browser_dbg_clean-exit-window.js \
|
||||
browser_dbg_cmd-blackbox.js \
|
||||
browser_dbg_cmd-break.js \
|
||||
browser_dbg_cmd-dbg.js \
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that closing a window with the debugger in a paused state exits cleanly.
|
||||
*/
|
||||
|
||||
let gDebuggee, gPanel, gDebugger, gWindow;
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
function test() {
|
||||
addWindow(TAB_URL)
|
||||
.then(win => initDebugger(TAB_URL, win))
|
||||
.then(([aTab, aDebuggee, aPanel, aWindow]) => {
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gWindow = aWindow;
|
||||
|
||||
return testCleanExit(gWindow);
|
||||
})
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
}
|
||||
|
||||
function testCleanExit(aWindow) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gWindow = aWindow;
|
||||
ok(!!gWindow, "Second window created.");
|
||||
|
||||
gWindow.focus();
|
||||
|
||||
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
is(topWindow, gWindow,
|
||||
"The second window is on top.");
|
||||
|
||||
let isActive = promise.defer();
|
||||
let isLoaded = promise.defer();
|
||||
|
||||
promise.all([isActive.promise, isLoaded.promise]).then(() => {
|
||||
gWindow.BrowserChromeTest.runWhenReady(() => {
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 16).then(() => {
|
||||
is(gDebugger.gThreadClient.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
gWindow.close();
|
||||
deferred.resolve();
|
||||
finish();
|
||||
});
|
||||
|
||||
gDebuggee.runDebuggerStatement();
|
||||
});
|
||||
});
|
||||
|
||||
let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
|
||||
if (focusManager.activeWindow != gWindow) {
|
||||
gWindow.addEventListener("activate", function onActivate(aEvent) {
|
||||
if (aEvent.target != gWindow) {
|
||||
return;
|
||||
}
|
||||
gWindow.removeEventListener("activate", onActivate, true);
|
||||
isActive.resolve();
|
||||
}, true);
|
||||
} else {
|
||||
isActive.resolve();
|
||||
}
|
||||
|
||||
let contentLocation = gWindow.content.location.href;
|
||||
if (contentLocation != TAB_URL) {
|
||||
gWindow.document.addEventListener("load", function onLoad(aEvent) {
|
||||
if (aEvent.target.documentURI != TAB_URL) {
|
||||
return;
|
||||
}
|
||||
gWindow.document.removeEventListener("load", onLoad, true);
|
||||
isLoaded.resolve();
|
||||
}, true);
|
||||
} else {
|
||||
isLoaded.resolve();
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gWindow = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
|
@ -416,18 +416,18 @@ function backspaceText(aElement, aTimes) {
|
|||
}
|
||||
}
|
||||
|
||||
function getTab(aTarget) {
|
||||
function getTab(aTarget, aWindow) {
|
||||
if (aTarget instanceof XULElement) {
|
||||
return promise.resolve(aTarget);
|
||||
} else {
|
||||
return addTab(aTarget);
|
||||
return addTab(aTarget, aWindow);
|
||||
}
|
||||
}
|
||||
|
||||
function initDebugger(aTarget, aWindow) {
|
||||
info("Initializing a debugger panel.");
|
||||
|
||||
return getTab(aTarget).then(aTab => {
|
||||
return getTab(aTarget, aWindow).then(aTab => {
|
||||
info("Debugee tab added successfully: " + aTarget);
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
@ -445,7 +445,7 @@ function initDebugger(aTarget, aWindow) {
|
|||
info("Debugger client resumed successfully.");
|
||||
|
||||
prepareDebugger(debuggerPanel);
|
||||
deferred.resolve([aTab, debuggee, debuggerPanel]);
|
||||
deferred.resolve([aTab, debuggee, debuggerPanel, aWindow]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -180,12 +180,6 @@ function ResponsiveUI(aWindow, aTab)
|
|||
this.buildUI();
|
||||
this.checkMenus();
|
||||
|
||||
this.docShell = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
|
||||
this.docShell.deviceSizeIsPageSize = true;
|
||||
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
|
||||
this.rotate();
|
||||
|
@ -258,8 +252,6 @@ ResponsiveUI.prototype = {
|
|||
this.browser.removeEventListener("load", this.bound_onPageLoad, true);
|
||||
this.browser.removeEventListener("unload", this.bound_onPageUnload, true);
|
||||
|
||||
this.docShell.deviceSizeIsPageSize = false;
|
||||
|
||||
if (this._floatingScrollbars)
|
||||
switchToNativeScrollbars(this.tab);
|
||||
|
||||
|
@ -296,7 +288,6 @@ ResponsiveUI.prototype = {
|
|||
this.container.removeAttribute("responsivemode");
|
||||
this.stack.removeAttribute("responsivemode");
|
||||
|
||||
delete this.docShell;
|
||||
delete this.tab.__responsiveUI;
|
||||
if (this.touchEventHandler)
|
||||
this.touchEventHandler.stop();
|
||||
|
|
|
@ -9,7 +9,6 @@ MOCHITEST_BROWSER_FILES := \
|
|||
browser_responsive_cmd.js \
|
||||
browser_responsivecomputedview.js \
|
||||
browser_responsiveui_touch.js \
|
||||
browser_responsive_devicewidth.js \
|
||||
touch.html \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let instance;
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,mop";
|
||||
|
||||
function startTest() {
|
||||
mgr.once("on", function() {executeSoon(onUIOpen)});
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
let mql = content.matchMedia("(max-device-width:100px)")
|
||||
|
||||
ok(!mql.matches, "media query doesn't match.");
|
||||
|
||||
mql.addListener(onMediaChange);
|
||||
instance.setSize(90, 500);
|
||||
}
|
||||
|
||||
function onMediaChange(mql) {
|
||||
mql.removeListener(onMediaChange);
|
||||
ok(mql.matches, "media query matches.");
|
||||
ok(window.screen.width != content.screen.width, "screen.width is not the size of the screen.");
|
||||
is(content.screen.width, 90, "screen.width is the width of the page.");
|
||||
is(content.screen.height, 500, "screen.height is the height of the page.");
|
||||
|
||||
|
||||
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
|
||||
mql.addListener(onMediaChange2);
|
||||
docShell.deviceSizeIsPageSize = false;
|
||||
}
|
||||
|
||||
function onMediaChange2(mql) {
|
||||
mql.removeListener(onMediaChange);
|
||||
ok(!mql.matches, "media query has been re-evaluated.");
|
||||
ok(window.screen.width == content.screen.width, "screen.width is not the size of the screen.");
|
||||
instance.stack.removeAttribute("notransition");
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -668,16 +668,13 @@ PropertyView.prototype = {
|
|||
|
||||
/**
|
||||
* Returns the className that should be assigned to the propertyView.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
get propertyHeaderClassName()
|
||||
{
|
||||
if (this.visible) {
|
||||
this.tree._darkStripe = !this.tree._darkStripe;
|
||||
let darkValue = this.tree._darkStripe ?
|
||||
"property-view theme-bg-darker" : "property-view";
|
||||
return darkValue;
|
||||
let isDark = this.tree._darkStripe = !this.tree._darkStripe;
|
||||
return isDark ? "property-view theme-bg-darker" : "property-view";
|
||||
}
|
||||
return "property-view-hidden";
|
||||
},
|
||||
|
@ -690,49 +687,66 @@ PropertyView.prototype = {
|
|||
get propertyContentClassName()
|
||||
{
|
||||
if (this.visible) {
|
||||
let darkValue = this.tree._darkStripe ?
|
||||
"property-content theme-bg-darker" : "property-content";
|
||||
return darkValue;
|
||||
let isDark = this.tree._darkStripe;
|
||||
return isDark ? "property-content theme-bg-darker" : "property-content";
|
||||
}
|
||||
return "property-content-hidden";
|
||||
},
|
||||
|
||||
/**
|
||||
* Build the markup for on computed style
|
||||
* @return Element
|
||||
*/
|
||||
buildMain: function PropertyView_buildMain()
|
||||
{
|
||||
let doc = this.tree.styleDocument;
|
||||
let onToggle = this.onStyleToggle.bind(this);
|
||||
|
||||
// Build the container element
|
||||
this.element = doc.createElementNS(HTML_NS, "div");
|
||||
this.element.setAttribute("class", this.propertyHeaderClassName);
|
||||
|
||||
this.matchedExpander = doc.createElementNS(HTML_NS, "div");
|
||||
this.matchedExpander.className = "expander theme-twisty";
|
||||
this.matchedExpander.setAttribute("tabindex", "0");
|
||||
this.matchedExpander.addEventListener("click",
|
||||
this.matchedExpanderClick.bind(this), false);
|
||||
this.matchedExpander.addEventListener("keydown", function(aEvent) {
|
||||
// Make it keyboard navigable
|
||||
this.element.setAttribute("tabindex", "0");
|
||||
this.element.addEventListener("keydown", function(aEvent) {
|
||||
let keyEvent = Ci.nsIDOMKeyEvent;
|
||||
if (aEvent.keyCode == keyEvent.DOM_VK_F1) {
|
||||
this.mdnLinkClick();
|
||||
}
|
||||
if (aEvent.keyCode == keyEvent.DOM_VK_RETURN ||
|
||||
aEvent.keyCode == keyEvent.DOM_VK_SPACE) {
|
||||
this.matchedExpanderClick(aEvent);
|
||||
onToggle(aEvent);
|
||||
}
|
||||
}.bind(this), false);
|
||||
|
||||
// Build the twisty expand/collapse
|
||||
this.matchedExpander = doc.createElementNS(HTML_NS, "div");
|
||||
this.matchedExpander.className = "expander theme-twisty";
|
||||
this.matchedExpander.addEventListener("click", onToggle, false);
|
||||
this.element.appendChild(this.matchedExpander);
|
||||
|
||||
// Build the style name element
|
||||
this.nameNode = doc.createElementNS(HTML_NS, "div");
|
||||
this.element.appendChild(this.nameNode);
|
||||
this.nameNode.setAttribute("class", "property-name theme-fg-color5");
|
||||
// Reset its tabindex attribute otherwise, if an ellipsis is applied
|
||||
// it will be reachable via TABing
|
||||
this.nameNode.setAttribute("tabindex", "");
|
||||
this.nameNode.textContent = this.nameNode.title = this.name;
|
||||
this.nameNode.addEventListener("click", function(aEvent) {
|
||||
this.matchedExpander.focus();
|
||||
}.bind(this), false);
|
||||
// Make it hand over the focus to the container
|
||||
this.nameNode.addEventListener("click", () => this.element.focus(), false);
|
||||
this.element.appendChild(this.nameNode);
|
||||
|
||||
// Build the style value element
|
||||
this.valueNode = doc.createElementNS(HTML_NS, "div");
|
||||
this.element.appendChild(this.valueNode);
|
||||
this.valueNode.setAttribute("class", "property-value theme-fg-color1");
|
||||
// Reset its tabindex attribute otherwise, if an ellipsis is applied
|
||||
// it will be reachable via TABing
|
||||
this.valueNode.setAttribute("tabindex", "");
|
||||
this.valueNode.setAttribute("dir", "ltr");
|
||||
this.valueNode.textContent = this.valueNode.title = this.value;
|
||||
// Make it hand over the focus to the container
|
||||
this.valueNode.addEventListener("click", () => this.element.focus(), false);
|
||||
this.element.appendChild(this.valueNode);
|
||||
|
||||
return this.element;
|
||||
},
|
||||
|
@ -836,7 +850,7 @@ PropertyView.prototype = {
|
|||
* @param {Event} aEvent Used to determine the class name of the targets click
|
||||
* event.
|
||||
*/
|
||||
matchedExpanderClick: function PropertyView_matchedExpanderClick(aEvent)
|
||||
onStyleToggle: function PropertyView_onStyleToggle(aEvent)
|
||||
{
|
||||
this.matchedExpanded = !this.matchedExpanded;
|
||||
this.refreshMatchedSelectors();
|
||||
|
|
|
@ -36,6 +36,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_bug894376_css_value_completion_existing_property_value_pair.js \
|
||||
browser_ruleview_bug_902966_revert_value_on_ESC.js \
|
||||
browser_ruleview_pseudoelement.js \
|
||||
browser_computedview_bug835808_keyboard_nav.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the style inspector works properly
|
||||
|
||||
let doc, computedView, inspector;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,computed view context menu test";
|
||||
}
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||
'span { font-variant: small-caps; color: #000000; } ' +
|
||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
||||
'<h1>Some header text</h1>\n' +
|
||||
'<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
|
||||
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
|
||||
'solely to provide some things to <span style="color: yellow">' +
|
||||
'highlight</span> and <span style="font-weight: bold">count</span> ' +
|
||||
'style list-items in the box at right. If you are reading this, ' +
|
||||
'you should go do something else instead. Maybe read a book. Or better ' +
|
||||
'yet, write some test-cases for another bit of code. ' +
|
||||
'<span style="font-style: italic">some text</span></p>\n' +
|
||||
'<p id="closing">more text</p>\n' +
|
||||
'<p>even more text</p>' +
|
||||
'</div>';
|
||||
doc.title = "Computed view keyboard navigation test";
|
||||
|
||||
openComputedView(startTests);
|
||||
}
|
||||
|
||||
function startTests(aInspector, aComputedView)
|
||||
{
|
||||
computedView = aComputedView;
|
||||
inspector = aInspector;
|
||||
testTabThrougStyles();
|
||||
}
|
||||
|
||||
function endTests()
|
||||
{
|
||||
computedView = inspector = doc = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function testTabThrougStyles()
|
||||
{
|
||||
let span = doc.querySelector("span");
|
||||
|
||||
inspector.once("computed-view-refreshed", () => {
|
||||
// Selecting the first computed style in the list
|
||||
let firstStyle = computedView.styleDocument.querySelector(".property-view");
|
||||
ok(firstStyle, "First computed style found in panel");
|
||||
firstStyle.focus();
|
||||
|
||||
// Tab to select the 2nd style, press return
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
inspector.once("computed-view-property-expanded", () => {
|
||||
// Verify the 2nd style has been expanded
|
||||
let secondStyleSelectors = computedView.styleDocument.querySelectorAll(
|
||||
".property-content .matchedselectors")[1];
|
||||
ok(secondStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
||||
|
||||
// Tab back up and test the same thing, with space
|
||||
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
|
||||
EventUtils.synthesizeKey("VK_SPACE", {});
|
||||
inspector.once("computed-view-property-expanded", () => {
|
||||
// Verify the 1st style has been expanded too
|
||||
let firstStyleSelectors = computedView.styleDocument.querySelectorAll(
|
||||
".property-content .matchedselectors")[0];
|
||||
ok(firstStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
||||
|
||||
endTests();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
inspector.selection.setNode(span);
|
||||
}
|
|
@ -45,6 +45,7 @@ body {
|
|||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
|
@ -58,6 +59,7 @@ body {
|
|||
background-size: 5px 8px;
|
||||
background-position: 2px center;
|
||||
padding-left: 10px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.other-property-value {
|
||||
|
|
|
@ -63,6 +63,7 @@ body {
|
|||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
|
@ -76,6 +77,7 @@ body {
|
|||
background-size: 5px 8px;
|
||||
background-position: 2px center;
|
||||
padding-left: 10px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.other-property-value {
|
||||
|
|
|
@ -63,6 +63,7 @@ body {
|
|||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
|
@ -76,6 +77,7 @@ body {
|
|||
background-size: 5px 8px;
|
||||
background-position: 2px center;
|
||||
padding-left: 10px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.other-property-value {
|
||||
|
|
|
@ -750,7 +750,6 @@ nsDocShell::nsDocShell():
|
|||
mIsAppTab(false),
|
||||
mUseGlobalHistory(false),
|
||||
mInPrivateBrowsing(false),
|
||||
mDeviceSizeIsPageSize(false),
|
||||
mFiredUnloadEvent(false),
|
||||
mEODForCurrentDocument(false),
|
||||
mURIResultedInDocument(false),
|
||||
|
@ -3933,27 +3932,6 @@ nsDocShell::GetCurrentSHEntry(nsISHEntry** aEntry, bool* aOSHE)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetDeviceSizeIsPageSize(bool aValue)
|
||||
{
|
||||
if (mDeviceSizeIsPageSize != aValue) {
|
||||
mDeviceSizeIsPageSize = aValue;
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
GetPresContext(getter_AddRefs(presContext));
|
||||
if (presContext) {
|
||||
presContext->MediaFeatureValuesChanged(presContext->eAlwaysRebuildStyle);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetDeviceSizeIsPageSize(bool* aValue)
|
||||
{
|
||||
*aValue = mDeviceSizeIsPageSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::ClearFrameHistory(nsISHEntry* aEntry)
|
||||
{
|
||||
|
|
|
@ -809,7 +809,6 @@ protected:
|
|||
bool mIsAppTab;
|
||||
bool mUseGlobalHistory;
|
||||
bool mInPrivateBrowsing;
|
||||
bool mDeviceSizeIsPageSize;
|
||||
|
||||
// This boolean is set to true right before we fire pagehide and generally
|
||||
// unset when we embed a new content viewer. While it's true no navigation
|
||||
|
|
|
@ -916,12 +916,4 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*/
|
||||
boolean isCommandEnabled(in string command);
|
||||
void doCommand(in string command);
|
||||
|
||||
/**
|
||||
* If deviceSizeIsPageSize is set to true, device-width/height media queries
|
||||
* will be calculated from the page size, not the device size.
|
||||
*
|
||||
* Used by the Responsive Design View.
|
||||
*/
|
||||
[infallible] attribute boolean deviceSizeIsPageSize;
|
||||
};
|
||||
|
|
|
@ -1508,6 +1508,23 @@ nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aSc
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::ScrollToCSSPixelsApproximate(float aX, float aY, bool* aRetVal)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(window);
|
||||
|
||||
nsIScrollableFrame* sf = static_cast<nsGlobalWindow*>(window.get())->GetScrollFrame();
|
||||
if (sf) {
|
||||
sf->ScrollToCSSPixelsApproximate(CSSPoint(aX, aY));
|
||||
}
|
||||
if (aRetVal) {
|
||||
*aRetVal = (sf != nullptr);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
|
||||
int32_t* aHeight)
|
||||
|
|
|
@ -385,19 +385,6 @@ nsScreen::SlowMozUnlockOrientation()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreen::IsDeviceSizePageSize()
|
||||
{
|
||||
nsPIDOMWindow* owner = GetOwner();
|
||||
if (owner) {
|
||||
nsIDocShell* docShell = owner->GetDocShell();
|
||||
if (docShell) {
|
||||
return docShell->GetDeviceSizeIsPageSize();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
JSObject*
|
||||
nsScreen::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||
|
|
|
@ -51,15 +51,6 @@ public:
|
|||
int32_t GetWidth(ErrorResult& aRv)
|
||||
{
|
||||
nsRect rect;
|
||||
if (IsDeviceSizePageSize()) {
|
||||
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
|
||||
if (owner) {
|
||||
int32_t innerWidth = 0;
|
||||
aRv = owner->GetInnerWidth(&innerWidth);
|
||||
return innerWidth;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = GetRect(rect);
|
||||
return rect.width;
|
||||
}
|
||||
|
@ -67,15 +58,6 @@ public:
|
|||
int32_t GetHeight(ErrorResult& aRv)
|
||||
{
|
||||
nsRect rect;
|
||||
if (IsDeviceSizePageSize()) {
|
||||
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
|
||||
if (owner) {
|
||||
int32_t innerHeight = 0;
|
||||
aRv = owner->GetInnerHeight(&innerHeight);
|
||||
return innerHeight;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = GetRect(rect);
|
||||
return rect.height;
|
||||
}
|
||||
|
@ -155,8 +137,6 @@ private:
|
|||
|
||||
LockPermission GetLockOrientationPermission() const;
|
||||
|
||||
bool IsDeviceSizePageSize();
|
||||
|
||||
nsRefPtr<FullScreenEventListener> mEventListener;
|
||||
};
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ interface nsIDOMEventTarget;
|
|||
interface nsIRunnable;
|
||||
interface nsICompositionStringSynthesizer;
|
||||
|
||||
[scriptable, uuid(dd45c6ae-9d80-46ef-86d7-f2795a48a77b)]
|
||||
[scriptable, uuid(a1383ae5-e828-4c9a-929d-5293e61beb64)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -652,6 +652,13 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
*/
|
||||
void getScrollXY(in boolean aFlushLayout, out long aScrollX, out long aScrollY);
|
||||
|
||||
/**
|
||||
* Sets the scroll position of the root scroll frame of the window.
|
||||
* Returns true on success, false on error (if the window didn't have a root
|
||||
* scroll frame).
|
||||
*/
|
||||
boolean scrollToCSSPixelsApproximate(in float aX, in float aY);
|
||||
|
||||
/**
|
||||
* Returns the scrollbar width of the window's scroll frame.
|
||||
*
|
||||
|
|
|
@ -1930,13 +1930,11 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
|||
// If the blob represents a remote blob for this ContentParent then we can
|
||||
// simply pass its actor back here.
|
||||
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob)) {
|
||||
BlobParent* actor =
|
||||
static_cast<BlobParent*>(
|
||||
static_cast<PBlobParent*>(remoteBlob->GetPBlob()));
|
||||
MOZ_ASSERT(actor);
|
||||
|
||||
if (static_cast<ContentParent*>(actor->Manager()) == this) {
|
||||
return actor;
|
||||
if (BlobParent* actor = static_cast<BlobParent*>(
|
||||
static_cast<PBlobParent*>(remoteBlob->GetPBlob()))) {
|
||||
if (static_cast<ContentParent*>(actor->Manager()) == this) {
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
#include "xpcpublic.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "JavaScriptChild.h"
|
||||
#include "APZCCallbackHelper.h"
|
||||
|
||||
#define BROWSER_ELEMENT_CHILD_SCRIPT \
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
|
||||
|
@ -302,29 +303,6 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t
|
|||
{
|
||||
}
|
||||
|
||||
// Get the DOMWindowUtils for the window corresponding to the given document.
|
||||
static already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils(nsIDocument* doc)
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils;
|
||||
nsCOMPtr<nsIDOMWindow> window = doc->GetDefaultView();
|
||||
if (window) {
|
||||
utils = do_GetInterface(window);
|
||||
}
|
||||
return utils.forget();
|
||||
}
|
||||
|
||||
// Get the DOMWindowUtils for the window corresponding to the givent content
|
||||
// element. This might be an iframe inside the tab, for instance.
|
||||
static already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils(nsIContent* content)
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils;
|
||||
nsIDocument* doc = content->GetCurrentDoc();
|
||||
if (doc) {
|
||||
utils = GetDOMWindowUtils(doc);
|
||||
}
|
||||
return utils.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
|
@ -348,7 +326,7 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent)
|
|||
else
|
||||
content = do_QueryInterface(target);
|
||||
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils = ::GetDOMWindowUtils(content);
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils = APZCCallbackHelper::GetDOMWindowUtils(content);
|
||||
utils->GetPresShellId(&presShellId);
|
||||
|
||||
if (!nsLayoutUtils::FindIDFor(content, &viewId))
|
||||
|
@ -1542,12 +1520,8 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
|
|||
MOZ_ASSERT(aFrameMetrics.mScrollId != FrameMetrics::NULL_SCROLL_ID);
|
||||
|
||||
if (aFrameMetrics.mScrollId == FrameMetrics::ROOT_SCROLL_ID) {
|
||||
uint32_t presShellId;
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
|
||||
nsresult rv = utils->GetPresShellId(&presShellId);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && aFrameMetrics.mPresShellId == presShellId) {
|
||||
if (APZCCallbackHelper::HasValidPresShellId(utils, aFrameMetrics)) {
|
||||
return ProcessUpdateFrame(aFrameMetrics);
|
||||
}
|
||||
} else {
|
||||
|
@ -1556,7 +1530,8 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
|
|||
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(
|
||||
aFrameMetrics.mScrollId);
|
||||
if (content) {
|
||||
return ProcessUpdateSubframe(content, aFrameMetrics);
|
||||
APZCCallbackHelper::UpdateSubFrame(content, aFrameMetrics);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1610,38 +1585,8 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
|||
DispatchMessageManagerMessage(NS_LITERAL_STRING("Viewport:Change"), data);
|
||||
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
|
||||
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mWebNav);
|
||||
|
||||
// set the scroll port size, which determines the scroll range
|
||||
utils->SetScrollPositionClampingScrollPortSize(
|
||||
cssCompositedRect.width, cssCompositedRect.height);
|
||||
|
||||
// scroll the window to the desired spot
|
||||
nsIScrollableFrame* sf = static_cast<nsGlobalWindow*>(window.get())->GetScrollFrame();
|
||||
if (sf) {
|
||||
sf->ScrollToCSSPixelsApproximate(aFrameMetrics.mScrollOffset);
|
||||
}
|
||||
|
||||
// set the resolution
|
||||
ParentLayerToLayerScale resolution = aFrameMetrics.mZoom
|
||||
/ aFrameMetrics.mDevPixelsPerCSSPixel
|
||||
/ aFrameMetrics.GetParentResolution()
|
||||
* ScreenToLayerScale(1);
|
||||
utils->SetResolution(resolution.scale, resolution.scale);
|
||||
|
||||
// and set the display port
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mWebNav->GetDocument(getter_AddRefs(domDoc));
|
||||
if (domDoc) {
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
domDoc->GetDocumentElement(getter_AddRefs(element));
|
||||
if (element) {
|
||||
utils->SetDisplayPortForElement(
|
||||
aFrameMetrics.mDisplayPort.x, aFrameMetrics.mDisplayPort.y,
|
||||
aFrameMetrics.mDisplayPort.width, aFrameMetrics.mDisplayPort.height,
|
||||
element);
|
||||
}
|
||||
}
|
||||
APZCCallbackHelper::UpdateRootFrame(utils, aFrameMetrics);
|
||||
|
||||
mLastMetrics = aFrameMetrics;
|
||||
|
||||
|
@ -1656,29 +1601,6 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::ProcessUpdateSubframe(nsIContent* aContent,
|
||||
const FrameMetrics& aMetrics)
|
||||
{
|
||||
// scroll the frame to the desired spot
|
||||
nsIScrollableFrame* scrollFrame = nsLayoutUtils::FindScrollableFrameFor(aMetrics.mScrollId);
|
||||
if (scrollFrame) {
|
||||
scrollFrame->ScrollToCSSPixelsApproximate(aMetrics.mScrollOffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(::GetDOMWindowUtils(aContent));
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
|
||||
if (utils && element) {
|
||||
// and set the display port
|
||||
utils->SetDisplayPortForElement(
|
||||
aMetrics.mDisplayPort.x, aMetrics.mDisplayPort.y,
|
||||
aMetrics.mDisplayPort.width, aMetrics.mDisplayPort.height,
|
||||
element);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvHandleDoubleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
|
|
|
@ -415,7 +415,6 @@ private:
|
|||
void DestroyWindow();
|
||||
void SetProcessNameToAppName();
|
||||
bool ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||
bool ProcessUpdateSubframe(nsIContent* aContent, const FrameMetrics& aMetrics);
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow();
|
||||
|
|
|
@ -27,7 +27,7 @@ interface nsISocketTransport;
|
|||
// Once bug 723206 will be fixed, this method could be replaced by
|
||||
// arguments when instantiating a TCPSocket object. For example it will
|
||||
// be possible to do (similarly to the WebSocket API):
|
||||
// var s = new MozTCPSocket(host, port);
|
||||
// var s = new MozTCPSocket(host, port);
|
||||
|
||||
// Bug 797561 - Expose a server tcp socket API to web applications
|
||||
|
||||
|
@ -215,7 +215,7 @@ interface nsIDOMTCPSocket : nsISupports
|
|||
* Needed to account for multiple possible types that can be provided to
|
||||
* the socket callbacks as arguments.
|
||||
*/
|
||||
[scriptable, uuid(0baa1be1-6a88-4f85-a6c8-29e95f35c122)]
|
||||
[scriptable, uuid(234c664c-3d6c-4859-b45c-4e9a98cb5bdc)]
|
||||
interface nsITCPSocketInternal : nsISupports {
|
||||
// Trigger the callback for |type| and provide a DOMError() object with the given data
|
||||
void callListenerError(in DOMString type, in DOMString name);
|
||||
|
@ -245,17 +245,20 @@ interface nsITCPSocketInternal : nsISupports {
|
|||
|
||||
// Create a DOM socket on the child side
|
||||
// This is called when the socket is accepted on the parent side.
|
||||
//
|
||||
//
|
||||
// @param socketChild
|
||||
// The socket child object for the IPC implementation.
|
||||
// @param binaryType
|
||||
// "arraybuffer" to use ArrayBuffer instances
|
||||
// "arraybuffer" to use ArrayBuffer instances
|
||||
// in the ondata callback and as the argument to send.
|
||||
// @param window
|
||||
// An object to create ArrayBuffer for this window. See Bug 831107.
|
||||
nsIDOMTCPSocket createAcceptedChild(in nsITCPSocketChild socketChild,
|
||||
in DOMString binaryType,
|
||||
in DOMString binaryType,
|
||||
in nsIDOMWindow window);
|
||||
|
||||
// Set App ID.
|
||||
void setAppId(in unsigned long appId);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,12 +38,13 @@ interface nsITCPSocketParent : nsISupports
|
|||
|
||||
// Intermediate class to handle sending multiple possible data types
|
||||
// and kicking off the chrome process socket object's connection.
|
||||
[scriptable, uuid(38bec1ed-b863-40dd-ba69-7bd92e568ee3)]
|
||||
[scriptable, uuid(be67b1b8-03b0-4171-a791-d004458021b6)]
|
||||
interface nsITCPSocketIntermediary : nsISupports {
|
||||
// Open the connection to the server with the given parameters
|
||||
nsIDOMTCPSocket open(in nsITCPSocketParent parent,
|
||||
in DOMString host, in unsigned short port,
|
||||
in boolean useSSL, in DOMString binaryType);
|
||||
in boolean useSSL, in DOMString binaryType,
|
||||
in unsigned long appId);
|
||||
|
||||
// Listen on a port
|
||||
nsIDOMTCPServerSocket listen(in nsITCPServerSocketParent parent,
|
||||
|
|
|
@ -22,6 +22,7 @@ const TOPIC_INTERFACE_REGISTERED = "network-interface-registered";
|
|||
const TOPIC_INTERFACE_UNREGISTERED = "network-interface-unregistered";
|
||||
const NET_TYPE_WIFI = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
|
||||
const NET_TYPE_MOBILE = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE;
|
||||
const NET_TYPE_UNKNOWN = Ci.nsINetworkInterface.NETWORK_TYPE_UNKNOWN;
|
||||
|
||||
// The maximum traffic amount can be saved in the |cachedAppStats|.
|
||||
const MAX_CACHED_TRAFFIC = 500 * 1000 * 1000; // 500 MB
|
||||
|
@ -424,8 +425,8 @@ this.NetworkStatsService = {
|
|||
aTimeStamp + " " + aRxBytes + " " + aTxBytes);
|
||||
}
|
||||
|
||||
// |aAppId| can not be 0 or null in this case.
|
||||
if (!aAppId) {
|
||||
// Check if |aAppId| and |aConnectionType| are valid.
|
||||
if (!aAppId || aConnectionType == NET_TYPE_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ const kCLOSED = 'closed';
|
|||
const kRESUME_ERROR = 'Calling resume() on a connection that was not suspended.';
|
||||
|
||||
const BUFFER_SIZE = 65536;
|
||||
const NETWORK_STATS_THRESHOLD = 65536;
|
||||
|
||||
// XXX we have no TCPError implementation right now because it's really hard to
|
||||
// do on b2g18. On mozilla-central we want a proper TCPError that ideally
|
||||
|
@ -161,6 +162,14 @@ TCPSocket.prototype = {
|
|||
_waitingForStartTLS: false,
|
||||
_pendingDataAfterStartTLS: [],
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Network statistics (Gonk-specific feature)
|
||||
_txBytes: 0,
|
||||
_rxBytes: 0,
|
||||
_appId: Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
_connectionType: Ci.nsINetworkInterface.NETWORK_TYPE_UNKNOWN,
|
||||
#endif
|
||||
|
||||
// Public accessors.
|
||||
get readyState() {
|
||||
return this._readyState;
|
||||
|
@ -315,6 +324,38 @@ TCPSocket.prototype = {
|
|||
BUFFER_SIZE, /* close source*/ false, /* close sink */ false);
|
||||
},
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Helper method for collecting network statistics.
|
||||
// Note this method is Gonk-specific.
|
||||
_saveNetworkStats: function ts_saveNetworkStats(enforce) {
|
||||
if (this._txBytes <= 0 && this._rxBytes <= 0) {
|
||||
// There is no traffic at all. No need to save statistics.
|
||||
return;
|
||||
}
|
||||
|
||||
// If "enforce" is false, the traffic amount is saved to NetworkStatsServiceProxy
|
||||
// only when the total amount exceeds the predefined threshold value.
|
||||
// The purpose is to avoid too much overhead for collecting statistics.
|
||||
let totalBytes = this._txBytes + this._rxBytes;
|
||||
if (!enforce && totalBytes < NETWORK_STATS_THRESHOLD) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nssProxy = Cc["@mozilla.org/networkstatsServiceProxy;1"]
|
||||
.getService(Ci.nsINetworkStatsServiceProxy);
|
||||
if (!nssProxy) {
|
||||
LOG("Error: Ci.nsINetworkStatsServiceProxy service is not available.");
|
||||
return;
|
||||
}
|
||||
nssProxy.saveAppStats(this._appId, this._connectionType, Date.now(),
|
||||
this._rxBytes, this._txBytes);
|
||||
|
||||
// Reset the counters once the statistics is saved to NetworkStatsServiceProxy.
|
||||
this._txBytes = this._rxBytes = 0;
|
||||
},
|
||||
// End of helper method for network statistics.
|
||||
#endif
|
||||
|
||||
callListener: function ts_callListener(type, data) {
|
||||
if (!this["on" + type])
|
||||
return;
|
||||
|
@ -371,6 +412,14 @@ TCPSocket.prototype = {
|
|||
return that;
|
||||
},
|
||||
|
||||
setAppId: function ts_setAppId(appId) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
this._appId = appId;
|
||||
#else
|
||||
// Do nothing because _appId only exists on Gonk-specific platform.
|
||||
#endif
|
||||
},
|
||||
|
||||
/* end nsITCPSocketInternal methods */
|
||||
|
||||
initWindowless: function ts_initWindowless() {
|
||||
|
@ -479,6 +528,17 @@ TCPSocket.prototype = {
|
|||
let transport = that._transport = this._createTransport(host, port, that._ssl);
|
||||
transport.setEventSink(that, Services.tm.currentThread);
|
||||
that._initStream(that._binaryType);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Set _connectionType, which is only required for network statistics.
|
||||
// Note that nsINetworkManager, as well as nsINetworkStatsServiceProxy, is
|
||||
// Gonk-specific.
|
||||
let networkManager = Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager);
|
||||
if (networkManager && networkManager.active) {
|
||||
that._connectionType = networkManager.active.type;
|
||||
}
|
||||
#endif
|
||||
|
||||
return that;
|
||||
},
|
||||
|
||||
|
@ -589,6 +649,13 @@ TCPSocket.prototype = {
|
|||
}
|
||||
|
||||
this._ensureCopying();
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Collect transmitted amount for network statistics.
|
||||
this._txBytes += length;
|
||||
this._saveNetworkStats(false);
|
||||
#endif
|
||||
|
||||
return bufferNotFull;
|
||||
},
|
||||
|
||||
|
@ -621,6 +688,12 @@ TCPSocket.prototype = {
|
|||
},
|
||||
|
||||
_maybeReportErrorAndCloseIfOpen: function(status) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Save network statistics once the connection is closed.
|
||||
// For now this function is Gonk-specific.
|
||||
this._saveNetworkStats(true);
|
||||
#endif
|
||||
|
||||
// If we're closed, we've already reported the error or just don't need to
|
||||
// report the error.
|
||||
if (this._readyState === kCLOSED)
|
||||
|
@ -813,6 +886,12 @@ TCPSocket.prototype = {
|
|||
} else {
|
||||
this.callListener("data", this._inputStreamScriptable.read(count));
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Collect received amount for network statistics.
|
||||
this._rxBytes += count;
|
||||
this._saveNetworkStats(false);
|
||||
#endif
|
||||
},
|
||||
|
||||
classID: Components.ID("{cda91b22-6472-11e1-aa11-834fec09cd0a}"),
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "mozilla/AppProcessChecker.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
#include "mozilla/net/PNeckoParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
|
@ -91,6 +93,15 @@ TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bo
|
|||
return true;
|
||||
}
|
||||
|
||||
// Obtain App ID
|
||||
uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
const PContentParent *content = Manager()->Manager();
|
||||
const InfallibleTArray<PBrowserParent*>& browsers = content->ManagedPBrowserParent();
|
||||
if (browsers.Length() > 0) {
|
||||
TabParent *tab = static_cast<TabParent*>(browsers[0]);
|
||||
appId = tab->OwnAppId();
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -98,7 +109,8 @@ TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bo
|
|||
return true;
|
||||
}
|
||||
|
||||
rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, getter_AddRefs(mSocket));
|
||||
rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, appId,
|
||||
getter_AddRefs(mSocket));
|
||||
if (NS_FAILED(rv) || !mSocket) {
|
||||
FireInteralError(this, __LINE__);
|
||||
return true;
|
||||
|
|
|
@ -30,12 +30,17 @@ TCPSocketParentIntermediary.prototype = {
|
|||
);
|
||||
},
|
||||
|
||||
open: function(aParentSide, aHost, aPort, aUseSSL, aBinaryType) {
|
||||
open: function(aParentSide, aHost, aPort, aUseSSL, aBinaryType, aAppId) {
|
||||
let baseSocket = Cc["@mozilla.org/tcp-socket;1"].createInstance(Ci.nsIDOMTCPSocket);
|
||||
let socket = baseSocket.open(aHost, aPort, {useSecureTransport: aUseSSL, binaryType: aBinaryType});
|
||||
if (!socket)
|
||||
return null;
|
||||
|
||||
let socketInternal = socket.QueryInterface(Ci.nsITCPSocketInternal);
|
||||
if (socketInternal) {
|
||||
socketInternal.setAppId(aAppId);
|
||||
}
|
||||
|
||||
// Handlers are set to the JS-implemented socket object on the parent side.
|
||||
this._setCallbacks(aParentSide, socket);
|
||||
return socket;
|
||||
|
|
|
@ -32,11 +32,14 @@ if CONFIG['MOZ_B2G_RIL']:
|
|||
|
||||
EXTRA_COMPONENTS += [
|
||||
'TCPServerSocket.js',
|
||||
'TCPSocket.js',
|
||||
'TCPSocket.manifest',
|
||||
'TCPSocketParentIntermediary.js',
|
||||
]
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'TCPSocket.js',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G_RIL']:
|
||||
EXTRA_COMPONENTS += [
|
||||
'NetworkStatsManager.js',
|
||||
|
|
|
@ -226,6 +226,49 @@ tasks.push(function testEnableData() {
|
|||
setSetting(DATA_KEY, true);
|
||||
});
|
||||
|
||||
tasks.push(function testUnregisterDataWhileDataEnabled() {
|
||||
log("Set data registration unregistered while data enabled.");
|
||||
|
||||
// When data registration is unregistered, all data calls
|
||||
// will be automatically deactivated.
|
||||
sendCmdToEmulator("gsm data unregistered", function() {
|
||||
connection.addEventListener("datachange", function ondatachange() {
|
||||
log("mobileConnection.data.state is now '"
|
||||
+ connection.data.state + "'.");
|
||||
if (connection.data.state == "notSearching") {
|
||||
connection.removeEventListener("datachange", ondatachange);
|
||||
log("mobileConnection.data.connected is now '"
|
||||
+ connection.data.connected + "'.");
|
||||
is(connection.data.connected, false, "data.connected");
|
||||
tasks.next();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
tasks.push(function testRegisterDataWhileDataEnabled() {
|
||||
log("Set data registration home while data enabled.");
|
||||
|
||||
// When data registration is registered, data call will be
|
||||
// (re)activated by gecko if ril.data.enabled is set to true.
|
||||
sendCmdToEmulator("gsm data home", function() {
|
||||
connection.addEventListener("datachange", function ondatachange() {
|
||||
connection.removeEventListener("datachange", ondatachange);
|
||||
log("mobileConnection.data.state is now '"
|
||||
+ connection.data.state + "'.");
|
||||
is(connection.data.state, "registered", "data.state");
|
||||
|
||||
connection.addEventListener("datachange", function ondatachange() {
|
||||
connection.removeEventListener("datachange", ondatachange);
|
||||
log("mobileConnection.data.connected is now '"
|
||||
+ connection.data.connected + "'.");
|
||||
is(connection.data.connected, true, "data.connected");
|
||||
tasks.next();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
tasks.push(function testDisableDataRoamingWhileRoaming() {
|
||||
log("Disable data roaming while roaming.");
|
||||
|
||||
|
|
|
@ -233,6 +233,7 @@ NetworkManager.prototype = {
|
|||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE ||
|
||||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
|
||||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) {
|
||||
this.removeHostRoutes(network.name);
|
||||
this.addHostRoute(network);
|
||||
}
|
||||
// Add extra host route. For example, mms proxy or mmsc.
|
||||
|
@ -640,6 +641,15 @@ NetworkManager.prototype = {
|
|||
this.worker.postMessage(options);
|
||||
},
|
||||
|
||||
removeHostRoutes: function removeHostRoutes(ifname) {
|
||||
debug("Going to remove all host routes on " + ifname);
|
||||
let options = {
|
||||
cmd: "removeHostRoutes",
|
||||
ifname: ifname,
|
||||
};
|
||||
this.worker.postMessage(options);
|
||||
},
|
||||
|
||||
resolveHostname: function resolveHostname(hosts) {
|
||||
let retval = [];
|
||||
|
||||
|
|
|
@ -3242,7 +3242,30 @@ RILNetworkInterface.prototype = {
|
|||
if (this.cid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.state == datacall.state) {
|
||||
if (datacall.state != GECKO_NETWORK_STATE_CONNECTED) {
|
||||
return;
|
||||
}
|
||||
// State remains connected, check for minor changes.
|
||||
let changed = false;
|
||||
if (this.gateway != datacall.gw) {
|
||||
this.gateway = datacall.gw;
|
||||
changed = true;
|
||||
}
|
||||
if (datacall.dns &&
|
||||
(this.dns1 != datacall.dns[0] ||
|
||||
this.dns2 != datacall.dns[1])) {
|
||||
this.dns1 = datacall.dns[0];
|
||||
this.dns2 = datacall.dns[1];
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
if (DEBUG) this.debug("Notify for data call minor changes.");
|
||||
Services.obs.notifyObservers(this,
|
||||
kNetworkInterfaceStateChangedTopic,
|
||||
null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -275,6 +275,13 @@ function removeHostRoute(options) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the routes associated with the named interface.
|
||||
*/
|
||||
function removeHostRoutes(options) {
|
||||
libnetutils.ifc_remove_host_routes(options.ifname);
|
||||
}
|
||||
|
||||
function removeNetworkRoute(options) {
|
||||
let ipvalue = netHelpers.stringToIP(options.ip);
|
||||
let netmaskvalue = netHelpers.stringToIP(options.netmask);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/**
|
||||
* Information about networks that is exposed to network manager API consumers.
|
||||
*/
|
||||
[scriptable, uuid(04fe5049-1ea8-4b4f-8c27-d23cd24611bb)]
|
||||
[scriptable, uuid(f4cf9d88-f962-4d29-9baa-fb295dad387b)]
|
||||
interface nsINetworkInterface : nsISupports
|
||||
{
|
||||
const long NETWORK_STATE_UNKNOWN = -1;
|
||||
|
@ -24,6 +24,7 @@ interface nsINetworkInterface : nsISupports
|
|||
*/
|
||||
readonly attribute long state;
|
||||
|
||||
const long NETWORK_TYPE_UNKNOWN = -1;
|
||||
const long NETWORK_TYPE_WIFI = 0;
|
||||
const long NETWORK_TYPE_MOBILE = 1;
|
||||
const long NETWORK_TYPE_MOBILE_MMS = 2;
|
||||
|
|
|
@ -450,6 +450,7 @@ this.NETWORK_CREG_TECH_LTE = 14;
|
|||
this.NETWORK_CREG_TECH_HSPAP = 15;
|
||||
this.NETWORK_CREG_TECH_GSM = 16;
|
||||
|
||||
this.CALL_STATE_UNKNOWN = -1;
|
||||
this.CALL_STATE_ACTIVE = 0;
|
||||
this.CALL_STATE_HOLDING = 1;
|
||||
this.CALL_STATE_DIALING = 2;
|
||||
|
|
|
@ -3629,12 +3629,12 @@ let RIL = {
|
|||
delete this.currentConference.cache;
|
||||
|
||||
// Update the conference call's state.
|
||||
let state = null;
|
||||
let state = CALL_STATE_UNKNOWN;
|
||||
for each (let call in this.currentConference.participants) {
|
||||
if (state && state != call.state) {
|
||||
if (state != CALL_STATE_UNKNOWN && state != call.state) {
|
||||
// Each participant should have the same state, otherwise something
|
||||
// wrong happens.
|
||||
state = null;
|
||||
state = CALL_STATE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
state = call.state;
|
||||
|
@ -3677,6 +3677,27 @@ let RIL = {
|
|||
this.sendChromeMessage(message);
|
||||
},
|
||||
|
||||
_compareDataCallLink: function _compareDataCallLink(source, target) {
|
||||
if (source.ifname != target.ifname ||
|
||||
source.ipaddr != target.ipaddr ||
|
||||
source.gw != target.gw) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare <datacall>.dns.
|
||||
let sdns = source.dns, tdns = target.dns;
|
||||
if (sdns.length != tdns.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < sdns.length; i++) {
|
||||
if (sdns[i] != tdns[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_processDataCallList: function _processDataCallList(datacalls, newDataCallOptions) {
|
||||
// Check for possible PDP errors: We check earlier because the datacall
|
||||
// can be removed if is the same as the current one.
|
||||
|
@ -3700,6 +3721,7 @@ let RIL = {
|
|||
// If datacalls list is coming from REQUEST_SETUP_DATA_CALL response,
|
||||
// we do not change state for any currentDataCalls not in datacalls list.
|
||||
if (!newDataCallOptions) {
|
||||
delete this.currentDataCalls[currentDataCall.cid];
|
||||
currentDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
|
||||
currentDataCall.rilMessageType = "datacallstatechange";
|
||||
this.sendChromeMessage(currentDataCall);
|
||||
|
@ -3717,31 +3739,60 @@ let RIL = {
|
|||
|
||||
this._setDataCallGeckoState(updatedDataCall);
|
||||
if (updatedDataCall.state != currentDataCall.state) {
|
||||
if (updatedDataCall.state == GECKO_NETWORK_STATE_DISCONNECTED) {
|
||||
delete this.currentDataCalls[currentDataCall.cid];
|
||||
}
|
||||
currentDataCall.status = updatedDataCall.status;
|
||||
currentDataCall.active = updatedDataCall.active;
|
||||
currentDataCall.state = updatedDataCall.state;
|
||||
currentDataCall.rilMessageType = "datacallstatechange";
|
||||
this.sendChromeMessage(currentDataCall);
|
||||
continue;
|
||||
}
|
||||
|
||||
// State not changed, now check links.
|
||||
if (this._compareDataCallLink(updatedDataCall, currentDataCall)) {
|
||||
if(DEBUG) debug("No changes in data call.");
|
||||
continue;
|
||||
}
|
||||
if ((updatedDataCall.ifname != currentDataCall.ifname) ||
|
||||
(updatedDataCall.ipaddr != currentDataCall.ipaddr)) {
|
||||
if(DEBUG) debug("Data link changed, cleanup.");
|
||||
this.deactivateDataCall(currentDataCall);
|
||||
continue;
|
||||
}
|
||||
// Minor change, just update and notify.
|
||||
if(DEBUG) debug("Data link minor change, just update and notify.");
|
||||
currentDataCall.gw = updatedDataCall.gw;
|
||||
if (updatedDataCall.dns) {
|
||||
currentDataCall.dns[0] = updatedDataCall.dns[0];
|
||||
currentDataCall.dns[1] = updatedDataCall.dns[1];
|
||||
}
|
||||
currentDataCall.rilMessageType = "datacallstatechange";
|
||||
this.sendChromeMessage(currentDataCall);
|
||||
}
|
||||
|
||||
for each (let newDataCall in datacalls) {
|
||||
if (!newDataCall.ifname) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!newDataCallOptions) {
|
||||
if (DEBUG) debug("Unexpected new data call: " + JSON.stringify(newDataCall));
|
||||
continue;
|
||||
}
|
||||
|
||||
this.currentDataCalls[newDataCall.cid] = newDataCall;
|
||||
this._setDataCallGeckoState(newDataCall);
|
||||
if (newDataCallOptions) {
|
||||
newDataCall.radioTech = newDataCallOptions.radioTech;
|
||||
newDataCall.apn = newDataCallOptions.apn;
|
||||
newDataCall.user = newDataCallOptions.user;
|
||||
newDataCall.passwd = newDataCallOptions.passwd;
|
||||
newDataCall.chappap = newDataCallOptions.chappap;
|
||||
newDataCall.pdptype = newDataCallOptions.pdptype;
|
||||
newDataCallOptions = null;
|
||||
} else if (DEBUG) {
|
||||
debug("Unexpected new data call: " + JSON.stringify(newDataCall));
|
||||
}
|
||||
|
||||
newDataCall.radioTech = newDataCallOptions.radioTech;
|
||||
newDataCall.apn = newDataCallOptions.apn;
|
||||
newDataCall.user = newDataCallOptions.user;
|
||||
newDataCall.passwd = newDataCallOptions.passwd;
|
||||
newDataCall.chappap = newDataCallOptions.chappap;
|
||||
newDataCall.pdptype = newDataCallOptions.pdptype;
|
||||
newDataCallOptions = null;
|
||||
|
||||
newDataCall.rilMessageType = "datacallstatechange";
|
||||
this.sendChromeMessage(newDataCall);
|
||||
}
|
||||
|
|
|
@ -216,6 +216,8 @@ TelephonyProvider.prototype = {
|
|||
|
||||
_convertRILCallState: function _convertRILCallState(aState) {
|
||||
switch (aState) {
|
||||
case RIL.CALL_STATE_UNKNOWN:
|
||||
return nsITelephonyProvider.CALL_STATE_UNKNOWN;
|
||||
case RIL.CALL_STATE_ACTIVE:
|
||||
return nsITelephonyProvider.CALL_STATE_CONNECTED;
|
||||
case RIL.CALL_STATE_HOLDING:
|
||||
|
@ -492,8 +494,7 @@ TelephonyProvider.prototype = {
|
|||
|
||||
notifyConferenceCallStateChanged: function notifyConferenceCallStateChanged(aState) {
|
||||
if (DEBUG) debug("handleConferenceCallStateChanged: " + aState);
|
||||
aState = aState != null ? this._convertRILCallState(aState) :
|
||||
nsITelephonyProvider.CALL_STATE_UNKNOWN;
|
||||
aState = this._convertRILCallState(aState);
|
||||
this._updateCallAudioState(null, aState);
|
||||
|
||||
this._notifyAllListeners("conferenceCallStateChanged", [aState]);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"@mozilla.org/telephony/gonktelephonyprovider;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(0d106c7e-ba47-48ee-ba48-c92002d401b6)]
|
||||
[scriptable, uuid(f072f334-e4ea-4754-9929-533da30444a8)]
|
||||
interface nsIGonkTelephonyProvider : nsITelephonyProvider
|
||||
{
|
||||
void notifyCallDisconnected(in jsval call);
|
||||
|
@ -27,5 +27,5 @@ interface nsIGonkTelephonyProvider : nsITelephonyProvider
|
|||
void notifySupplementaryService(in long callIndex,
|
||||
in AString notification);
|
||||
|
||||
void notifyConferenceCallStateChanged(in unsigned short state);
|
||||
void notifyConferenceCallStateChanged(in short state);
|
||||
};
|
||||
|
|
|
@ -58,12 +58,17 @@ function verifyInitialState() {
|
|||
ok(telephony);
|
||||
ok(conference);
|
||||
|
||||
checkState(null, [], '', []);
|
||||
|
||||
sendCmdToEmulator("gsm clear", function(result) {
|
||||
log("Clear up calls from a previous test if any.");
|
||||
is(result[0], "OK");
|
||||
dial();
|
||||
|
||||
// No more calls in the list; give time for emulator to catch up.
|
||||
waitFor(function next() {
|
||||
checkState(null, [], '', []);
|
||||
dial();
|
||||
}, function isDone() {
|
||||
return (telephony.calls.length == 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -200,6 +205,7 @@ function conferenceAddTwoCalls() {
|
|||
let pending = ["conference.oncallschanged", "conference.onconnected",
|
||||
"outgoingCall.onstatechange", "outgoingCall.ongroupchange",
|
||||
"incomingCall.onstatechange", "incomingCall.ongroupchange"];
|
||||
let nextTest = conferenceHold;
|
||||
|
||||
// We are expecting to receive conference.oncallschanged two times since
|
||||
// two calls are added into conference.
|
||||
|
@ -214,7 +220,7 @@ function conferenceAddTwoCalls() {
|
|||
|
||||
if (expected.length == 0) {
|
||||
conference.oncallschanged = null;
|
||||
receivedPending("conference.oncallschanged", pending, conferenceHold);
|
||||
receivedPending("conference.oncallschanged", pending, nextTest);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -232,7 +238,7 @@ function conferenceAddTwoCalls() {
|
|||
is(result[1], "inbound from " + inNumber + " : active");
|
||||
is(result[2], "OK");
|
||||
|
||||
receivedPending("conference.onconnected", pending, conferenceHold);
|
||||
receivedPending("conference.onconnected", pending, nextTest);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -243,7 +249,7 @@ function conferenceAddTwoCalls() {
|
|||
ok(outgoingCall.group);
|
||||
is(outgoingCall.group, conference);
|
||||
|
||||
receivedPending("outgoingCall.ongroupchange", pending, conferenceHold);
|
||||
receivedPending("outgoingCall.ongroupchange", pending, nextTest);
|
||||
};
|
||||
|
||||
outgoingCall.onstatechange = function(event) {
|
||||
|
@ -253,7 +259,7 @@ function conferenceAddTwoCalls() {
|
|||
ok(!outgoingCall.ongroupchange);
|
||||
is(outgoingCall.state, conference.state);
|
||||
|
||||
receivedPending("outgoingCall.onstatechange", pending, conferenceHold);
|
||||
receivedPending("outgoingCall.onstatechange", pending, nextTest);
|
||||
};
|
||||
|
||||
incomingCall.ongroupchange = function(event) {
|
||||
|
@ -263,7 +269,7 @@ function conferenceAddTwoCalls() {
|
|||
ok(incomingCall.group);
|
||||
is(incomingCall.group, conference);
|
||||
|
||||
receivedPending("incomingCall.ongroupchange", pending, conferenceHold);
|
||||
receivedPending("incomingCall.ongroupchange", pending, nextTest);
|
||||
};
|
||||
|
||||
incomingCall.onstatechange = function(event) {
|
||||
|
@ -273,7 +279,7 @@ function conferenceAddTwoCalls() {
|
|||
ok(!incomingCall.ongroupchange);
|
||||
is(incomingCall.state, conference.state);
|
||||
|
||||
receivedPending("incomingCall.onstatechange", pending, conferenceHold);
|
||||
receivedPending("incomingCall.onstatechange", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.add(outgoingCall, incomingCall);
|
||||
|
@ -285,6 +291,7 @@ function conferenceHold() {
|
|||
let pending = ["conference.onholding", "conference.onheld",
|
||||
"outgoingCall.onholding", "outgoingCall.onheld",
|
||||
"incomingCall.onholding", "incomingCall.onheld"];
|
||||
let nextTest = conferenceResume;
|
||||
|
||||
conference.onholding = function(event) {
|
||||
log("Received 'holding' event for the conference call.");
|
||||
|
@ -292,7 +299,7 @@ function conferenceHold() {
|
|||
|
||||
is(conference.state, 'holding');
|
||||
|
||||
receivedPending("conference.onholding", pending, conferenceResume);
|
||||
receivedPending("conference.onholding", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.onheld = function(event) {
|
||||
|
@ -308,7 +315,7 @@ function conferenceHold() {
|
|||
is(result[1], "inbound from " + inNumber + " : held");
|
||||
is(result[2], "OK");
|
||||
|
||||
receivedPending("conference.onheld", pending, conferenceResume);
|
||||
receivedPending("conference.onheld", pending, nextTest);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -318,7 +325,7 @@ function conferenceHold() {
|
|||
|
||||
is(outgoingCall.state, 'holding');
|
||||
|
||||
receivedPending("outgoingCall.onholding", pending, conferenceResume);
|
||||
receivedPending("outgoingCall.onholding", pending, nextTest);
|
||||
};
|
||||
|
||||
outgoingCall.onheld = function(event) {
|
||||
|
@ -328,7 +335,7 @@ function conferenceHold() {
|
|||
ok(!outgoingCall.onholding);
|
||||
is(outgoingCall.state, 'held');
|
||||
|
||||
receivedPending("outgoingCall.onheld", pending, conferenceResume);
|
||||
receivedPending("outgoingCall.onheld", pending, nextTest);
|
||||
};
|
||||
|
||||
incomingCall.onholding = function(event) {
|
||||
|
@ -337,7 +344,7 @@ function conferenceHold() {
|
|||
|
||||
is(incomingCall.state, 'holding');
|
||||
|
||||
receivedPending("incomingCall.onholding", pending, conferenceResume);
|
||||
receivedPending("incomingCall.onholding", pending, nextTest);
|
||||
};
|
||||
|
||||
incomingCall.onheld = function(event) {
|
||||
|
@ -347,7 +354,7 @@ function conferenceHold() {
|
|||
ok(!incomingCall.onholding);
|
||||
is(incomingCall.state, 'held');
|
||||
|
||||
receivedPending("incomingCall.onheld", pending, conferenceResume);
|
||||
receivedPending("incomingCall.onheld", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.hold();
|
||||
|
@ -359,6 +366,7 @@ function conferenceResume() {
|
|||
let pending = ["conference.onresuming", "conference.onconnected",
|
||||
"outgoingCall.onresuming", "outgoingCall.onconnected",
|
||||
"incomingCall.onresuming", "incomingCall.onconnected"];
|
||||
let nextTest = simulate2ndIncoming;
|
||||
|
||||
conference.onresuming = function(event) {
|
||||
log("Received 'resuming' event for the conference call.");
|
||||
|
@ -366,7 +374,7 @@ function conferenceResume() {
|
|||
|
||||
is(conference.state, 'resuming');
|
||||
|
||||
receivedPending("conference.onresuming", pending, simulate2ndIncoming);
|
||||
receivedPending("conference.onresuming", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.onconnected = function(event) {
|
||||
|
@ -382,7 +390,7 @@ function conferenceResume() {
|
|||
is(result[1], "inbound from " + inNumber + " : active");
|
||||
is(result[2], "OK");
|
||||
|
||||
receivedPending("conference.onconnected", pending, simulate2ndIncoming);
|
||||
receivedPending("conference.onconnected", pending, nextTest);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -392,7 +400,7 @@ function conferenceResume() {
|
|||
|
||||
is(outgoingCall.state, 'resuming');
|
||||
|
||||
receivedPending("outgoingCall.onresuming", pending, simulate2ndIncoming);
|
||||
receivedPending("outgoingCall.onresuming", pending, nextTest);
|
||||
};
|
||||
|
||||
outgoingCall.onconnected = function(event) {
|
||||
|
@ -402,7 +410,7 @@ function conferenceResume() {
|
|||
ok(!outgoingCall.onresuming);
|
||||
is(outgoingCall.state, 'connected');
|
||||
|
||||
receivedPending("outgoingCall.onconnected", pending, simulate2ndIncoming);
|
||||
receivedPending("outgoingCall.onconnected", pending, nextTest);
|
||||
};
|
||||
|
||||
incomingCall.onresuming = function(event) {
|
||||
|
@ -411,7 +419,7 @@ function conferenceResume() {
|
|||
|
||||
is(incomingCall.state, 'resuming');
|
||||
|
||||
receivedPending("incomingCall.onresuming", pending, simulate2ndIncoming);
|
||||
receivedPending("incomingCall.onresuming", pending, nextTest);
|
||||
};
|
||||
|
||||
incomingCall.onconnected = function(event) {
|
||||
|
@ -421,7 +429,7 @@ function conferenceResume() {
|
|||
ok(!incomingCall.onresuming);
|
||||
is(incomingCall.state, 'connected');
|
||||
|
||||
receivedPending("incomingCall.onconnected", pending, simulate2ndIncoming);
|
||||
receivedPending("incomingCall.onconnected", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.resume();
|
||||
|
@ -496,6 +504,7 @@ function conferenceAddOneCall() {
|
|||
let callToAdd = incomingCall2;
|
||||
let pending = ["conference.oncallschanged", "conference.onconnected",
|
||||
"callToAdd.ongroupchange", "callToAdd.onconnected"];
|
||||
let nextTest = conferenceRemove;
|
||||
|
||||
ok(!callToAdd.group);
|
||||
|
||||
|
@ -507,7 +516,7 @@ function conferenceAddOneCall() {
|
|||
is(conference.calls.length, 3);
|
||||
is(conference.calls[2].number, event.call.number);
|
||||
|
||||
receivedPending("conference.oncallschanged", pending, conferenceRemove);
|
||||
receivedPending("conference.oncallschanged", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.onconnected = function(event) {
|
||||
|
@ -526,7 +535,7 @@ function conferenceAddOneCall() {
|
|||
is(result[2], "inbound from " + inNumber2 + " : active");
|
||||
is(result[3], "OK");
|
||||
|
||||
receivedPending("conference.onconnected", pending, conferenceRemove);
|
||||
receivedPending("conference.onconnected", pending, nextTest);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -535,7 +544,7 @@ function conferenceAddOneCall() {
|
|||
callToAdd.ongroupchange = null;
|
||||
|
||||
is(callToAdd.group, conference);
|
||||
receivedPending("callToAdd.ongroupchange", pending, conferenceRemove);
|
||||
receivedPending("callToAdd.ongroupchange", pending, nextTest);
|
||||
};
|
||||
|
||||
callToAdd.onconnected = function(event) {
|
||||
|
@ -545,7 +554,7 @@ function conferenceAddOneCall() {
|
|||
ok(!callToAdd.ongroupchange);
|
||||
is(callToAdd.state, 'connected');
|
||||
|
||||
receivedPending("callToAdd.onconnected", pending, conferenceRemove);
|
||||
receivedPending("callToAdd.onconnected", pending, nextTest);
|
||||
};
|
||||
conference.add(callToAdd);
|
||||
}
|
||||
|
@ -560,6 +569,7 @@ function conferenceRemove() {
|
|||
let callToRemove = conference.calls[0];
|
||||
let pending = ["callToRemove.ongroupchange", "telephony.oncallschanged",
|
||||
"conference.oncallschanged", "conference.onstatechange"];
|
||||
let nextTest = emptyConference;
|
||||
|
||||
callToRemove.ongroupchange = function(event) {
|
||||
log("Received 'groupchange' event for the call to remove.");
|
||||
|
@ -568,7 +578,7 @@ function conferenceRemove() {
|
|||
ok(!callToRemove.group);
|
||||
is(callToRemove.state, 'connected');
|
||||
|
||||
receivedPending("callToRemove.ongroupchange", pending, cleanUp);
|
||||
receivedPending("callToRemove.ongroupchange", pending, nextTest);
|
||||
};
|
||||
|
||||
telephony.oncallschanged = function(event) {
|
||||
|
@ -582,7 +592,7 @@ function conferenceRemove() {
|
|||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0].number, event.call.number);
|
||||
|
||||
receivedPending("telephony.oncallschanged", pending, cleanUp);
|
||||
receivedPending("telephony.oncallschanged", pending, nextTest);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -593,7 +603,7 @@ function conferenceRemove() {
|
|||
is(event.call.number, callToRemove.number);
|
||||
is(conference.calls.length, 2);
|
||||
|
||||
receivedPending("conference.oncallschanged", pending, cleanUp);
|
||||
receivedPending("conference.oncallschanged", pending, nextTest);
|
||||
};
|
||||
|
||||
conference.onstatechange = function(event) {
|
||||
|
@ -612,13 +622,94 @@ function conferenceRemove() {
|
|||
is(result[2], "inbound from " + inNumber2 + " : held");
|
||||
is(result[3], "OK");
|
||||
|
||||
receivedPending("conference.onstatechange", pending, cleanUp);
|
||||
receivedPending("conference.onstatechange", pending, nextTest);
|
||||
});
|
||||
};
|
||||
|
||||
conference.remove(callToRemove);
|
||||
}
|
||||
|
||||
// We first release a call in telephony, then release a call in conference.
|
||||
// The only call left in conference will be automatically moved from conference
|
||||
// to the calls list of telephony.
|
||||
function emptyConference() {
|
||||
log("Release one call in conference.");
|
||||
|
||||
outgoingCall.ondisconnected = function(event) {
|
||||
log("Received 'disconnected' event for the outgoing call.");
|
||||
outgoingCall.ondisconnected = null;
|
||||
|
||||
checkState(null, [], 'held',
|
||||
[incomingCall, incomingCall2]);
|
||||
|
||||
// We are going to release incomingCall. Once released, incomingCall2
|
||||
// is going to be moved out of the conference call automatically.
|
||||
sendCmdToEmulator("gsm cancel " + inNumber);
|
||||
};
|
||||
|
||||
let pending = ["conference.oncallschanged", "conference.onstatechange",
|
||||
"incomingCall2.ongroupchange"];
|
||||
let nextTest = hangUpLastCall;
|
||||
|
||||
incomingCall2.ongroupchange = function(event) {
|
||||
log("Received 'groupchange' event for the outgoing call.");
|
||||
incomingCall2.ongroupchange = null;
|
||||
|
||||
ok(!incomingCall2.group);
|
||||
is(incomingCall2.state, 'held');
|
||||
|
||||
receivedPending("incomingCall2.ongroupchange", pending, nextTest);
|
||||
};
|
||||
|
||||
// We are expecting to receive conference.oncallschanged two times since
|
||||
// two calls are removed from conference.
|
||||
let expected = [incomingCall, incomingCall2];
|
||||
conference.oncallschanged = function(event) {
|
||||
log("Received 'callschanged' event for the conference call.");
|
||||
|
||||
let index = expected.indexOf(event.call);
|
||||
ok(index != -1);
|
||||
expected.splice(index, 1);
|
||||
|
||||
if (expected.length == 0) {
|
||||
conference.oncallschanged = null;
|
||||
is(conference.calls.length, 0);
|
||||
receivedPending("conference.oncallschanged", pending, nextTest);
|
||||
}
|
||||
};
|
||||
|
||||
conference.onstatechange = function(event) {
|
||||
log("Received 'statechange' event for the conference call.");
|
||||
conference.onstatechange = null;
|
||||
|
||||
ok(!conference.oncallschanged);
|
||||
checkState(null, [incomingCall2], '', []);
|
||||
|
||||
receivedPending("conference.onstatechange", pending, nextTest);
|
||||
};
|
||||
|
||||
sendCmdToEmulator("gsm cancel " + outNumber);
|
||||
}
|
||||
|
||||
function hangUpLastCall() {
|
||||
log("Going to leave the test. Hanging up the last call.");
|
||||
|
||||
incomingCall2.ondisconnected = function(event) {
|
||||
incomingCall2.ondisconnected = null;
|
||||
|
||||
checkState(null, [], '', []);
|
||||
|
||||
sendCmdToEmulator("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "OK");
|
||||
|
||||
cleanUp();
|
||||
});
|
||||
};
|
||||
|
||||
sendCmdToEmulator("gsm cancel " + inNumber2);
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
if (pendingEmulatorCmdCount) {
|
||||
window.setTimeout(cleanUp, 100);
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
@ -48,7 +48,7 @@ function dial() {
|
|||
outgoingCall.onalerting = function onalerting(event) {
|
||||
log("Received 'alerting' call event.");
|
||||
answer();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function answer() {
|
||||
|
@ -73,4 +73,4 @@ function cleanUp(){
|
|||
finish();
|
||||
}
|
||||
|
||||
getExistingCalls();
|
||||
getExistingCalls();
|
||||
|
|
|
@ -32,7 +32,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -27,7 +27,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -26,7 +26,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -25,7 +25,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -25,7 +25,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -36,7 +36,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -24,7 +24,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -121,6 +121,11 @@ function cleanUp() {
|
|||
setRadioEnabled(false, function() {
|
||||
sendToEmulator("gsm clear", function(result) {
|
||||
is(result[0], "OK");
|
||||
dial("0912345678");
|
||||
|
||||
waitFor(function() {
|
||||
dial("0912345678");
|
||||
}, function() {
|
||||
return telephony.calls.length === 0;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -23,7 +23,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -28,7 +28,7 @@ function getExistingCalls() {
|
|||
function cancelExistingCalls(callList) {
|
||||
if (callList.length && callList[0] != "OK") {
|
||||
// Existing calls remain; get rid of the next one in the list
|
||||
nextCall = callList.shift().split(' ')[2].trim();
|
||||
nextCall = callList.shift().split(/\s+/)[2].trim();
|
||||
log("Cancelling existing call '" + nextCall +"'");
|
||||
runEmulatorCmd("gsm cancel " + nextCall, function(result) {
|
||||
if (result[0] == "OK") {
|
||||
|
|
|
@ -133,7 +133,10 @@ public:
|
|||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
delete gHalDiskSpaceWatcher;
|
||||
if (gHalDiskSpaceWatcher) {
|
||||
delete gHalDiskSpaceWatcher;
|
||||
gHalDiskSpaceWatcher = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -885,7 +885,7 @@ DestroyAlarmData(void* aData)
|
|||
// Runs on alarm-watcher thread.
|
||||
void ShutDownAlarm(int aSigno)
|
||||
{
|
||||
if (aSigno == SIGUSR1) {
|
||||
if (aSigno == SIGUSR1 && sAlarmData) {
|
||||
sAlarmData->mShuttingDown = true;
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -2672,17 +2672,6 @@ bool nsPresContext::GetPaintFlashing() const
|
|||
return mPaintFlashing;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPresContext::IsDeviceSizePageSize()
|
||||
{
|
||||
bool isDeviceSizePageSize = false;
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
|
||||
if (docShell) {
|
||||
isDeviceSizePageSize = docShell->GetDeviceSizeIsPageSize();
|
||||
}
|
||||
return isDeviceSizePageSize;
|
||||
}
|
||||
|
||||
nsRootPresContext::nsRootPresContext(nsIDocument* aDocument,
|
||||
nsPresContextType aType)
|
||||
: nsPresContext(aDocument, aType),
|
||||
|
|
|
@ -1003,8 +1003,6 @@ public:
|
|||
mExistThrottledUpdates = aExistThrottledUpdates;
|
||||
}
|
||||
|
||||
bool IsDeviceSizePageSize();
|
||||
|
||||
protected:
|
||||
friend class nsRunnableMethod<nsPresContext>;
|
||||
NS_HIDDEN_(void) ThemeChangedInternal();
|
||||
|
|
|
@ -111,19 +111,14 @@ static nsSize
|
|||
GetDeviceSize(nsPresContext* aPresContext)
|
||||
{
|
||||
nsSize size;
|
||||
|
||||
if (aPresContext->IsDeviceSizePageSize()) {
|
||||
size = GetSize(aPresContext);
|
||||
} else if (aPresContext->IsRootPaginatedDocument()) {
|
||||
if (aPresContext->IsRootPaginatedDocument())
|
||||
// We want the page size, including unprintable areas and margins.
|
||||
// XXX The spec actually says we want the "page sheet size", but
|
||||
// how is that different?
|
||||
size = aPresContext->GetPageSize();
|
||||
} else {
|
||||
else
|
||||
GetDeviceContextFor(aPresContext)->
|
||||
GetDeviceSurfaceDimensions(size.width, size.height);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
@ -2257,7 +2257,7 @@ public class GeckoAppShell
|
|||
sEventDispatcher.registerEventListener(event, listener);
|
||||
}
|
||||
|
||||
static EventDispatcher getEventDispatcher() {
|
||||
public static EventDispatcher getEventDispatcher() {
|
||||
return sEventDispatcher;
|
||||
}
|
||||
|
||||
|
|
|
@ -220,14 +220,12 @@ FENNEC_JAVA_FILES = \
|
|||
home/BookmarkThumbnailView.java \
|
||||
home/BrowserSearch.java \
|
||||
home/HistoryPage.java \
|
||||
home/HomeCursorLoaderCallbacks.java \
|
||||
home/HomeFragment.java \
|
||||
home/HomeListView.java \
|
||||
home/HomePager.java \
|
||||
home/HomePagerTabStrip.java \
|
||||
home/HomeBanner.java \
|
||||
home/FadedTextView.java \
|
||||
home/FaviconsLoader.java \
|
||||
home/LastTabsPage.java \
|
||||
home/MostRecentPage.java \
|
||||
home/MostVisitedPage.java \
|
||||
|
|
|
@ -25,6 +25,7 @@ SYNC_JAVA_FILES := \
|
|||
background/bagheera/BagheeraRequestDelegate.java \
|
||||
background/bagheera/BoundedByteArrayEntity.java \
|
||||
background/bagheera/DeflateHelper.java \
|
||||
background/common/DateUtils.java \
|
||||
background/common/log/Logger.java \
|
||||
background/common/log/writers/AndroidLevelCachingLogWriter.java \
|
||||
background/common/log/writers/AndroidLogWriter.java \
|
||||
|
|
|
@ -160,12 +160,17 @@ public class PropertyAnimator implements Runnable {
|
|||
}
|
||||
|
||||
// Try to start animation after any on-going layout round
|
||||
// in the current view tree.
|
||||
if (treeObserver != null && treeObserver.isAlive()) {
|
||||
// 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()) {
|
||||
treeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
treeObserver.removeOnPreDrawListener(this);
|
||||
if (treeObserver.isAlive()) {
|
||||
treeObserver.removeOnPreDrawListener(this);
|
||||
}
|
||||
|
||||
mFramePoster.postFirstAnimationFrame();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.background.common;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Formatter;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class DateUtils {
|
||||
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
|
||||
|
||||
public static final class DateFormatter {
|
||||
private final Calendar calendar;
|
||||
private final Formatter formatter;
|
||||
private final StringBuilder builder;
|
||||
|
||||
public DateFormatter() {
|
||||
this.calendar = Calendar.getInstance(UTC);
|
||||
this.builder = new StringBuilder(); // So we can reset it.
|
||||
this.formatter = new Formatter(this.builder, null);
|
||||
}
|
||||
|
||||
public String getDateString(long time) {
|
||||
calendar.setTimeInMillis(time);
|
||||
builder.setLength(0);
|
||||
return formatter.format("%04d-%02d-%02d",
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH) + 1, // 0-indexed.
|
||||
calendar.get(Calendar.DAY_OF_MONTH))
|
||||
.toString();
|
||||
}
|
||||
|
||||
public String getDateStringForDay(long day) {
|
||||
return getDateString(GlobalConstants.MILLISECONDS_PER_DAY * day);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDay(final long time) {
|
||||
return (int) Math.floor(time / GlobalConstants.MILLISECONDS_PER_DAY);
|
||||
}
|
||||
}
|
|
@ -47,4 +47,8 @@ public class GlobalConstants {
|
|||
public static String GECKO_PREFERENCES_CLASS = "org.mozilla.gecko.GeckoPreferences";
|
||||
public static String GECKO_BROADCAST_ANNOUNCEMENTS_PREF_METHOD = "broadcastAnnouncementsPref";
|
||||
public static String GECKO_BROADCAST_HEALTHREPORT_UPLOAD_PREF_METHOD = "broadcastHealthReportUploadPref";
|
||||
|
||||
// Common time values.
|
||||
public static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
public static final long MILLISECONDS_PER_SIX_MONTHS = 180 * MILLISECONDS_PER_DAY;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Iterator;
|
|||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.SysInfo;
|
||||
import org.mozilla.gecko.background.common.GlobalConstants;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
|
@ -77,7 +78,7 @@ public class EnvironmentBuilder {
|
|||
e.sysName = SysInfo.getName();
|
||||
e.sysVersion = SysInfo.getReleaseVersion();
|
||||
|
||||
e.profileCreation = (int) (info.getProfileCreationTime() / HealthReportConstants.MILLISECONDS_PER_DAY);
|
||||
e.profileCreation = (int) (info.getProfileCreationTime() / GlobalConstants.MILLISECONDS_PER_DAY);
|
||||
|
||||
// Corresponds to Gecko pref "extensions.blocklist.enabled".
|
||||
e.isBlocklistEnabled = (info.isBlocklistEnabled() ? 1 : 0);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package org.mozilla.gecko.background.healthreport;
|
||||
|
||||
import org.mozilla.gecko.background.common.GlobalConstants;
|
||||
|
||||
public class HealthReportConstants {
|
||||
public static final String HEALTH_AUTHORITY = "@ANDROID_PACKAGE_NAME@.health";
|
||||
public static final String GLOBAL_LOG_TAG = "GeckoHealth";
|
||||
|
@ -15,9 +17,6 @@ public class HealthReportConstants {
|
|||
*/
|
||||
public static final long EARLIEST_LAST_PING = 1367500000000L;
|
||||
|
||||
public static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
public static final long MILLISECONDS_PER_SIX_MONTHS = 180 * MILLISECONDS_PER_DAY;
|
||||
|
||||
// Not `final` so we have the option to turn this on at runtime with a magic addon.
|
||||
public static boolean UPLOAD_FEATURE_DISABLED = false;
|
||||
|
||||
|
@ -29,15 +28,15 @@ public class HealthReportConstants {
|
|||
// intent is scheduled to be called by the Android Alarm Manager, not how
|
||||
// frequently we actually submit.
|
||||
public static final String PREF_SUBMISSION_INTENT_INTERVAL_MSEC = "healthreport_submission_intent_interval_msec";
|
||||
public static final long DEFAULT_SUBMISSION_INTENT_INTERVAL_MSEC = MILLISECONDS_PER_DAY / 24;
|
||||
public static final long DEFAULT_SUBMISSION_INTENT_INTERVAL_MSEC = GlobalConstants.MILLISECONDS_PER_DAY / 24;
|
||||
|
||||
public static final String ACTION_HEALTHREPORT_UPLOAD_PREF = "@ANDROID_PACKAGE_NAME@.HEALTHREPORT_UPLOAD_PREF";
|
||||
|
||||
public static final String PREF_MINIMUM_TIME_BETWEEN_UPLOADS = "healthreport_time_between_uploads";
|
||||
public static final long DEFAULT_MINIMUM_TIME_BETWEEN_UPLOADS = MILLISECONDS_PER_DAY;
|
||||
public static final long DEFAULT_MINIMUM_TIME_BETWEEN_UPLOADS = GlobalConstants.MILLISECONDS_PER_DAY;
|
||||
|
||||
public static final String PREF_MINIMUM_TIME_BEFORE_FIRST_SUBMISSION = "healthreport_time_before_first_submission";
|
||||
public static final long DEFAULT_MINIMUM_TIME_BEFORE_FIRST_SUBMISSION = MILLISECONDS_PER_DAY;
|
||||
public static final long DEFAULT_MINIMUM_TIME_BEFORE_FIRST_SUBMISSION = GlobalConstants.MILLISECONDS_PER_DAY;
|
||||
|
||||
public static final String PREF_MINIMUM_TIME_AFTER_FAILURE = "healthreport_time_after_failure";
|
||||
public static final long DEFAULT_MINIMUM_TIME_AFTER_FAILURE = DEFAULT_SUBMISSION_INTENT_INTERVAL_MSEC;
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.background.common.DateUtils;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportStorage.MeasurementFields.FieldSpec;
|
||||
|
||||
|
@ -1029,7 +1030,7 @@ public class HealthReportDatabaseStorage implements HealthReportStorage {
|
|||
|
||||
@Override
|
||||
public int getDay(long time) {
|
||||
return HealthReportUtils.getDay(time);
|
||||
return DateUtils.getDay(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Set;
|
|||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.background.common.DateUtils.DateFormatter;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportStorage.Field;
|
||||
|
||||
|
@ -22,9 +23,11 @@ public class HealthReportGenerator {
|
|||
private static final String LOG_TAG = "GeckoHealthGen";
|
||||
|
||||
private final HealthReportStorage storage;
|
||||
private final DateFormatter dateFormatter;
|
||||
|
||||
public HealthReportGenerator(HealthReportStorage storage) {
|
||||
this.storage = storage;
|
||||
this.dateFormatter = new DateFormatter();
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-method")
|
||||
|
@ -76,10 +79,10 @@ public class HealthReportGenerator {
|
|||
JSONObject document = new JSONObject();
|
||||
|
||||
if (lastPingTime >= HealthReportConstants.EARLIEST_LAST_PING) {
|
||||
document.put("lastPingDate", HealthReportUtils.getDateString(lastPingTime));
|
||||
document.put("lastPingDate", dateFormatter.getDateString(lastPingTime));
|
||||
}
|
||||
|
||||
document.put("thisPingDate", HealthReportUtils.getDateString(now()));
|
||||
document.put("thisPingDate", dateFormatter.getDateString(now()));
|
||||
document.put("version", PAYLOAD_VERSION);
|
||||
|
||||
document.put("environments", getEnvironmentsJSON(currentEnvironment, envs));
|
||||
|
@ -147,7 +150,7 @@ public class HealthReportGenerator {
|
|||
|
||||
if (dateChanged) {
|
||||
if (dateObject != null) {
|
||||
days.put(HealthReportUtils.getDateStringForDay(lastDate), dateObject);
|
||||
days.put(dateFormatter.getDateStringForDay(lastDate), dateObject);
|
||||
}
|
||||
dateObject = new JSONObject();
|
||||
lastDate = cDate;
|
||||
|
@ -179,7 +182,7 @@ public class HealthReportGenerator {
|
|||
cursor.moveToNext();
|
||||
continue;
|
||||
}
|
||||
days.put(HealthReportUtils.getDateStringForDay(lastDate), dateObject);
|
||||
days.put(dateFormatter.getDateStringForDay(lastDate), dateObject);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
|
|
|
@ -4,13 +4,10 @@
|
|||
|
||||
package org.mozilla.gecko.background.healthreport;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -25,24 +22,10 @@ import android.net.Uri;
|
|||
public class HealthReportUtils {
|
||||
public static final String LOG_TAG = HealthReportUtils.class.getSimpleName();
|
||||
|
||||
public static int getDay(final long time) {
|
||||
return (int) Math.floor(time / HealthReportConstants.MILLISECONDS_PER_DAY);
|
||||
}
|
||||
|
||||
public static String getEnvironmentHash(final String input) {
|
||||
return DigestUtils.shaHex(input);
|
||||
}
|
||||
|
||||
public static String getDateStringForDay(long day) {
|
||||
return getDateString(HealthReportConstants.MILLISECONDS_PER_DAY * day);
|
||||
}
|
||||
|
||||
public static String getDateString(long time) {
|
||||
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return format.format(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take an environment URI (one that identifies an environment) and produce an
|
||||
* event URI.
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Collection;
|
|||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.background.bagheera.BagheeraClient;
|
||||
import org.mozilla.gecko.background.bagheera.BagheeraRequestDelegate;
|
||||
import org.mozilla.gecko.background.common.GlobalConstants;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.healthreport.EnvironmentBuilder;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportConstants;
|
||||
|
@ -103,7 +104,7 @@ public class AndroidSubmissionClient implements SubmissionClient {
|
|||
return;
|
||||
}
|
||||
|
||||
long since = localTime - HealthReportConstants.MILLISECONDS_PER_SIX_MONTHS;
|
||||
long since = localTime - GlobalConstants.MILLISECONDS_PER_SIX_MONTHS;
|
||||
long last = Math.max(getLastUploadLocalTime(), HealthReportConstants.EARLIEST_LAST_PING);
|
||||
|
||||
if (!storage.hasEventSince(last)) {
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.mozilla.gecko.GeckoEvent;
|
|||
import org.mozilla.gecko.GeckoProfile;
|
||||
|
||||
import org.mozilla.gecko.background.healthreport.EnvironmentBuilder;
|
||||
import org.mozilla.gecko.background.common.GlobalConstants;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportConstants;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportDatabaseStorage;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportGenerator;
|
||||
|
@ -124,7 +125,7 @@ public class BrowserHealthReporter implements GeckoEventListener {
|
|||
GeckoProfile profile = GeckoAppShell.getGeckoInterface().getProfile();
|
||||
String profilePath = profile.getDir().getAbsolutePath();
|
||||
|
||||
long since = System.currentTimeMillis() - HealthReportConstants.MILLISECONDS_PER_SIX_MONTHS;
|
||||
long since = System.currentTimeMillis() - GlobalConstants.MILLISECONDS_PER_SIX_MONTHS;
|
||||
long lastPingTime = Math.max(getLastUploadLocalTime(), HealthReportConstants.EARLIEST_LAST_PING);
|
||||
|
||||
return generateReport(since, lastPingTime, profilePath);
|
||||
|
|
|
@ -179,7 +179,7 @@ public class BookmarksPage extends HomeFragment {
|
|||
BrowserDB.invalidateCachedState();
|
||||
|
||||
// Create callbacks before the initial loader is started.
|
||||
mLoaderCallbacks = new CursorLoaderCallbacks(activity, getLoaderManager());
|
||||
mLoaderCallbacks = new CursorLoaderCallbacks();
|
||||
mThumbnailsLoaderCallbacks = new ThumbnailsLoaderCallbacks();
|
||||
loadIfVisible();
|
||||
}
|
||||
|
@ -453,11 +453,7 @@ public class BookmarksPage extends HomeFragment {
|
|||
/**
|
||||
* Loader callbacks for the LoaderManager of this fragment.
|
||||
*/
|
||||
private class CursorLoaderCallbacks extends HomeCursorLoaderCallbacks {
|
||||
public CursorLoaderCallbacks(Context context, LoaderManager loaderManager) {
|
||||
super(context, loaderManager);
|
||||
}
|
||||
|
||||
private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
switch(id) {
|
||||
|
@ -472,11 +468,9 @@ public class BookmarksPage extends HomeFragment {
|
|||
case LOADER_ID_TOP_BOOKMARKS: {
|
||||
return new TopBookmarksLoader(getActivity());
|
||||
}
|
||||
|
||||
default: {
|
||||
return super.onCreateLoader(id, args);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -485,7 +479,6 @@ public class BookmarksPage extends HomeFragment {
|
|||
switch(loaderId) {
|
||||
case LOADER_ID_BOOKMARKS_LIST: {
|
||||
mListAdapter.swapCursor(c);
|
||||
loadFavicons(c);
|
||||
mList.setHeaderDividersEnabled(c != null && c.getCount() > 0);
|
||||
break;
|
||||
}
|
||||
|
@ -509,11 +502,6 @@ public class BookmarksPage extends HomeFragment {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
super.onLoadFinished(loader, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,18 +522,8 @@ public class BookmarksPage extends HomeFragment {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
super.onLoaderReset(loader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFaviconsLoaded() {
|
||||
mListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче