mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
d21149fffa
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="90f848a40efad820ab00fa52bec52dff37255b12"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="90f848a40efad820ab00fa52bec52dff37255b12"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d",
|
||||
"git_revision": "4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "6238380e300e25c4ec8aea2a8804d0ca3675f7fb",
|
||||
"revision": "3057b08e087df6d1ee21ca3a3741e56bb78021a1",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="90f848a40efad820ab00fa52bec52dff37255b12"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d4f756aa35cb7f030a92f3c1f65fb55254ddd1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4d87112bbf48cdd09c19e553cc9aebd2a2c4ddfd"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -147,8 +147,8 @@ let gTests = [
|
||||
Assert.ok(tabOpened);
|
||||
Assert.equal(tokenData.code, "code1");
|
||||
Assert.equal(tokenData.state, "state");
|
||||
Assert.equal(keys.kAr, "kAr");
|
||||
Assert.equal(keys.kBr, "kBr");
|
||||
Assert.deepEqual(keys.kAr, {k: "kAr"});
|
||||
Assert.deepEqual(keys.kBr, {k: "kBr"});
|
||||
resolve();
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,9 @@
|
||||
state: "state",
|
||||
code: "code1",
|
||||
closeWindow: "signin",
|
||||
keys: { kAr: 'kAr', kBr: 'kBr' },
|
||||
// Keys normally contain more information, but this is enough
|
||||
// to keep Loop's tests happy.
|
||||
keys: { kAr: { k: 'kAr' }, kBr: { k: 'kBr' }},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -202,10 +202,10 @@ let LoopRoomsInternal = {
|
||||
* information.
|
||||
*/
|
||||
promiseEncryptRoomData: Task.async(function* (roomData) {
|
||||
// For now, disable encryption/context if context is disabled, or if
|
||||
// FxA is turned on.
|
||||
if (!MozLoopService.getLoopPref("contextInConverations.enabled") ||
|
||||
this.sessionType == LOOP_SESSION_TYPE.FXA) {
|
||||
// XXX We should only return unencrypted data whilst we're still working
|
||||
// on context. Once bug 1115340 is fixed, this function should no longer be
|
||||
// here.
|
||||
function getUnencryptedData() {
|
||||
var serverRoomData = extend({}, roomData);
|
||||
delete serverRoomData.decryptedContext;
|
||||
|
||||
@ -218,6 +218,11 @@ let LoopRoomsInternal = {
|
||||
};
|
||||
}
|
||||
|
||||
// For now, disable encryption/context if context is disabled
|
||||
if (!MozLoopService.getLoopPref("contextInConverations.enabled")) {
|
||||
return getUnencryptedData();
|
||||
}
|
||||
|
||||
var newRoomData = extend({}, roomData);
|
||||
|
||||
if (!newRoomData.context) {
|
||||
@ -227,7 +232,17 @@ let LoopRoomsInternal = {
|
||||
// First get the room key.
|
||||
let key = yield this.promiseGetOrCreateRoomKey(newRoomData);
|
||||
|
||||
newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key);
|
||||
try {
|
||||
newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key);
|
||||
}
|
||||
catch (ex) {
|
||||
// XXX Bug 1153788 should remove this, then we can remove the whole
|
||||
// try/catch.
|
||||
if (ex.message == "FxA re-register not implemented") {
|
||||
return getUnencryptedData();
|
||||
}
|
||||
return Promise.reject(ex);
|
||||
}
|
||||
|
||||
// Now encrypt the actual data.
|
||||
newRoomData.context.value = yield loopCrypto.encryptBytes(key,
|
||||
@ -654,8 +669,7 @@ let LoopRoomsInternal = {
|
||||
};
|
||||
|
||||
// If we're not encrypting currently, then only send the roomName.
|
||||
if (!Services.prefs.getBoolPref("loop.contextInConverations.enabled") ||
|
||||
this.sessionType == LOOP_SESSION_TYPE.FXA) {
|
||||
if (!Services.prefs.getBoolPref("loop.contextInConverations.enabled")) {
|
||||
sendData = {
|
||||
roomName: newRoomName
|
||||
};
|
||||
|
@ -959,6 +959,9 @@ let MozLoopServiceInternal = {
|
||||
|
||||
gFxAOAuthClientPromise = this.promiseFxAOAuthParameters().then(
|
||||
parameters => {
|
||||
// Add the fact that we want keys to the parameters.
|
||||
parameters.keys = true;
|
||||
|
||||
try {
|
||||
gFxAOAuthClient = new FxAccountsOAuthClient({
|
||||
parameters: parameters,
|
||||
@ -1031,7 +1034,10 @@ let MozLoopServiceInternal = {
|
||||
* @param {Deferred} deferred used to resolve the gFxAOAuthClientPromise
|
||||
* @param {Object} result (with code and state)
|
||||
*/
|
||||
_fxAOAuthComplete: function(deferred, result) {
|
||||
_fxAOAuthComplete: function(deferred, result, keys) {
|
||||
if (keys.kBr) {
|
||||
Services.prefs.setCharPref("loop.key.fxa", keys.kBr.k);
|
||||
}
|
||||
gFxAOAuthClientPromise = null;
|
||||
// Note: The state was already verified in FxAccountsOAuthClient.
|
||||
deferred.resolve(result);
|
||||
@ -1331,8 +1337,14 @@ this.MozLoopService = {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.userProfile) {
|
||||
// We're an FxA user.
|
||||
// XXX Bug 1153788 will implement this for FxA.
|
||||
reject(new Error("unimplemented"));
|
||||
if (Services.prefs.prefHasUserValue("loop.key.fxa")) {
|
||||
resolve(MozLoopService.getLoopPref("key.fxa"));
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX If we don't have a key for FxA yet, then simply reject for now.
|
||||
// We'll create some sign-in/sign-out UX in bug 1153788.
|
||||
reject(new Error("FxA re-register not implemented"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -240,6 +240,18 @@ loop.shared.mixins = (function() {
|
||||
rootObject.removeEventListener("resize", this.updateVideoContainer);
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the dimensions cache, e.g. for when the session is ended, and
|
||||
* before a new session, so that we always ensure we see an update when a
|
||||
* new session is started.
|
||||
*/
|
||||
resetDimensionsCache: function() {
|
||||
this._videoDimensionsCache = {
|
||||
local: {},
|
||||
remote: {}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Whenever the dimensions change of a video stream, this function is called
|
||||
* by `updateVideoDimensions` to store the new values and notifies the callee
|
||||
|
@ -383,6 +383,12 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
this.updateVideoContainer();
|
||||
}
|
||||
|
||||
if (nextState.roomState === ROOM_STATES.INIT ||
|
||||
nextState.roomState === ROOM_STATES.GATHER ||
|
||||
nextState.roomState === ROOM_STATES.READY) {
|
||||
this.resetDimensionsCache();
|
||||
}
|
||||
|
||||
// When screen sharing stops.
|
||||
if (this.state.receivingScreenShare && !nextState.receivingScreenShare) {
|
||||
// Remove the custom screenshare styles on the remote camera.
|
||||
|
@ -383,6 +383,12 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
this.updateVideoContainer();
|
||||
}
|
||||
|
||||
if (nextState.roomState === ROOM_STATES.INIT ||
|
||||
nextState.roomState === ROOM_STATES.GATHER ||
|
||||
nextState.roomState === ROOM_STATES.READY) {
|
||||
this.resetDimensionsCache();
|
||||
}
|
||||
|
||||
// When screen sharing stops.
|
||||
if (this.state.receivingScreenShare && !nextState.receivingScreenShare) {
|
||||
// Remove the custom screenshare styles on the remote camera.
|
||||
|
@ -7,7 +7,7 @@ support-files =
|
||||
google_service.sjs
|
||||
head.js
|
||||
loop_fxa.sjs
|
||||
../../../../base/content/test/general/browser_fxa_oauth.html
|
||||
../../../../base/content/test/general/browser_fxa_oauth_with_keys.html
|
||||
|
||||
[browser_CardDavImporter.js]
|
||||
[browser_fxa_login.js]
|
||||
|
@ -134,7 +134,7 @@ function params(request, response) {
|
||||
*/
|
||||
function oauth_authorization(request, response) {
|
||||
response.setStatusLine(request.httpVersion, 302, "Found");
|
||||
response.setHeader("Location", "browser_fxa_oauth.html");
|
||||
response.setHeader("Location", "browser_fxa_oauth_with_keys.html");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -214,6 +214,19 @@ describe("loop.standaloneRoomViews", function() {
|
||||
|
||||
sinon.assert.calledOnce(view.updateVideoContainer);
|
||||
});
|
||||
|
||||
it("should reset the video dimensions cache when the gather state is entered", function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.SESSION_CONNECTED});
|
||||
|
||||
var view = mountTestComponent();
|
||||
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.GATHER});
|
||||
|
||||
expect(view._videoDimensionsCache).eql({
|
||||
local: {},
|
||||
remote: {}
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
describe("#publishStream", function() {
|
||||
|
@ -3,6 +3,7 @@
|
||||
/* global Services, Assert */
|
||||
|
||||
const kGuestKeyPref = "loop.key";
|
||||
const kFxAKeyPref = "loop.key.fxa";
|
||||
|
||||
do_register_cleanup(function() {
|
||||
Services.prefs.clearUserPref(kGuestKeyPref);
|
||||
@ -33,12 +34,25 @@ add_task(function* test_guestGetKey() {
|
||||
Assert.equal(key, kFakeKey, "should return existing key");
|
||||
});
|
||||
|
||||
add_task(function* test_fxaGetKey() {
|
||||
// Set the userProfile to look like we're logged into FxA.
|
||||
add_task(function* test_fxaGetKnownKey() {
|
||||
const kFakeKey = "75312468";
|
||||
// Set the userProfile to look like we're logged into FxA with a key stored.
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = { token_type: "bearer" };
|
||||
MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" };
|
||||
Services.prefs.setCharPref(kFxAKeyPref, kFakeKey);
|
||||
|
||||
let key = yield MozLoopService.promiseProfileEncryptionKey();
|
||||
|
||||
Assert.equal(key, kFakeKey, "should return existing key");
|
||||
});
|
||||
|
||||
add_task(function* test_fxaGetKey() {
|
||||
// Set the userProfile to look like we're logged into FxA without a key stored.
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = { token_type: "bearer" };
|
||||
MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" };
|
||||
Services.prefs.clearUserPref(kFxAKeyPref);
|
||||
|
||||
// Currently unimplemented, add a test when we implement the code.
|
||||
yield Assert.rejects(MozLoopService.promiseProfileEncryptionKey(),
|
||||
/unimplemented/, "should reject as unimplemented");
|
||||
/not implemented/, "should reject as unimplemented");
|
||||
});
|
||||
|
@ -118,6 +118,10 @@
|
||||
#include "mozilla/EMEUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <cutils/properties.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -1453,6 +1457,17 @@ Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
|
||||
} // hardware.memory
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (aName.EqualsLiteral("acl.version")) {
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
uint32_t len = property_get("persist.acl.version", value, nullptr);
|
||||
if (len > 0) {
|
||||
p->MaybeResolve(NS_ConvertUTF8toUTF16(value));
|
||||
return p.forget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
p->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return p.forget();
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ UNIFIED_SOURCES += [
|
||||
'src/base/pickle.cc',
|
||||
'src/base/rand_util.cc',
|
||||
'src/base/revocable_store.cc',
|
||||
'src/base/scoped_temp_dir.cc',
|
||||
'src/base/string_piece.cc',
|
||||
'src/base/string_util.cc',
|
||||
'src/base/thread.cc',
|
||||
|
@ -139,12 +139,6 @@ void AppendToPath(std::wstring* path, const std::wstring& new_ending) {
|
||||
path->push_back(FilePath::kSeparators[0]);
|
||||
path->append(new_ending);
|
||||
}
|
||||
bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
|
||||
bool recursive) {
|
||||
return CopyDirectory(FilePath::FromWStringHack(from_path),
|
||||
FilePath::FromWStringHack(to_path),
|
||||
recursive);
|
||||
}
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
return CopyFile(FilePath::FromWStringHack(from_path),
|
||||
FilePath::FromWStringHack(to_path));
|
||||
@ -172,8 +166,8 @@ bool CreateTemporaryFileName(std::wstring* temp_file) {
|
||||
*temp_file = temp_file_path.ToWStringHack();
|
||||
return true;
|
||||
}
|
||||
bool Delete(const std::wstring& path, bool recursive) {
|
||||
return Delete(FilePath::FromWStringHack(path), recursive);
|
||||
bool Delete(const std::wstring& path) {
|
||||
return Delete(FilePath::FromWStringHack(path));
|
||||
}
|
||||
bool DirectoryExists(const std::wstring& path) {
|
||||
return DirectoryExists(FilePath::FromWStringHack(path));
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <sys/stat.h>
|
||||
#elif defined(OS_POSIX)
|
||||
#include <sys/types.h>
|
||||
#include <fts.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
@ -87,34 +86,17 @@ void ReplaceExtension(std::wstring* file_name, const std::wstring& extension);
|
||||
|
||||
// Deletes the given path, whether it's a file or a directory.
|
||||
// If it's a directory, it's perfectly happy to delete all of the
|
||||
// directory's contents. Passing true to recursive deletes
|
||||
// subdirectories and their contents as well.
|
||||
// directory's contents.
|
||||
// Returns true if successful, false otherwise.
|
||||
//
|
||||
// WARNING: USING THIS WITH recursive==true IS EQUIVALENT
|
||||
// TO "rm -rf", SO USE WITH CAUTION.
|
||||
bool Delete(const FilePath& path, bool recursive);
|
||||
bool Delete(const FilePath& path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool Delete(const std::wstring& path, bool recursive);
|
||||
bool Delete(const std::wstring& path);
|
||||
|
||||
// Copies a single file. Use CopyDirectory to copy directories.
|
||||
bool CopyFile(const FilePath& from_path, const FilePath& to_path);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool CopyFile(const std::wstring& from_path, const std::wstring& to_path);
|
||||
|
||||
// Copies the given path, and optionally all subdirectories and their contents
|
||||
// as well.
|
||||
// If there are files existing under to_path, always overwrite.
|
||||
// Returns true if successful, false otherwise.
|
||||
// Dont't use wildcards on the names, it may stop working without notice.
|
||||
//
|
||||
// If you only need to copy a file use CopyFile, it's faster.
|
||||
bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
|
||||
bool recursive);
|
||||
// Deprecated temporary compatibility function.
|
||||
bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
|
||||
bool recursive);
|
||||
|
||||
// Returns true if the given path exists on the local filesystem,
|
||||
// false otherwise.
|
||||
bool PathExists(const FilePath& path);
|
||||
|
@ -8,13 +8,10 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#ifndef ANDROID
|
||||
#include <fts.h>
|
||||
#endif
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#define _DARWIN_USE_64_BIT_INODE // Use 64-bit inode data structures
|
||||
#include <sys/stat.h>
|
||||
@ -53,7 +50,7 @@ bool AbsolutePath(FilePath* path) {
|
||||
// which works both with and without the recursive flag. I'm not sure we need
|
||||
// that functionality. If not, remove from file_util_win.cc, otherwise add it
|
||||
// here.
|
||||
bool Delete(const FilePath& path, bool recursive) {
|
||||
bool Delete(const FilePath& path) {
|
||||
const char* path_str = path.value().c_str();
|
||||
struct stat file_info;
|
||||
int test = stat(path_str, &file_info);
|
||||
@ -64,174 +61,8 @@ bool Delete(const FilePath& path, bool recursive) {
|
||||
}
|
||||
if (!S_ISDIR(file_info.st_mode))
|
||||
return (unlink(path_str) == 0);
|
||||
if (!recursive)
|
||||
return (rmdir(path_str) == 0);
|
||||
|
||||
#ifdef ANDROID
|
||||
// XXX Need ftsless impl for bionic
|
||||
return false;
|
||||
#else
|
||||
bool success = true;
|
||||
int ftsflags = FTS_PHYSICAL | FTS_NOSTAT;
|
||||
char top_dir[PATH_MAX];
|
||||
if (base::strlcpy(top_dir, path_str,
|
||||
arraysize(top_dir)) >= arraysize(top_dir)) {
|
||||
return false;
|
||||
}
|
||||
char* dir_list[2] = { top_dir, NULL };
|
||||
FTS* fts = fts_open(dir_list, ftsflags, NULL);
|
||||
if (fts) {
|
||||
FTSENT* fts_ent = fts_read(fts);
|
||||
while (success && fts_ent != NULL) {
|
||||
switch (fts_ent->fts_info) {
|
||||
case FTS_DNR:
|
||||
case FTS_ERR:
|
||||
// log error
|
||||
success = false;
|
||||
continue;
|
||||
break;
|
||||
case FTS_DP:
|
||||
success = (rmdir(fts_ent->fts_accpath) == 0);
|
||||
break;
|
||||
case FTS_D:
|
||||
break;
|
||||
case FTS_NSOK:
|
||||
case FTS_F:
|
||||
case FTS_SL:
|
||||
case FTS_SLNONE:
|
||||
success = (unlink(fts_ent->fts_accpath) == 0);
|
||||
break;
|
||||
default:
|
||||
DCHECK(false);
|
||||
break;
|
||||
}
|
||||
fts_ent = fts_read(fts);
|
||||
}
|
||||
fts_close(fts);
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Move(const FilePath& from_path, const FilePath& to_path) {
|
||||
if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
|
||||
return true;
|
||||
|
||||
if (!CopyDirectory(from_path, to_path, true))
|
||||
return false;
|
||||
|
||||
Delete(from_path, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CopyDirectory(const FilePath& from_path,
|
||||
const FilePath& to_path,
|
||||
bool recursive) {
|
||||
// Some old callers of CopyDirectory want it to support wildcards.
|
||||
// After some discussion, we decided to fix those callers.
|
||||
// Break loudly here if anyone tries to do this.
|
||||
// TODO(evanm): remove this once we're sure it's ok.
|
||||
DCHECK(to_path.value().find('*') == std::string::npos);
|
||||
DCHECK(from_path.value().find('*') == std::string::npos);
|
||||
|
||||
char top_dir[PATH_MAX];
|
||||
if (base::strlcpy(top_dir, from_path.value().c_str(),
|
||||
arraysize(top_dir)) >= arraysize(top_dir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
// XXX Need ftsless impl for bionic
|
||||
return false;
|
||||
#else
|
||||
char* dir_list[] = { top_dir, NULL };
|
||||
FTS* fts = fts_open(dir_list, FTS_PHYSICAL | FTS_NOSTAT, NULL);
|
||||
if (!fts) {
|
||||
CHROMIUM_LOG(ERROR) << "fts_open failed: " << strerror(errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
FTSENT* ent;
|
||||
while (!error && (ent = fts_read(fts)) != NULL) {
|
||||
// ent->fts_path is the source path, including from_path, so paste
|
||||
// the suffix after from_path onto to_path to create the target_path.
|
||||
std::string suffix(&ent->fts_path[from_path.value().size()]);
|
||||
// Strip the leading '/' (if any).
|
||||
if (!suffix.empty()) {
|
||||
DCHECK_EQ('/', suffix[0]);
|
||||
suffix.erase(0, 1);
|
||||
}
|
||||
const FilePath target_path = to_path.Append(suffix);
|
||||
switch (ent->fts_info) {
|
||||
case FTS_D: // Preorder directory.
|
||||
// If we encounter a subdirectory in a non-recursive copy, prune it
|
||||
// from the traversal.
|
||||
if (!recursive && ent->fts_level > 0) {
|
||||
if (fts_set(fts, ent, FTS_SKIP) != 0)
|
||||
error = errno;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try creating the target dir, continuing on it if it exists already.
|
||||
// Rely on the user's umask to produce correct permissions.
|
||||
if (mkdir(target_path.value().c_str(), 0777) != 0) {
|
||||
if (errno != EEXIST)
|
||||
error = errno;
|
||||
}
|
||||
break;
|
||||
case FTS_F: // Regular file.
|
||||
case FTS_NSOK: // File, no stat info requested.
|
||||
errno = 0;
|
||||
if (!CopyFile(FilePath(ent->fts_path), target_path))
|
||||
error = errno ? errno : EINVAL;
|
||||
break;
|
||||
case FTS_DP: // Postorder directory.
|
||||
case FTS_DOT: // "." or ".."
|
||||
// Skip it.
|
||||
continue;
|
||||
case FTS_DC: // Directory causing a cycle.
|
||||
// Skip this branch.
|
||||
if (fts_set(fts, ent, FTS_SKIP) != 0)
|
||||
error = errno;
|
||||
break;
|
||||
case FTS_DNR: // Directory cannot be read.
|
||||
case FTS_ERR: // Error.
|
||||
case FTS_NS: // Stat failed.
|
||||
// Abort with the error.
|
||||
error = ent->fts_errno;
|
||||
break;
|
||||
case FTS_SL: // Symlink.
|
||||
case FTS_SLNONE: // Symlink with broken target.
|
||||
CHROMIUM_LOG(WARNING) << "CopyDirectory() skipping symbolic link: " <<
|
||||
ent->fts_path;
|
||||
continue;
|
||||
case FTS_DEFAULT: // Some other sort of file.
|
||||
CHROMIUM_LOG(WARNING) << "CopyDirectory() skipping file of unknown type: " <<
|
||||
ent->fts_path;
|
||||
continue;
|
||||
default:
|
||||
NOTREACHED();
|
||||
continue; // Hope for the best!
|
||||
}
|
||||
}
|
||||
// fts_read may have returned NULL and set errno to indicate an error.
|
||||
if (!error && errno != 0)
|
||||
error = errno;
|
||||
|
||||
if (!fts_close(fts)) {
|
||||
// If we already have an error, let's use that error instead of the error
|
||||
// fts_close set.
|
||||
if (!error)
|
||||
error = errno;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
CHROMIUM_LOG(ERROR) << "CopyDirectory(): " << strerror(error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
return (rmdir(path_str) == 0);
|
||||
}
|
||||
|
||||
bool PathExists(const FilePath& path) {
|
||||
|
@ -27,14 +27,14 @@ bool AbsolutePath(FilePath* path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Delete(const FilePath& path, bool recursive) {
|
||||
bool Delete(const FilePath& path) {
|
||||
if (path.value().length() >= MAX_PATH)
|
||||
return false;
|
||||
|
||||
// If we're not recursing use DeleteFile; it should be faster. DeleteFile
|
||||
// Use DeleteFile; it should be faster. DeleteFile
|
||||
// fails if passed a directory though, which is why we fall through on
|
||||
// failure to the SHFileOperation.
|
||||
if (!recursive && DeleteFile(path.value().c_str()) != 0)
|
||||
if (DeleteFile(path.value().c_str()) != 0)
|
||||
return true;
|
||||
|
||||
// SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
|
||||
@ -48,8 +48,7 @@ bool Delete(const FilePath& path, bool recursive) {
|
||||
file_operation.wFunc = FO_DELETE;
|
||||
file_operation.pFrom = double_terminated_path;
|
||||
file_operation.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION;
|
||||
if (!recursive)
|
||||
file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY;
|
||||
file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY;
|
||||
int err = SHFileOperation(&file_operation);
|
||||
// Some versions of Windows return ERROR_FILE_NOT_FOUND when
|
||||
// deleting an empty directory.
|
||||
@ -98,26 +97,6 @@ bool ShellCopy(const FilePath& from_path, const FilePath& to_path,
|
||||
return (SHFileOperation(&file_operation) == 0);
|
||||
}
|
||||
|
||||
bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
|
||||
bool recursive) {
|
||||
if (recursive)
|
||||
return ShellCopy(from_path, to_path, true);
|
||||
|
||||
// Instead of creating a new directory, we copy the old one to include the
|
||||
// security information of the folder as part of the copy.
|
||||
if (!PathExists(to_path)) {
|
||||
// Except that Vista fails to do that, and instead do a recursive copy if
|
||||
// the target directory doesn't exist.
|
||||
if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA)
|
||||
CreateDirectory(to_path);
|
||||
else
|
||||
ShellCopy(from_path, to_path, false);
|
||||
}
|
||||
|
||||
FilePath directory = from_path.Append(L"*.*");
|
||||
return ShellCopy(directory, to_path, false);
|
||||
}
|
||||
|
||||
bool PathExists(const FilePath& path) {
|
||||
return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES);
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/scoped_temp_dir.h"
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
ScopedTempDir::ScopedTempDir() {
|
||||
}
|
||||
|
||||
ScopedTempDir::~ScopedTempDir() {
|
||||
if (!path_.empty() && !file_util::Delete(path_, true))
|
||||
CHROMIUM_LOG(ERROR) << "ScopedTempDir unable to delete " << path_.value();
|
||||
}
|
||||
|
||||
bool ScopedTempDir::CreateUniqueTempDir() {
|
||||
// This "scoped_dir" prefix is only used on Windows and serves as a template
|
||||
// for the unique name.
|
||||
if (!file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("scoped_dir"),
|
||||
&path_))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScopedTempDir::Set(const FilePath& path) {
|
||||
DCHECK(path_.empty());
|
||||
if (!file_util::DirectoryExists(path) &&
|
||||
!file_util::CreateDirectory(path)) {
|
||||
return false;
|
||||
}
|
||||
path_ = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
FilePath ScopedTempDir::Take() {
|
||||
FilePath ret = path_;
|
||||
path_ = FilePath();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ScopedTempDir::IsValid() const {
|
||||
return !path_.empty() && file_util::DirectoryExists(path_);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_SCOPED_TEMP_DIR_H_
|
||||
#define BASE_SCOPED_TEMP_DIR_H_
|
||||
|
||||
// An object representing a temporary / scratch directory that should be cleaned
|
||||
// up (recursively) when this object goes out of scope. Note that since
|
||||
// deletion occurs during the destructor, no further error handling is possible
|
||||
// if the directory fails to be deleted. As a result, deletion is not
|
||||
// guaranteed by this class.
|
||||
|
||||
#include "base/file_path.h"
|
||||
|
||||
class ScopedTempDir {
|
||||
public:
|
||||
// No directory is owned/created initially.
|
||||
ScopedTempDir();
|
||||
|
||||
// Recursively delete path_
|
||||
~ScopedTempDir();
|
||||
|
||||
// Creates a unique directory in TempPath, and takes ownership of it.
|
||||
// See file_util::CreateNewTemporaryDirectory.
|
||||
bool CreateUniqueTempDir();
|
||||
|
||||
// Takes ownership of directory at |path|, creating it if necessary.
|
||||
// Don't call multiple times unless Take() has been called first.
|
||||
bool Set(const FilePath& path);
|
||||
|
||||
// Caller takes ownership of the temporary directory so it won't be destroyed
|
||||
// when this object goes out of scope.
|
||||
FilePath Take();
|
||||
|
||||
const FilePath& path() const { return path_; }
|
||||
|
||||
// Returns true if path_ is non-empty and exists.
|
||||
bool IsValid() const;
|
||||
|
||||
private:
|
||||
FilePath path_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedTempDir);
|
||||
};
|
||||
|
||||
#endif // BASE_SCOPED_TEMP_DIR_H_
|
@ -93,7 +93,7 @@ bool SharedMemory::Delete(const std::wstring& name) {
|
||||
|
||||
FilePath path(WideToUTF8(mem_filename));
|
||||
if (file_util::PathExists(path)) {
|
||||
return file_util::Delete(path, false);
|
||||
return file_util::Delete(path);
|
||||
}
|
||||
|
||||
// Doesn't exist, so success.
|
||||
@ -170,7 +170,7 @@ bool SharedMemory::CreateOrOpen(const std::wstring &name,
|
||||
// Deleting the file prevents anyone else from mapping it in
|
||||
// (making it private), and prevents the need for cleanup (once
|
||||
// the last fd is closed, it is truly freed).
|
||||
file_util::Delete(path, false);
|
||||
file_util::Delete(path);
|
||||
} else {
|
||||
std::wstring mem_filename;
|
||||
if (FilenameForMemoryName(name, &mem_filename) == false)
|
||||
|
@ -198,20 +198,15 @@
|
||||
<!ENTITY tab_queue_prompt_tip_text "you can change this later in Settings">
|
||||
<!ENTITY tab_queue_prompt_positive_action_button "Enable">
|
||||
<!ENTITY tab_queue_prompt_negative_action_button "Not now">
|
||||
<!-- Localization note (tab_queue_notification_text_plural) : The
|
||||
<!ENTITY tab_queue_notification_title "&brandShortName;">
|
||||
<!-- Localization note (tab_queue_notification_text_plural2) : The
|
||||
formatD is replaced with the number of tabs queued. The
|
||||
number of tabs queued is always more than one. We can't use
|
||||
Android plural forms, sadly. See Bug #753859. -->
|
||||
<!ENTITY tab_queue_notification_text_plural "&formatD; tabs queued">
|
||||
<!-- Localization note (tab_queue_notification_title_plural) : This is the
|
||||
title of a notification; we expect more than one tab queued. -->
|
||||
<!ENTITY tab_queue_notification_title_plural "Tabs Queued">
|
||||
<!-- Localization note (tab_queue_notification_title_singular) : This is the
|
||||
title of a notification; we expect only one tab queued. -->
|
||||
<!ENTITY tab_queue_notification_title_singular "Tab Queued">
|
||||
<!-- Localization note (tab_queue_notification_text_singular) : This is the
|
||||
<!ENTITY tab_queue_notification_text_plural2 "&formatD; tabs waiting">
|
||||
<!-- Localization note (tab_queue_notification_text_singular2) : This is the
|
||||
text of a notification; we expect only one tab queued. -->
|
||||
<!ENTITY tab_queue_notification_text_singular "1 tab queued">
|
||||
<!ENTITY tab_queue_notification_text_singular2 "1 tab waiting">
|
||||
|
||||
<!ENTITY pref_char_encoding "Character encoding">
|
||||
<!ENTITY pref_char_encoding_on "Show menu">
|
||||
|
@ -137,6 +137,8 @@ OnSharedPreferenceChangeListener
|
||||
public static final String PREFS_SUGGESTED_SITES = NON_PREF_PREFIX + "home_suggested_sites";
|
||||
public static final String PREFS_TAB_QUEUE = NON_PREF_PREFIX + "tab_queue";
|
||||
public static final String PREFS_CUSTOMIZE_SCREEN = NON_PREF_PREFIX + "customize_screen";
|
||||
public static final String PREFS_TAB_QUEUE_LAST_SITE = NON_PREF_PREFIX + "last_site";
|
||||
public static final String PREFS_TAB_QUEUE_LAST_TIME = NON_PREF_PREFIX + "last_time";
|
||||
|
||||
// These values are chosen to be distinct from other Activity constants.
|
||||
private static final int REQUEST_CODE_PREF_SCREEN = 5;
|
||||
|
35
mobile/android/base/resources/layout/tab_queue_toast.xml
Normal file
35
mobile/android/base/resources/layout/tab_queue_toast.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/toast"
|
||||
style="@style/Toast">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/toast_message"
|
||||
style="@style/ToastMessage"
|
||||
|
||||
tools:text="Tab queued in firefox" />
|
||||
|
||||
<View
|
||||
android:id="@+id/toast_divider"
|
||||
style="@style/ToastDivider" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/toast_button"
|
||||
style="@style/ToastButton"
|
||||
android:drawableLeft="@drawable/switch_button_icon"
|
||||
|
||||
tools:text="Open" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
12
mobile/android/base/resources/values-w400dp/styles.xml
Normal file
12
mobile/android/base/resources/values-w400dp/styles.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Toast" parent="ToastBase">
|
||||
<item name="android:layout_width">400dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -247,10 +247,9 @@
|
||||
<string name="tab_queue_prompt_negative_action_button">&tab_queue_prompt_negative_action_button;</string>
|
||||
<string name="tab_queue_toast_message">&tab_queue_toast_message2;</string>
|
||||
<string name="tab_queue_toast_action">&tab_queue_toast_action;</string>
|
||||
<string name="tab_queue_notification_text_singular">&tab_queue_notification_text_singular;</string>
|
||||
<string name="tab_queue_notification_text_plural">&tab_queue_notification_text_plural;</string>
|
||||
<string name="tab_queue_notification_title_singular">&tab_queue_notification_title_singular;</string>
|
||||
<string name="tab_queue_notification_title_plural">&tab_queue_notification_title_plural;</string>
|
||||
<string name="tab_queue_notification_text_singular">&tab_queue_notification_text_singular2;</string>
|
||||
<string name="tab_queue_notification_text_plural">&tab_queue_notification_text_plural2;</string>
|
||||
<string name="tab_queue_notification_title">&tab_queue_notification_title;</string>
|
||||
|
||||
<string name="pref_about_firefox">&pref_about_firefox;</string>
|
||||
<string name="pref_vendor_faqs">&pref_vendor_faqs;</string>
|
||||
|
@ -21,6 +21,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@ -104,6 +105,45 @@ public class TabQueueHelper {
|
||||
return jsonArray.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a url from the file, if it exists.
|
||||
* If the url exists multiple times, all instances of it will be removed.
|
||||
* This should not be run on the UI thread.
|
||||
*
|
||||
* @param context
|
||||
* @param urlToRemove URL to remove
|
||||
* @param filename filename to remove URL from
|
||||
* @return the number of queued urls
|
||||
*/
|
||||
public static int removeURLFromFile(final Context context, final String urlToRemove, final String filename) {
|
||||
ThreadUtils.assertNotOnUiThread();
|
||||
|
||||
final GeckoProfile profile = GeckoProfile.get(context);
|
||||
|
||||
JSONArray jsonArray = profile.readJSONArrayFromFile(filename);
|
||||
JSONArray newArray = new JSONArray();
|
||||
String url;
|
||||
|
||||
// Since JSONArray.remove was only added in API 19, we have to use two arrays in order to remove.
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
try {
|
||||
url = jsonArray.getString(i);
|
||||
} catch (JSONException e) {
|
||||
url = "";
|
||||
}
|
||||
if(!TextUtils.isEmpty(url) && !urlToRemove.equals(url)) {
|
||||
newArray.put(url);
|
||||
}
|
||||
}
|
||||
|
||||
profile.writeFile(filename, newArray.toString());
|
||||
|
||||
final SharedPreferences prefs = GeckoSharedPrefs.forApp(context);
|
||||
prefs.edit().putInt(PREF_TAB_QUEUE_COUNT, newArray.length()).apply();
|
||||
|
||||
return newArray.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a notification showing the total number of tabs queue. If there is already a notification displayed, it
|
||||
* will be replaced.
|
||||
@ -119,19 +159,17 @@ public class TabQueueHelper {
|
||||
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
String title, text;
|
||||
final String text;
|
||||
final Resources resources = context.getResources();
|
||||
if (tabsQueued == 1) {
|
||||
title = resources.getString(R.string.tab_queue_notification_title_singular);
|
||||
text = resources.getString(R.string.tab_queue_notification_text_singular);
|
||||
} else {
|
||||
title = resources.getString(R.string.tab_queue_notification_title_plural);
|
||||
text = resources.getString(R.string.tab_queue_notification_text_plural, tabsQueued);
|
||||
}
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.ic_status_logo)
|
||||
.setContentTitle(title)
|
||||
.setContentTitle(resources.getString(R.string.tab_queue_notification_title))
|
||||
.setContentText(text)
|
||||
.setContentIntent(pendingIntent);
|
||||
|
||||
|
@ -5,6 +5,13 @@
|
||||
|
||||
package org.mozilla.gecko.tabqueue;
|
||||
|
||||
import org.mozilla.gecko.BrowserApp;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -14,6 +21,7 @@ import android.graphics.PixelFormat;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@ -21,12 +29,6 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import org.mozilla.gecko.BrowserApp;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -56,6 +58,7 @@ public class TabQueueService extends Service {
|
||||
private static final String LOGTAG = "Gecko" + TabQueueService.class.getSimpleName();
|
||||
|
||||
private static final long TOAST_TIMEOUT = 3000;
|
||||
private static final long TOAST_DOUBLE_TAP_TIMEOUT_MILLIS = 6000;
|
||||
|
||||
private WindowManager windowManager;
|
||||
private View toastLayout;
|
||||
@ -84,7 +87,7 @@ public class TabQueueService extends Service {
|
||||
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
|
||||
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||
toastLayout = layoutInflater.inflate(R.layout.button_toast, null);
|
||||
toastLayout = layoutInflater.inflate(R.layout.tab_queue_toast, null);
|
||||
|
||||
final Resources resources = getResources();
|
||||
|
||||
@ -95,7 +98,7 @@ public class TabQueueService extends Service {
|
||||
openNowButton.setText(resources.getText(R.string.tab_queue_toast_action));
|
||||
|
||||
toastLayoutParams = new WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.MATCH_PARENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.TYPE_PHONE,
|
||||
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
|
||||
@ -108,6 +111,50 @@ public class TabQueueService extends Service {
|
||||
|
||||
@Override
|
||||
public int onStartCommand(final Intent intent, final int flags, final int startId) {
|
||||
// If this is a redelivery then lets bypass the entire double tap to open now code as that's a big can of worms,
|
||||
// we also don't expect redeliveries because of the short time window associated with this feature.
|
||||
if (flags != START_FLAG_REDELIVERY) {
|
||||
final Context applicationContext = getApplicationContext();
|
||||
final SharedPreferences sharedPreferences = GeckoSharedPrefs.forApp(applicationContext);
|
||||
|
||||
final String lastUrl = sharedPreferences.getString(GeckoPreferences.PREFS_TAB_QUEUE_LAST_SITE, "");
|
||||
|
||||
final ContextUtils.SafeIntent safeIntent = new ContextUtils.SafeIntent(intent);
|
||||
final String intentUrl = safeIntent.getDataString();
|
||||
|
||||
final long lastRunTime = sharedPreferences.getLong(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME, 0);
|
||||
final boolean isWithinDoubleTapTimeLimit = System.currentTimeMillis() - lastRunTime < TOAST_DOUBLE_TAP_TIMEOUT_MILLIS;
|
||||
|
||||
if (!TextUtils.isEmpty(lastUrl) && lastUrl.equals(intentUrl) && isWithinDoubleTapTimeLimit) {
|
||||
// Background thread because we could do some file IO if we have to remove a url from the list.
|
||||
tabQueueHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// If there is a runnable around, that means that the previous process hasn't yet completed, so
|
||||
// we will need to prevent it from running and remove the view from the window manager.
|
||||
// If there is no runnable around then the url has already been added to the list, so we'll
|
||||
// need to remove it before proceeding or that url will open multiple times.
|
||||
if (stopServiceRunnable != null) {
|
||||
tabQueueHandler.removeCallbacks(stopServiceRunnable);
|
||||
stopSelfResult(stopServiceRunnable.getStartId());
|
||||
stopServiceRunnable = null;
|
||||
removeView();
|
||||
} else {
|
||||
TabQueueHelper.removeURLFromFile(applicationContext, intentUrl, TabQueueHelper.FILE_NAME);
|
||||
}
|
||||
openNow(safeIntent.getUnsafe());
|
||||
stopSelfResult(startId);
|
||||
}
|
||||
});
|
||||
|
||||
return START_REDELIVER_INTENT;
|
||||
}
|
||||
|
||||
sharedPreferences.edit().putString(GeckoPreferences.PREFS_TAB_QUEUE_LAST_SITE, intentUrl)
|
||||
.putLong(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME, System.currentTimeMillis())
|
||||
.apply();
|
||||
}
|
||||
|
||||
if (stopServiceRunnable != null) {
|
||||
// If we're already displaying a toast, keep displaying it but store the previous url.
|
||||
// The open button will refer to the most recently opened link.
|
||||
@ -130,14 +177,8 @@ public class TabQueueService extends Service {
|
||||
public void onClick(final View view) {
|
||||
tabQueueHandler.removeCallbacks(stopServiceRunnable);
|
||||
stopServiceRunnable = null;
|
||||
|
||||
|
||||
Intent forwardIntent = new Intent(intent);
|
||||
forwardIntent.setClass(getApplicationContext(), BrowserApp.class);
|
||||
forwardIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(forwardIntent);
|
||||
|
||||
removeView();
|
||||
openNow(intent);
|
||||
stopSelfResult(startId);
|
||||
}
|
||||
});
|
||||
@ -147,6 +188,17 @@ public class TabQueueService extends Service {
|
||||
return START_REDELIVER_INTENT;
|
||||
}
|
||||
|
||||
private void openNow(Intent intent) {
|
||||
Intent forwardIntent = new Intent(intent);
|
||||
forwardIntent.setClass(getApplicationContext(), BrowserApp.class);
|
||||
forwardIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(forwardIntent);
|
||||
|
||||
GeckoSharedPrefs.forApp(getApplicationContext()).edit().remove(GeckoPreferences.PREFS_TAB_QUEUE_LAST_SITE)
|
||||
.remove(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME)
|
||||
.apply();
|
||||
}
|
||||
|
||||
private void removeView() {
|
||||
windowManager.removeView(toastLayout);
|
||||
}
|
||||
@ -198,18 +250,22 @@ public class TabQueueService extends Service {
|
||||
this.startId = startId;
|
||||
}
|
||||
|
||||
public void run(final boolean shouldStopService) {
|
||||
public void run() {
|
||||
run(true);
|
||||
}
|
||||
|
||||
public void run(final boolean shouldRemoveView) {
|
||||
onRun();
|
||||
|
||||
if (shouldStopService) {
|
||||
if (shouldRemoveView) {
|
||||
removeView();
|
||||
}
|
||||
|
||||
stopSelfResult(startId);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
run(true);
|
||||
public int getStartId() {
|
||||
return startId;
|
||||
}
|
||||
|
||||
public abstract void onRun();
|
||||
|
@ -3446,50 +3446,59 @@
|
||||
"description": "PLACES: Days from last maintenance"
|
||||
},
|
||||
"UPDATE_CHECK_NO_UPDATE_EXTERNAL" : {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of no updates were found for a background update check (externally initiated)"
|
||||
},
|
||||
"UPDATE_CHECK_NO_UPDATE_NOTIFY" : {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of no updates were found for a background update check (timer initiated)"
|
||||
},
|
||||
"UPDATE_CHECK_CODE_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 50,
|
||||
"description": "Update: background update check result code except for no updates found (externally initiated)"
|
||||
},
|
||||
"UPDATE_CHECK_CODE_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 50,
|
||||
"description": "Update: background update check result code except for no updates found (timer initiated)"
|
||||
},
|
||||
"UPDATE_CHECK_EXTENDED_ERROR_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"keyed": true,
|
||||
"description": "Update: keyed count (key names are prefixed with AUS_CHECK_EX_ERR_) of background update check extended error code (externally initiated)"
|
||||
},
|
||||
"UPDATE_CHECK_EXTENDED_ERROR_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"keyed": true,
|
||||
"description": "Update: keyed count (key names are prefixed with AUS_CHECK_EX_ERR_) of background update check extended error code (timer initiated)"
|
||||
},
|
||||
"UPDATE_INVALID_LASTUPDATETIME_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that have a last update time greater than the current time (externally initiated)"
|
||||
},
|
||||
"UPDATE_INVALID_LASTUPDATETIME_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that have a last update time greater than the current time (timer initiated)"
|
||||
},
|
||||
"UPDATE_LAST_NOTIFY_INTERVAL_DAYS_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"n_buckets": 60,
|
||||
@ -3497,6 +3506,7 @@
|
||||
"description": "Update: interval in days since the last background update check (externally initiated)"
|
||||
},
|
||||
"UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"n_buckets": 30,
|
||||
@ -3504,214 +3514,253 @@
|
||||
"description": "Update: interval in days since the last background update check (timer initiated)"
|
||||
},
|
||||
"UPDATE_PING_COUNT_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems for this ping for comparison with other pings (externally initiated)"
|
||||
},
|
||||
"UPDATE_PING_COUNT_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems for this ping for comparison with other pings (timer initiated)"
|
||||
},
|
||||
"UPDATE_SERVICE_INSTALLED_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "boolean",
|
||||
"description": "Update: whether the service is installed (externally initiated)"
|
||||
},
|
||||
"UPDATE_SERVICE_INSTALLED_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "boolean",
|
||||
"description": "Update: whether the service is installed (timer initiated)"
|
||||
},
|
||||
"UPDATE_SERVICE_MANUALLY_UNINSTALLED_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that manually uninstalled the service (externally initiated)"
|
||||
},
|
||||
"UPDATE_SERVICE_MANUALLY_UNINSTALLED_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that manually uninstalled the service (timer initiated)"
|
||||
},
|
||||
"UPDATE_UNABLE_TO_APPLY_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that cannot apply updates (externally initiated)"
|
||||
},
|
||||
"UPDATE_UNABLE_TO_APPLY_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that cannot apply updates (timer initiated)"
|
||||
},
|
||||
"UPDATE_CANNOT_STAGE_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that cannot stage updates (externally initiated)"
|
||||
},
|
||||
"UPDATE_CANNOT_STAGE_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that cannot stage updates (timer initiated)"
|
||||
},
|
||||
"UPDATE_HAS_PREF_URL_OVERRIDE_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that have an app.update.url.override preference (externally initiated)"
|
||||
},
|
||||
"UPDATE_HAS_PREF_URL_OVERRIDE_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of systems that have an app.update.url.override preference (timer initiated)"
|
||||
},
|
||||
"UPDATE_PREF_UPDATE_CANCELATIONS_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: number of sequential update elevation request cancelations greater than 0 (externally initiated)"
|
||||
},
|
||||
"UPDATE_PREF_UPDATE_CANCELATIONS_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: number of sequential update elevation request cancelations greater than 0 (timer initiated)"
|
||||
},
|
||||
"UPDATE_PREF_SERVICE_ERRORS_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 30,
|
||||
"description": "Update: number of sequential update service errors greater than 0 (externally initiated)"
|
||||
},
|
||||
"UPDATE_PREF_SERVICE_ERRORS_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 30,
|
||||
"description": "Update: number of sequential update service errors greater than 0 (timer initiated)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_AUTO_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.auto boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_AUTO_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.auto boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.staging.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.staging.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_EXTERNAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.service.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_NOTIFY": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Update: count of when the app.update.service.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_DOWNLOAD_CODE_COMPLETE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 50,
|
||||
"description": "Update: complete patch download result code"
|
||||
},
|
||||
"UPDATE_DOWNLOAD_CODE_PARTIAL": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 50,
|
||||
"description": "Update: complete patch download result code"
|
||||
},
|
||||
"UPDATE_STATE_CODE_COMPLETE_STARTUP": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 20,
|
||||
"description": "Update: the state of a complete update from update.status on startup"
|
||||
},
|
||||
"UPDATE_STATE_CODE_PARTIAL_STARTUP": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 20,
|
||||
"description": "Update: the state of a partial patch update from update.status on startup"
|
||||
},
|
||||
"UPDATE_STATE_CODE_UNKNOWN_STARTUP": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 20,
|
||||
"description": "Update: the state of an unknown patch update from update.status on startup"
|
||||
},
|
||||
"UPDATE_STATE_CODE_COMPLETE_STAGE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 20,
|
||||
"description": "Update: the state of a complete patch update from update.status after staging"
|
||||
},
|
||||
"UPDATE_STATE_CODE_PARTIAL_STAGE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 20,
|
||||
"description": "Update: the state of a partial patch update from update.status after staging"
|
||||
},
|
||||
"UPDATE_STATE_CODE_UNKNOWN_STAGE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 20,
|
||||
"description": "Update: the state of an unknown patch update from update.status after staging"
|
||||
},
|
||||
"UPDATE_STATUS_ERROR_CODE_COMPLETE_STARTUP": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: the status error code for a failed complete patch update from update.status on startup"
|
||||
},
|
||||
"UPDATE_STATUS_ERROR_CODE_PARTIAL_STARTUP": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: the status error code for a failed partial patch update from update.status on startup"
|
||||
},
|
||||
"UPDATE_STATUS_ERROR_CODE_UNKNOWN_STARTUP": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: the status error code for a failed unknown patch update from update.status on startup"
|
||||
},
|
||||
"UPDATE_STATUS_ERROR_CODE_COMPLETE_STAGE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: the status error code for a failed complete patch update from update.status after staging"
|
||||
},
|
||||
"UPDATE_STATUS_ERROR_CODE_PARTIAL_STAGE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: the status error code for a failed partial patch update from update.status after staging"
|
||||
},
|
||||
"UPDATE_STATUS_ERROR_CODE_UNKNOWN_STAGE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 100,
|
||||
"description": "Update: the status error code for a failed unknown patch update from update.status after staging"
|
||||
},
|
||||
"UPDATE_WIZ_LAST_PAGE_CODE": {
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 30,
|
||||
|
Loading…
Reference in New Issue
Block a user