mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Merge m-c to fx-team.
This commit is contained in:
commit
ebc2221702
@ -12,7 +12,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
|
||||
|
@ -12,7 +12,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "35ef07425e808811af0462a6ba08c36409236846",
|
||||
"revision": "7e08d1fefea803f39389bb009e146aaa692d126a",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -11,7 +11,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
@ -95,7 +95,7 @@
|
||||
<project name="device/qcom/common" path="device/qcom/common" revision="d13aaf080177b7c48f243d51827db5c7a7873cd0"/>
|
||||
<project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="f06bcacc6f13cec895dc5d4c2385c076396194ec"/>
|
||||
<project name="android-device-hamachi" path="device/qcom/hamachi" remote="b2g" revision="9071ac8f0830979fe4a96ce47c7443d8adf0929d"/>
|
||||
<project name="kernel/msm" path="kernel" revision="8072055e7094023e2cac8eea425bb785fe1d4066"/>
|
||||
<project name="kernel/msm" path="kernel" revision="a6578b9cacf9079f2dcf5bfe77c31b1be18809e3"/>
|
||||
<project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="19933e5d182a4799c6217b19a18562193a419298"/>
|
||||
<project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="5a58382180c70d0c446badc9c9837918ab69ec60"/>
|
||||
<project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="20d83ab382a1f813702421e76c2f9f994585990e"/>
|
||||
|
@ -10,7 +10,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -12,7 +12,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -11,7 +11,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
|
||||
|
@ -11,7 +11,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="0eadf61ef60f13324fe8290d8c2b516d98230fdc"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0f39c7179c8b297326c0e2313950610be1f5c52"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="15e8982284c4560f9c74c2b9fe8bb361ebfe0cb6"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -48,13 +48,17 @@ public:
|
||||
mFrameType(UNKNOWN)
|
||||
{}
|
||||
enum FrameType {
|
||||
I_FRAME, // intraframe
|
||||
P_FRAME, // predicted frame
|
||||
B_FRAME, // bidirectionally predicted frame
|
||||
AUDIO_FRAME, // audio frame
|
||||
AAC_CSD, // AAC codec specific data
|
||||
AVC_CSD, // AVC codec specific data
|
||||
UNKNOWN // FrameType not set
|
||||
VP8_I_FRAME, // VP8 intraframe
|
||||
VP8_P_FRAME, // VP8 predicted frame
|
||||
OPUS_AUDIO_FRAME, // Opus audio frame
|
||||
VORBIS_AUDIO_FRAME,
|
||||
AVC_I_FRAME,
|
||||
AVC_P_FRAME,
|
||||
AVC_B_FRAME,
|
||||
AVC_CSD, // AVC codec specific data
|
||||
AAC_AUDIO_FRAME,
|
||||
AAC_CSD, // AAC codec specific data
|
||||
UNKNOWN // FrameType not set
|
||||
};
|
||||
nsresult SwapInFrameData(nsTArray<uint8_t>& aData)
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ OmxVideoTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
||||
videoData->SetFrameType(EncodedFrame::AVC_CSD);
|
||||
} else {
|
||||
videoData->SetFrameType((outFlags & OMXCodecWrapper::BUFFER_SYNC_FRAME) ?
|
||||
EncodedFrame::I_FRAME : EncodedFrame::P_FRAME);
|
||||
EncodedFrame::AVC_I_FRAME : EncodedFrame::AVC_P_FRAME);
|
||||
}
|
||||
rv = videoData->SwapInFrameData(buffer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -217,7 +217,7 @@ OmxAudioTrackEncoder::AppendEncodedFrames(EncodedFrameContainer& aContainer)
|
||||
|
||||
nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
|
||||
audiodata->SetFrameType(isCSD ?
|
||||
EncodedFrame::AAC_CSD : EncodedFrame::AUDIO_FRAME);
|
||||
EncodedFrame::AAC_CSD : EncodedFrame::AAC_AUDIO_FRAME);
|
||||
audiodata->SetTimeStamp(outTimeUs);
|
||||
rv = audiodata->SwapInFrameData(frameData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -327,7 +327,7 @@ OpusTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
||||
}
|
||||
|
||||
nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
|
||||
audiodata->SetFrameType(EncodedFrame::AUDIO_FRAME);
|
||||
audiodata->SetFrameType(EncodedFrame::OPUS_AUDIO_FRAME);
|
||||
int framesInPCM = frameCopied;
|
||||
if (mResampler) {
|
||||
nsAutoTArray<AudioDataValue, 9600> resamplingDest;
|
||||
|
@ -162,7 +162,7 @@ nsresult
|
||||
VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData)
|
||||
{
|
||||
vpx_codec_iter_t iter = nullptr;
|
||||
EncodedFrame::FrameType frameType = EncodedFrame::P_FRAME;
|
||||
EncodedFrame::FrameType frameType = EncodedFrame::VP8_P_FRAME;
|
||||
nsTArray<uint8_t> frameData;
|
||||
nsresult rv;
|
||||
const vpx_codec_cx_pkt_t *pkt = nullptr;
|
||||
@ -181,7 +181,7 @@ VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData)
|
||||
// End of frame
|
||||
if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) {
|
||||
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
|
||||
frameType = EncodedFrame::I_FRAME;
|
||||
frameType = EncodedFrame::VP8_I_FRAME;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ VorbisTrackEncoder::GetEncodedFrames(EncodedFrameContainer& aData)
|
||||
if (vorbis_analysis(&mVorbisBlock, &oggPacket) == 0) {
|
||||
VORBISLOG("vorbis_analysis_blockout block size %d", oggPacket.bytes);
|
||||
EncodedFrame* audiodata = new EncodedFrame();
|
||||
audiodata->SetFrameType(EncodedFrame::AUDIO_FRAME);
|
||||
audiodata->SetFrameType(EncodedFrame::VORBIS_AUDIO_FRAME);
|
||||
nsTArray<uint8_t> frameData;
|
||||
frameData.AppendElements(oggPacket.packet, oggPacket.bytes);
|
||||
audiodata->SwapInFrameData(frameData);
|
||||
|
@ -141,7 +141,7 @@ TrackRunBox::fillSampleTable()
|
||||
if (flags.to_ulong() & flags_sample_flags_present) {
|
||||
sample_info_table[i].sample_flags =
|
||||
set_sample_flags(
|
||||
(frames.ElementAt(i)->GetFrameType() == EncodedFrame::I_FRAME));
|
||||
(frames.ElementAt(i)->GetFrameType() == EncodedFrame::AVC_I_FRAME));
|
||||
table_size += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
|
@ -98,12 +98,12 @@ ISOMediaWriter::WriteEncodedTrack(const EncodedFrameContainer& aData,
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
nsRefPtr<EncodedFrame> frame(aData.GetEncodedFrames()[i]);
|
||||
EncodedFrame::FrameType type = frame->GetFrameType();
|
||||
if (type == EncodedFrame::AUDIO_FRAME ||
|
||||
if (type == EncodedFrame::AAC_AUDIO_FRAME ||
|
||||
type == EncodedFrame::AAC_CSD) {
|
||||
frag = mAudioFragmentBuffer;
|
||||
} else if (type == EncodedFrame::I_FRAME ||
|
||||
type == EncodedFrame::P_FRAME ||
|
||||
type == EncodedFrame::B_FRAME ||
|
||||
} else if (type == EncodedFrame::AVC_I_FRAME ||
|
||||
type == EncodedFrame::AVC_P_FRAME ||
|
||||
type == EncodedFrame::AVC_B_FRAME ||
|
||||
type == EncodedFrame::AVC_CSD) {
|
||||
frag = mVideoFragmentBuffer;
|
||||
} else {
|
||||
|
@ -50,7 +50,7 @@ OggWriter::WriteEncodedTrack(const EncodedFrameContainer& aData,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
for (uint32_t i = 0; i < aData.GetEncodedFrames().Length(); i++) {
|
||||
if (aData.GetEncodedFrames()[i]->GetFrameType() != EncodedFrame::AUDIO_FRAME) {
|
||||
if (aData.GetEncodedFrames()[i]->GetFrameType() != EncodedFrame::OPUS_AUDIO_FRAME) {
|
||||
LOG("[OggWriter] wrong encoded data type!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame)
|
||||
EbmlGlobal ebml;
|
||||
ebml.offset = 0;
|
||||
|
||||
if (aFrame->GetFrameType() == EncodedFrame::FrameType::I_FRAME && mClusterHeaderIndex > 0) {
|
||||
if (aFrame->GetFrameType() == EncodedFrame::FrameType::VP8_I_FRAME && mClusterHeaderIndex > 0) {
|
||||
FinishCluster();
|
||||
}
|
||||
|
||||
@ -94,21 +94,21 @@ EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame)
|
||||
mClusterBuffs.LastElement().SetLength(aFrame->GetFrameData().Length() + DEFAULT_HEADER_SIZE);
|
||||
ebml.buf = mClusterBuffs.LastElement().Elements();
|
||||
|
||||
if (aFrame->GetFrameType() == EncodedFrame::FrameType::I_FRAME) {
|
||||
if (aFrame->GetFrameType() == EncodedFrame::FrameType::VP8_I_FRAME) {
|
||||
EbmlLoc ebmlLoc;
|
||||
Ebml_StartSubElement(&ebml, &ebmlLoc, Cluster);
|
||||
mClusterHeaderIndex = mClusterBuffs.Length() - 1; // current cluster header array index
|
||||
mClusterLengthLoc = ebmlLoc.offset;
|
||||
if (aFrame->GetFrameType() != EncodedFrame::FrameType::AUDIO_FRAME) {
|
||||
if (aFrame->GetFrameType() != EncodedFrame::FrameType::VORBIS_AUDIO_FRAME) {
|
||||
mClusterTimecode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC;
|
||||
}
|
||||
Ebml_SerializeUnsigned(&ebml, Timecode, mClusterTimecode);
|
||||
}
|
||||
|
||||
if (aFrame->GetFrameType() != EncodedFrame::FrameType::AUDIO_FRAME) {
|
||||
if (aFrame->GetFrameType() != EncodedFrame::FrameType::VORBIS_AUDIO_FRAME) {
|
||||
short timeCode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC - mClusterTimecode;
|
||||
writeSimpleBlock(&ebml, 0x1, timeCode, aFrame->GetFrameType() ==
|
||||
EncodedFrame::FrameType::I_FRAME,
|
||||
EncodedFrame::FrameType::VP8_I_FRAME,
|
||||
0, 0, (unsigned char*)aFrame->GetFrameData().Elements(),
|
||||
aFrame->GetFrameData().Length());
|
||||
} else {
|
||||
|
@ -8,10 +8,10 @@ const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// This module exposes a subset of the functionnalities of the parent DOM
|
||||
// Registry to content processes, to be be used from the AppsService component.
|
||||
// This module exposes a subset of the functionalities of the parent DOM
|
||||
// Registry to content processes, to be used from the AppsService component.
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DOMApplicationRegistry"];
|
||||
this.EXPORTED_SYMBOLS = ["DOMApplicationRegistry", "WrappedManifestCache"];
|
||||
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
@ -20,54 +20,265 @@ function debug(s) {
|
||||
//dump("-*- AppsServiceChild.jsm: " + s + "\n");
|
||||
}
|
||||
|
||||
const APPS_IPC_MSG_NAMES = [
|
||||
"Webapps:AddApp",
|
||||
"Webapps:RemoveApp",
|
||||
"Webapps:CheckForUpdate:Return:KO",
|
||||
"Webapps:FireEvent",
|
||||
"Webapps:UpdateState"
|
||||
];
|
||||
|
||||
// A simple cache for the wrapped manifests.
|
||||
this.WrappedManifestCache = {
|
||||
_cache: { },
|
||||
|
||||
// Gets an entry from the cache, and populates the cache if needed.
|
||||
get: function mcache_get(aManifestURL, aManifest, aWindow, aInnerWindowID) {
|
||||
if (!(aManifestURL in this._cache)) {
|
||||
this._cache[aManifestURL] = { };
|
||||
}
|
||||
|
||||
let winObjs = this._cache[aManifestURL];
|
||||
if (!(aInnerWindowID in winObjs)) {
|
||||
winObjs[aInnerWindowID] = Cu.cloneInto(aManifest, aWindow);
|
||||
}
|
||||
|
||||
return winObjs[aInnerWindowID];
|
||||
},
|
||||
|
||||
// Invalidates an entry in the cache.
|
||||
evict: function mcache_evict(aManifestURL, aInnerWindowID) {
|
||||
debug("Evicting manifest " + aManifestURL + " window ID " +
|
||||
aInnerWindowID);
|
||||
if (aManifestURL in this._cache) {
|
||||
let winObjs = this._cache[aManifestURL];
|
||||
if (aInnerWindowID in winObjs) {
|
||||
delete winObjs[aInnerWindowID];
|
||||
}
|
||||
|
||||
if (Object.keys(winObjs).length == 0) {
|
||||
delete this._cache[aManifestURL];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
// Clear the cache on memory pressure.
|
||||
this._cache = { };
|
||||
Cu.forceGC();
|
||||
},
|
||||
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, "memory-pressure", false);
|
||||
}
|
||||
};
|
||||
|
||||
this.WrappedManifestCache.init();
|
||||
|
||||
|
||||
// DOMApplicationRegistry keeps a cache containing a list of apps in the device.
|
||||
// This information is updated with the data received from the main process and
|
||||
// it is queried by the DOM objects to set their state.
|
||||
// This module handle all the messages broadcasted from the parent process,
|
||||
// including DOM events, which are dispatched to the corresponding DOM objects.
|
||||
|
||||
this.DOMApplicationRegistry = {
|
||||
// DOMApps will hold a list of arrays of weak references to
|
||||
// mozIDOMApplication objects indexed by manifest URL.
|
||||
DOMApps: {},
|
||||
|
||||
init: function init() {
|
||||
debug("init");
|
||||
this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
|
||||
["Webapps:AddApp", "Webapps:RemoveApp"].forEach((function(aMsgName) {
|
||||
APPS_IPC_MSG_NAMES.forEach((function(aMsgName) {
|
||||
this.cpmm.addMessageListener(aMsgName, this);
|
||||
}).bind(this));
|
||||
|
||||
this.cpmm.sendAsyncMessage("Webapps:RegisterForMessages", {
|
||||
messages: APPS_IPC_MSG_NAMES
|
||||
});
|
||||
|
||||
// We need to prime the cache with the list of apps.
|
||||
// XXX shoud we do this async and block callers if it's not yet there?
|
||||
this.webapps = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
|
||||
// XXX should we do this async and block callers if it's not yet there?
|
||||
let list = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
|
||||
this.webapps = list.webapps;
|
||||
|
||||
// We need a fast mapping from localId -> app, so we add an index.
|
||||
// And add the manifest to the app object.
|
||||
this.localIdIndex = { };
|
||||
for (let id in this.webapps) {
|
||||
let app = this.webapps[id];
|
||||
this.localIdIndex[app.localId] = app;
|
||||
app.manifest = list.manifests[id];
|
||||
}
|
||||
|
||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
// cpmm.addMessageListener causes the DOMApplicationRegistry object to live
|
||||
// forever if we don't clean up properly.
|
||||
// cpmm.addMessageListener causes the DOMApplicationRegistry object to
|
||||
// live forever if we don't clean up properly.
|
||||
this.webapps = null;
|
||||
["Webapps:AddApp", "Webapps:RemoveApp"].forEach((function(aMsgName) {
|
||||
this.DOMApps = null;
|
||||
|
||||
APPS_IPC_MSG_NAMES.forEach((aMsgName) => {
|
||||
this.cpmm.removeMessageListener(aMsgName, this);
|
||||
}).bind(this));
|
||||
});
|
||||
|
||||
this.cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
|
||||
APPS_IPC_MSG_NAMES)
|
||||
},
|
||||
|
||||
receiveMessage: function receiveMessage(aMessage) {
|
||||
debug("Received " + aMessage.name + " message.");
|
||||
let msg = aMessage.json;
|
||||
let msg = aMessage.data;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:AddApp":
|
||||
this.webapps[msg.id] = msg.app;
|
||||
this.localIdIndex[msg.app.localId] = msg.app;
|
||||
break;
|
||||
case "Webapps:RemoveApp":
|
||||
delete this.DOMApps[this.webapps[msg.id].manifestURL];
|
||||
delete this.localIdIndex[this.webapps[msg.id].localId];
|
||||
delete this.webapps[msg.id];
|
||||
break;
|
||||
case "Webapps:FireEvent":
|
||||
this._fireEvent(aMessage);
|
||||
break;
|
||||
case "Webapps:UpdateState":
|
||||
this._updateState(msg);
|
||||
break;
|
||||
case "Webapps:CheckForUpdate:Return:KO":
|
||||
let DOMApps = this.DOMApps[msg.manifestURL];
|
||||
if (!DOMApps || !msg.requestID) {
|
||||
return;
|
||||
}
|
||||
DOMApps.forEach((DOMApp) => {
|
||||
let domApp = DOMApp.get();
|
||||
if (msg.requestID) {
|
||||
domApp._fireRequestResult(aMessage, true /* aIsError */);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* mozIDOMApplication management
|
||||
*/
|
||||
|
||||
// Every time a DOM app is created, we save a weak reference to it that will
|
||||
// be used to dispatch events and fire request results.
|
||||
addDOMApp: function(aApp, aManifestURL, aId) {
|
||||
let weakRef = Cu.getWeakReference(aApp);
|
||||
|
||||
if (!this.DOMApps[aManifestURL]) {
|
||||
this.DOMApps[aManifestURL] = [];
|
||||
}
|
||||
|
||||
let apps = this.DOMApps[aManifestURL];
|
||||
|
||||
// Get rid of dead weak references.
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
if (!apps[i].get()) {
|
||||
apps.splice(i);
|
||||
}
|
||||
}
|
||||
|
||||
apps.push(weakRef);
|
||||
|
||||
// Each DOM app contains a proxy object used to build their state. We
|
||||
// return the handler for this proxy object with traps to get and set
|
||||
// app properties kept in the DOMApplicationRegistry app cache.
|
||||
return {
|
||||
get: function(target, prop) {
|
||||
if (!DOMApplicationRegistry.webapps[aId]) {
|
||||
return;
|
||||
}
|
||||
return DOMApplicationRegistry.webapps[aId][prop];
|
||||
},
|
||||
set: function(target, prop, val) {
|
||||
if (!DOMApplicationRegistry.webapps[aId]) {
|
||||
return;
|
||||
}
|
||||
DOMApplicationRegistry.webapps[aId][prop] = val;
|
||||
return;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
_fireEvent: function(aMessage) {
|
||||
let msg = aMessage.data;
|
||||
debug("_fireEvent " + JSON.stringify(msg));
|
||||
if (!this.DOMApps || !msg.manifestURL || !msg.eventType) {
|
||||
return;
|
||||
}
|
||||
|
||||
let DOMApps = this.DOMApps[msg.manifestURL];
|
||||
if (!DOMApps) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The parent might ask childs to trigger more than one event in one
|
||||
// shot, so in order to avoid needless IPC we allow an array for the
|
||||
// 'eventType' IPC message field.
|
||||
if (!Array.isArray(msg.eventType)) {
|
||||
msg.eventType = [msg.eventType];
|
||||
}
|
||||
|
||||
DOMApps.forEach((DOMApp) => {
|
||||
let domApp = DOMApp.get();
|
||||
msg.eventType.forEach((aEventType) => {
|
||||
if ('on' + aEventType in domApp) {
|
||||
domApp._fireEvent(aEventType);
|
||||
}
|
||||
});
|
||||
|
||||
if (msg.requestID) {
|
||||
aMessage.data.result = msg.manifestURL;
|
||||
domApp._fireRequestResult(aMessage);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_updateState: function(aMessage) {
|
||||
if (!this.DOMApps || !aMessage.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
let app = this.webapps[aMessage.id];
|
||||
if (!app) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMessage.app) {
|
||||
for (let prop in aMessage.app) {
|
||||
app[prop] = aMessage.app[prop];
|
||||
}
|
||||
}
|
||||
|
||||
if (aMessage.error) {
|
||||
app.downloadError = aMessage.error;
|
||||
}
|
||||
|
||||
if (aMessage.manifest) {
|
||||
app.manifest = aMessage.manifest;
|
||||
// Evict the wrapped manifest cache for all the affected DOM objects.
|
||||
let DOMApps = this.DOMApps[app.manifestURL];
|
||||
if (!DOMApps) {
|
||||
return;
|
||||
}
|
||||
DOMApps.forEach((DOMApp) => {
|
||||
let domApp = DOMApp.get();
|
||||
WrappedManifestCache.evict(app.manifestURL, domApp.innerWindowID);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIAppsService API
|
||||
*/
|
||||
getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
|
||||
debug("getAppByManifestURL " + aManifestURL);
|
||||
return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
|
||||
|
@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
|
||||
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
@ -264,50 +265,9 @@ WebappsRegistry.prototype = {
|
||||
* mozIDOMApplication object
|
||||
*/
|
||||
|
||||
// A simple cache for the wrapped manifests.
|
||||
let manifestCache = {
|
||||
_cache: { },
|
||||
|
||||
// Gets an entry from the cache, and populates the cache if needed.
|
||||
get: function mcache_get(aManifestURL, aManifest, aWindow, aInnerWindowID) {
|
||||
if (!(aManifestURL in this._cache)) {
|
||||
this._cache[aManifestURL] = { };
|
||||
}
|
||||
|
||||
let winObjs = this._cache[aManifestURL];
|
||||
if (!(aInnerWindowID in winObjs)) {
|
||||
winObjs[aInnerWindowID] = Cu.cloneInto(aManifest, aWindow);
|
||||
}
|
||||
|
||||
return winObjs[aInnerWindowID];
|
||||
},
|
||||
|
||||
// Invalidates an entry in the cache.
|
||||
evict: function mcache_evict(aManifestURL, aInnerWindowID) {
|
||||
if (aManifestURL in this._cache) {
|
||||
let winObjs = this._cache[aManifestURL];
|
||||
if (aInnerWindowID in winObjs) {
|
||||
delete winObjs[aInnerWindowID];
|
||||
}
|
||||
|
||||
if (Object.keys(winObjs).length == 0) {
|
||||
delete this._cache[aManifestURL];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
// Clear the cache on memory pressure.
|
||||
this._cache = { };
|
||||
},
|
||||
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, "memory-pressure", false);
|
||||
}
|
||||
};
|
||||
|
||||
function createApplicationObject(aWindow, aApp) {
|
||||
let app = Cc["@mozilla.org/webapps/application;1"].createInstance(Ci.mozIDOMApplication);
|
||||
let app = Cc["@mozilla.org/webapps/application;1"]
|
||||
.createInstance(Ci.mozIDOMApplication);
|
||||
app.wrappedJSObject.init(aWindow, aApp);
|
||||
return app;
|
||||
}
|
||||
@ -320,27 +280,12 @@ WebappsApplication.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
init: function(aWindow, aApp) {
|
||||
let proxyHandler = DOMApplicationRegistry.addDOMApp(this,
|
||||
aApp.manifestURL,
|
||||
aApp.id);
|
||||
this._proxy = new Proxy(this, proxyHandler);
|
||||
|
||||
this._window = aWindow;
|
||||
let principal = this._window.document.nodePrincipal;
|
||||
this._appStatus = principal.appStatus;
|
||||
this.origin = aApp.origin;
|
||||
this._manifest = aApp.manifest;
|
||||
this._updateManifest = aApp.updateManifest;
|
||||
this.manifestURL = aApp.manifestURL;
|
||||
this.receipts = aApp.receipts;
|
||||
this.installOrigin = aApp.installOrigin;
|
||||
this.installTime = aApp.installTime;
|
||||
this.installState = aApp.installState || "installed";
|
||||
this.removable = aApp.removable;
|
||||
this.lastUpdateCheck = aApp.lastUpdateCheck ? aApp.lastUpdateCheck
|
||||
: Date.now();
|
||||
this.updateTime = aApp.updateTime ? aApp.updateTime
|
||||
: aApp.installTime;
|
||||
this.progress = NaN;
|
||||
this.downloadAvailable = aApp.downloadAvailable;
|
||||
this.downloading = aApp.downloading;
|
||||
this.readyToApplyDownload = aApp.readyToApplyDownload;
|
||||
this.downloadSize = aApp.downloadSize || 0;
|
||||
|
||||
this._onprogress = null;
|
||||
this._ondownloadsuccess = null;
|
||||
@ -348,40 +293,83 @@ WebappsApplication.prototype = {
|
||||
this._ondownloadavailable = null;
|
||||
this._ondownloadapplied = null;
|
||||
|
||||
this._downloadError = null;
|
||||
this.initDOMRequestHelper(aWindow);
|
||||
},
|
||||
|
||||
this.initDOMRequestHelper(aWindow, [
|
||||
{ name: "Webapps:CheckForUpdate:Return:KO", weakRef: true },
|
||||
{ name: "Webapps:Connect:Return:OK", weakRef: true },
|
||||
{ name: "Webapps:Connect:Return:KO", weakRef: true },
|
||||
{ name: "Webapps:FireEvent", weakRef: true },
|
||||
{ name: "Webapps:GetConnections:Return:OK", weakRef: true },
|
||||
{ name: "Webapps:UpdateState", weakRef: true }
|
||||
]);
|
||||
get _appStatus() {
|
||||
return this._proxy.appStatus;
|
||||
},
|
||||
|
||||
cpmm.sendAsyncMessage("Webapps:RegisterForMessages", {
|
||||
messages: ["Webapps:FireEvent",
|
||||
"Webapps:UpdateState"],
|
||||
app: {
|
||||
id: this.id,
|
||||
manifestURL: this.manifestURL,
|
||||
installState: this.installState,
|
||||
downloading: this.downloading
|
||||
}
|
||||
});
|
||||
get downloadAvailable() {
|
||||
return this._proxy.downloadAvailable;
|
||||
},
|
||||
|
||||
get downloading() {
|
||||
return this._proxy.downloading;
|
||||
},
|
||||
|
||||
get downloadSize() {
|
||||
return this._proxy.downloadSize;
|
||||
},
|
||||
|
||||
get installOrigin() {
|
||||
return this._proxy.installOrigin;
|
||||
},
|
||||
|
||||
get installState() {
|
||||
return this._proxy.installState;
|
||||
},
|
||||
|
||||
get installTime() {
|
||||
return this._proxy.installTime;
|
||||
},
|
||||
|
||||
get lastUpdateCheck() {
|
||||
return this._proxy.lastUpdateCheck;
|
||||
},
|
||||
|
||||
get manifestURL() {
|
||||
return this._proxy.manifestURL;
|
||||
},
|
||||
|
||||
get origin() {
|
||||
return this._proxy.origin;
|
||||
},
|
||||
|
||||
get progress() {
|
||||
return this._proxy.progress;
|
||||
},
|
||||
|
||||
get readyToApplyDownload() {
|
||||
return this._proxy.readyToApplyDownload;
|
||||
},
|
||||
|
||||
get receipts() {
|
||||
return this._proxy.receipts;
|
||||
},
|
||||
|
||||
set receipts(aReceipts) {
|
||||
this._proxy.receipts = aReceipts;
|
||||
},
|
||||
|
||||
get removable() {
|
||||
return this._proxy.removable;
|
||||
},
|
||||
|
||||
get updateTime() {
|
||||
return this._proxy.updateTime;
|
||||
},
|
||||
|
||||
get manifest() {
|
||||
return manifestCache.get(this.manifestURL,
|
||||
this._manifest,
|
||||
this._window,
|
||||
this.innerWindowID);
|
||||
return WrappedManifestCache.get(this.manifestURL,
|
||||
this._proxy.manifest,
|
||||
this._window,
|
||||
this.innerWindowID);
|
||||
},
|
||||
|
||||
get updateManifest() {
|
||||
return this.updateManifest =
|
||||
this._updateManifest ? Cu.cloneInto(this._updateManifest, this._window)
|
||||
: null;
|
||||
return this._proxy.updateManifest ?
|
||||
Cu.cloneInto(this._proxy.updateManifest, this._window) : null;
|
||||
},
|
||||
|
||||
set onprogress(aCallback) {
|
||||
@ -425,7 +413,7 @@ WebappsApplication.prototype = {
|
||||
},
|
||||
|
||||
get downloadError() {
|
||||
return new this._window.DOMError(this._downloadError || '');
|
||||
return new this._window.DOMError(this._proxy.downloadError || '');
|
||||
},
|
||||
|
||||
download: function() {
|
||||
@ -467,12 +455,11 @@ WebappsApplication.prototype = {
|
||||
BrowserElementPromptService.getBrowserElementChildForWindow(this._window);
|
||||
if (browserChild) {
|
||||
this.addMessageListeners("Webapps:ClearBrowserData:Return");
|
||||
browserChild.messageManager.sendAsyncMessage(
|
||||
"Webapps:ClearBrowserData",
|
||||
{ manifestURL: this.manifestURL,
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) }
|
||||
);
|
||||
browserChild.messageManager.sendAsyncMessage("Webapps:ClearBrowserData", {
|
||||
manifestURL: this.manifestURL,
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request)
|
||||
});
|
||||
} else {
|
||||
Services.DOMRequest.fireErrorAsync(request, "NO_CLEARABLE_BROWSER");
|
||||
}
|
||||
@ -480,29 +467,34 @@ WebappsApplication.prototype = {
|
||||
},
|
||||
|
||||
connect: function(aKeyword, aRules) {
|
||||
this.addMessageListeners(["Webapps:Connect:Return:OK",
|
||||
"Webapps:Connect:Return:KO"]);
|
||||
return this.createPromise(function (aResolve, aReject) {
|
||||
cpmm.sendAsyncMessage("Webapps:Connect",
|
||||
{ keyword: aKeyword,
|
||||
rules: aRules,
|
||||
manifestURL: this.manifestURL,
|
||||
outerWindowID: this._id,
|
||||
appStatus: this._appStatus,
|
||||
requestID: this.getPromiseResolverId({
|
||||
resolve: aResolve,
|
||||
reject: aReject
|
||||
})});
|
||||
cpmm.sendAsyncMessage("Webapps:Connect", {
|
||||
keyword: aKeyword,
|
||||
rules: aRules,
|
||||
manifestURL: this.manifestURL,
|
||||
outerWindowID: this._id,
|
||||
appStatus: this._appStatus,
|
||||
requestID: this.getPromiseResolverId({
|
||||
resolve: aResolve,
|
||||
reject: aReject
|
||||
})
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
getConnections: function() {
|
||||
this.addMessageListeners("Webapps:getConnections:Return:OK");
|
||||
return this.createPromise(function (aResolve, aReject) {
|
||||
cpmm.sendAsyncMessage("Webapps:GetConnections",
|
||||
{ manifestURL: this.manifestURL,
|
||||
outerWindowID: this._id,
|
||||
requestID: this.getPromiseResolverId({
|
||||
resolve: aResolve,
|
||||
reject: aReject
|
||||
})});
|
||||
cpmm.sendAsyncMessage("Webapps:GetConnections", {
|
||||
manifestURL: this.manifestURL,
|
||||
outerWindowID: this._id,
|
||||
requestID: this.getPromiseResolverId({
|
||||
resolve: aResolve,
|
||||
reject: aReject
|
||||
})
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
@ -551,12 +543,7 @@ WebappsApplication.prototype = {
|
||||
|
||||
uninit: function() {
|
||||
this._onprogress = null;
|
||||
cpmm.sendAsyncMessage("Webapps:UnregisterForMessages", [
|
||||
"Webapps:FireEvent",
|
||||
"Webapps:UpdateState"
|
||||
]);
|
||||
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
WrappedManifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
},
|
||||
|
||||
_fireEvent: function(aName) {
|
||||
@ -573,21 +560,15 @@ WebappsApplication.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_updateState: function(aMsg) {
|
||||
if (aMsg.app) {
|
||||
for (let prop in aMsg.app) {
|
||||
this[prop] = aMsg.app[prop];
|
||||
}
|
||||
}
|
||||
|
||||
if (aMsg.error) {
|
||||
this._downloadError = aMsg.error;
|
||||
}
|
||||
|
||||
if (aMsg.manifest) {
|
||||
this._manifest = aMsg.manifest;
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
_fireRequestResult: function(aMessage, aIsError) {
|
||||
let req;
|
||||
let msg = aMessage.data;
|
||||
req = this.takeRequest(msg.requestID);
|
||||
if (!req) {
|
||||
return;
|
||||
}
|
||||
aIsError ? Services.DOMRequest.fireError(req, msg.error)
|
||||
: Services.DOMRequest.fireSuccess(req, msg.result);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
@ -601,10 +582,7 @@ WebappsApplication.prototype = {
|
||||
req = this.takeRequest(msg.requestID);
|
||||
}
|
||||
|
||||
// ondownload* callbacks should be triggered on all app instances
|
||||
if ((msg.oid != this._id || !req) &&
|
||||
aMessage.name !== "Webapps:FireEvent" &&
|
||||
aMessage.name !== "Webapps:UpdateState") {
|
||||
if (msg.oid != this._id || !req) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -619,45 +597,13 @@ WebappsApplication.prototype = {
|
||||
"Webapps:Launch:Return:KO"]);
|
||||
Services.DOMRequest.fireSuccess(req, null);
|
||||
break;
|
||||
case "Webapps:CheckForUpdate:Return:KO":
|
||||
Services.DOMRequest.fireError(req, msg.error);
|
||||
break;
|
||||
case "Webapps:FireEvent":
|
||||
if (msg.manifestURL != this.manifestURL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The parent might ask childs to trigger more than one event in one
|
||||
// shot, so in order to avoid needless IPC we allow an array for the
|
||||
// 'eventType' IPC message field.
|
||||
if (!Array.isArray(msg.eventType)) {
|
||||
msg.eventType = [msg.eventType];
|
||||
}
|
||||
|
||||
msg.eventType.forEach((aEventType) => {
|
||||
if ("_on" + aEventType in this) {
|
||||
this._fireEvent(aEventType);
|
||||
} else {
|
||||
dump("Unsupported event type " + aEventType + "\n");
|
||||
}
|
||||
});
|
||||
|
||||
if (req) {
|
||||
Services.DOMRequest.fireSuccess(req, this.manifestURL);
|
||||
}
|
||||
break;
|
||||
case "Webapps:UpdateState":
|
||||
if (msg.manifestURL != this.manifestURL) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateState(msg);
|
||||
break;
|
||||
case "Webapps:ClearBrowserData:Return":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
Services.DOMRequest.fireSuccess(req, null);
|
||||
break;
|
||||
case "Webapps:Connect:Return:OK":
|
||||
this.removeMessageListeners(["Webapps:Connect:Return:OK",
|
||||
"Webapps:Connect:Return:KO"]);
|
||||
let messagePorts = [];
|
||||
msg.messagePortIDs.forEach((aPortID) => {
|
||||
let port = new this._window.MozInterAppMessagePort(aPortID);
|
||||
@ -666,9 +612,12 @@ WebappsApplication.prototype = {
|
||||
req.resolve(messagePorts);
|
||||
break;
|
||||
case "Webapps:Connect:Return:KO":
|
||||
this.removeMessageListeners(["Webapps:Connect:Return:OK",
|
||||
"Webapps:Connect:Return:KO"]);
|
||||
req.reject("No connections registered");
|
||||
break;
|
||||
case "Webapps:GetConnections:Return:OK":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
let connections = [];
|
||||
msg.connections.forEach((aConnection) => {
|
||||
let connection =
|
||||
@ -850,12 +799,8 @@ WebappsApplicationMgmt.prototype = {
|
||||
break;
|
||||
case "Webapps:Uninstall:Broadcast:Return:OK":
|
||||
if (this._onuninstall) {
|
||||
let detail = {
|
||||
manifestURL: msg.manifestURL,
|
||||
origin: msg.origin
|
||||
};
|
||||
let event = new this._window.MozApplicationEvent("applicationuninstall",
|
||||
{ application : createApplicationObject(this._window, detail) });
|
||||
{ application : createApplicationObject(this._window, msg) });
|
||||
this._onuninstall.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
@ -884,7 +829,5 @@ WebappsApplicationMgmt.prototype = {
|
||||
classDescription: "Webapps Application Mgmt"})
|
||||
}
|
||||
|
||||
manifestCache.init();
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry,
|
||||
WebappsApplication]);
|
||||
|
@ -1142,8 +1142,7 @@ this.DOMApplicationRegistry = {
|
||||
this.removeMessageListener(["Webapps:Internal:AllMessages"], mm);
|
||||
break;
|
||||
case "Webapps:GetList":
|
||||
this.addMessageListener(["Webapps:AddApp", "Webapps:RemoveApp"], null, mm);
|
||||
return this.webapps;
|
||||
return { webapps: this.webapps, manifests: this._manifestCache };
|
||||
case "Webapps:Download":
|
||||
this.startDownload(msg.manifestURL);
|
||||
break;
|
||||
@ -1288,7 +1287,7 @@ this.DOMApplicationRegistry = {
|
||||
downloading: false
|
||||
},
|
||||
error: error,
|
||||
manifestURL: app.manifestURL,
|
||||
id: app.id
|
||||
})
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloaderror",
|
||||
@ -1317,7 +1316,7 @@ this.DOMApplicationRegistry = {
|
||||
if (!app.downloadAvailable) {
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
error: "NO_DOWNLOAD_AVAILABLE",
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloaderror",
|
||||
@ -1362,7 +1361,7 @@ this.DOMApplicationRegistry = {
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: jsonManifest,
|
||||
manifestURL: aManifestURL
|
||||
id: app.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadsuccess",
|
||||
@ -1405,7 +1404,7 @@ this.DOMApplicationRegistry = {
|
||||
DOMApplicationRegistry._saveApps().then(() => {
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: aManifestURL
|
||||
id: app.id
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadsuccess",
|
||||
@ -1499,7 +1498,7 @@ this.DOMApplicationRegistry = {
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: aData,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadapplied",
|
||||
@ -1539,7 +1538,7 @@ this.DOMApplicationRegistry = {
|
||||
installState: aApp.installState,
|
||||
progress: 0
|
||||
},
|
||||
manifestURL: aApp.manifestURL
|
||||
id: aApp.id
|
||||
});
|
||||
let cacheUpdate = updateSvc.scheduleAppUpdate(
|
||||
appcacheURI, docURI, aApp.localId, false, aProfileDir);
|
||||
@ -1589,6 +1588,7 @@ this.DOMApplicationRegistry = {
|
||||
debug("checkForUpdate for " + aData.manifestURL);
|
||||
|
||||
function sendError(aError) {
|
||||
debug("checkForUpdate error " + aError);
|
||||
aData.error = aError;
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
|
||||
}
|
||||
@ -1618,8 +1618,7 @@ this.DOMApplicationRegistry = {
|
||||
// then we can't have an update.
|
||||
if (app.origin.startsWith("app://") &&
|
||||
app.manifestURL.startsWith("app://")) {
|
||||
aData.error = "NOT_UPDATABLE";
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
|
||||
sendError("NOT_UPDATABLE");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1636,8 +1635,7 @@ this.DOMApplicationRegistry = {
|
||||
if (onlyCheckAppCache) {
|
||||
// Bail out for packaged apps.
|
||||
if (app.origin.startsWith("app://")) {
|
||||
aData.error = "NOT_UPDATABLE";
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
|
||||
sendError("NOT_UPDATABLE");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1645,8 +1643,7 @@ this.DOMApplicationRegistry = {
|
||||
this._readManifests([{ id: id }]).then((aResult) => {
|
||||
let manifest = aResult[0].manifest;
|
||||
if (!manifest.appcache_path) {
|
||||
aData.error = "NOT_UPDATABLE";
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
|
||||
sendError("NOT_UPDATABLE");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1662,7 +1659,7 @@ this.DOMApplicationRegistry = {
|
||||
this._saveApps().then(() => {
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadavailable",
|
||||
@ -1671,8 +1668,7 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
});
|
||||
} else {
|
||||
aData.error = "NOT_UPDATABLE";
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
|
||||
sendError("NOT_UPDATABLE");
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1732,7 +1728,7 @@ this.DOMApplicationRegistry = {
|
||||
: "downloadapplied";
|
||||
aMm.sendAsyncMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
aMm.sendAsyncMessage("Webapps:FireEvent", {
|
||||
eventType: eventType,
|
||||
@ -1759,7 +1755,7 @@ this.DOMApplicationRegistry = {
|
||||
: "downloadapplied";
|
||||
aMm.sendAsyncMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
aMm.sendAsyncMessage("Webapps:FireEvent", {
|
||||
eventType: eventType,
|
||||
@ -1867,7 +1863,7 @@ this.DOMApplicationRegistry = {
|
||||
this._saveApps().then(() => {
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aApp,
|
||||
manifestURL: aApp.manifestURL
|
||||
id: aApp.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadavailable",
|
||||
@ -1931,7 +1927,7 @@ this.DOMApplicationRegistry = {
|
||||
reg.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aApp,
|
||||
manifest: aApp.manifest,
|
||||
manifestURL: aApp.manifestURL
|
||||
id: aApp.id
|
||||
});
|
||||
reg.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadapplied",
|
||||
@ -1953,7 +1949,7 @@ this.DOMApplicationRegistry = {
|
||||
reg.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aApp,
|
||||
manifest: aApp.manifest,
|
||||
manifestURL: aApp.manifestURL
|
||||
id: aApp.id
|
||||
});
|
||||
reg.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: eventType,
|
||||
@ -2218,8 +2214,8 @@ this.DOMApplicationRegistry = {
|
||||
queuedDownload: {},
|
||||
queuedPackageDownload: {},
|
||||
|
||||
onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
aDontNeedNetwork) {
|
||||
onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
aDontNeedNetwork) {
|
||||
// If we are offline, register to run when we'll be online.
|
||||
if ((Services.io.offline) && !aDontNeedNetwork) {
|
||||
let onlineWrapper = {
|
||||
@ -2349,7 +2345,6 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest;
|
||||
this._writeManifestFile(id, aData.isPackage, jsonManifest);
|
||||
|
||||
debug("app.origin: " + app.origin);
|
||||
let manifest = new ManifestHelper(jsonManifest, app.origin);
|
||||
|
||||
let appObject = this._cloneApp(aData, app, manifest, id, localId);
|
||||
@ -2393,6 +2388,8 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
// corresponging DOMRequest.onsuccess event as soon as the app is properly
|
||||
// saved in the registry.
|
||||
this._saveApps().then(() => {
|
||||
aData.isPackage ? appObject.updateManifest = jsonManifest :
|
||||
appObject.manifest = jsonManifest;
|
||||
this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
|
||||
if (aData.isPackage && aData.autoInstall) {
|
||||
// Skip directly to onInstallSuccessAck, since there isn't
|
||||
@ -2509,7 +2506,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: aManifest,
|
||||
manifestURL: aNewApp.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
@ -2619,14 +2616,11 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
oldApp,
|
||||
aNewApp);
|
||||
|
||||
AppDownloadManager.add(
|
||||
aNewApp.manifestURL,
|
||||
{
|
||||
channel: requestChannel,
|
||||
appId: id,
|
||||
previousState: aIsUpdate ? "installed" : "pending"
|
||||
}
|
||||
);
|
||||
AppDownloadManager.add(aNewApp.manifestURL, {
|
||||
channel: requestChannel,
|
||||
appId: id,
|
||||
previousState: aIsUpdate ? "installed" : "pending"
|
||||
});
|
||||
|
||||
// We set the 'downloading' flag to true right before starting the fetch.
|
||||
oldApp.downloading = true;
|
||||
@ -2649,7 +2643,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
debug("package's etag or hash unchanged; sending 'applied' event");
|
||||
// The package's Etag or hash has not changed.
|
||||
// We send a "applied" event right away.
|
||||
this._sendAppliedEvent(aNewApp, oldApp, id);
|
||||
this._sendAppliedEvent(oldApp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2789,7 +2783,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
app: {
|
||||
progress: aProgress
|
||||
},
|
||||
manifestURL: aNewApp.manifestURL
|
||||
id: aNewApp.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "progress",
|
||||
@ -2917,21 +2911,21 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
* @param aOldApp {Object} the currently stored app data
|
||||
* @param aId {String} the unique id of the app
|
||||
*/
|
||||
_sendAppliedEvent: function(aNewApp, aOldApp, aId) {
|
||||
aOldApp.downloading = false;
|
||||
aOldApp.downloadAvailable = false;
|
||||
aOldApp.downloadSize = 0;
|
||||
aOldApp.installState = "installed";
|
||||
aOldApp.readyToApplyDownload = false;
|
||||
if (aOldApp.staged && aOldApp.staged.manifestHash) {
|
||||
_sendAppliedEvent: function(aApp) {
|
||||
aApp.downloading = false;
|
||||
aApp.downloadAvailable = false;
|
||||
aApp.downloadSize = 0;
|
||||
aApp.installState = "installed";
|
||||
aApp.readyToApplyDownload = false;
|
||||
if (aApp.staged && aApp.staged.manifestHash) {
|
||||
// If we're here then the manifest has changed but the package
|
||||
// hasn't. Let's clear this, so we don't keep offering
|
||||
// a bogus update to the user
|
||||
aOldApp.manifestHash = aOldApp.staged.manifestHash;
|
||||
aOldApp.etag = aOldApp.staged.etag || aOldApp.etag;
|
||||
aOldApp.staged = {};
|
||||
aApp.manifestHash = aApp.staged.manifestHash;
|
||||
aApp.etag = aApp.staged.etag || aApp.etag;
|
||||
aApp.staged = {};
|
||||
// Move the staged update manifest to a non staged one.
|
||||
let dirPath = this._getAppDir(aId).path;
|
||||
let dirPath = this._getAppDir(aApp.id).path;
|
||||
|
||||
// We don't really mind much if this fails.
|
||||
OS.File.move(OS.Path.join(dirPath, "staged-update.webapp"),
|
||||
@ -2941,15 +2935,15 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
// Save the updated registry, and cleanup the tmp directory.
|
||||
this._saveApps().then(() => {
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aOldApp,
|
||||
manifestURL: aNewApp.manifestURL
|
||||
app: aApp,
|
||||
id: aApp.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
manifestURL: aNewApp.manifestURL,
|
||||
manifestURL: aApp.manifestURL,
|
||||
eventType: ["downloadsuccess", "downloadapplied"]
|
||||
});
|
||||
});
|
||||
let file = FileUtils.getFile("TmpD", ["webapps", aId], false);
|
||||
let file = FileUtils.getFile("TmpD", ["webapps", aApp.id], false);
|
||||
if (file && file.exists()) {
|
||||
file.remove(true);
|
||||
}
|
||||
@ -3328,7 +3322,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aOldApp,
|
||||
error: aError,
|
||||
manifestURL: aNewApp.manifestURL
|
||||
id: aNewApp.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloaderror",
|
||||
@ -3878,7 +3872,7 @@ AppcacheObserver.prototype = {
|
||||
let app = this.app;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "progress",
|
||||
@ -3910,7 +3904,7 @@ AppcacheObserver.prototype = {
|
||||
app.downloadAvailable = false;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
@ -3923,7 +3917,7 @@ AppcacheObserver.prototype = {
|
||||
app.downloading = false;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
id: app.id
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
error: aError,
|
||||
|
@ -99,6 +99,7 @@ var PackagedTestHelper = (function PackagedTestHelper() {
|
||||
var aApp = evt.application;
|
||||
aApp.ondownloaderror = function(evt) {
|
||||
var error = aApp.downloadError.name;
|
||||
ok(true, "Got downloaderror " + error);
|
||||
if (error == aExpectedError) {
|
||||
ok(true, "Got expected " + aExpectedError);
|
||||
var expected = {
|
||||
|
@ -79,16 +79,15 @@ function updateApp(aExpectedReady, aPreviousVersion, aNextVersion) {
|
||||
checkLastAppState.bind(PackagedTestHelper, miniManifestURL, false, false,
|
||||
aNextVersion, PackagedTestHelper.next);
|
||||
|
||||
var ondownloadsuccesshandler =
|
||||
checkLastAppState.bind(undefined, miniManifestURL,
|
||||
aExpectedReady, false, aPreviousVersion,
|
||||
function() {
|
||||
navigator.mozApps.mgmt.applyDownload(lApp);
|
||||
});
|
||||
|
||||
checkForUpdate(true, ondownloadsuccesshandler, ondownloadappliedhandler, null,
|
||||
true);
|
||||
var ondownloadsuccesshandler =
|
||||
checkLastAppState.bind(undefined, miniManifestURL,
|
||||
aExpectedReady, false, aPreviousVersion,
|
||||
function() {
|
||||
navigator.mozApps.mgmt.applyDownload(lApp);
|
||||
});
|
||||
|
||||
checkForUpdate(true, ondownloadsuccesshandler, ondownloadappliedhandler, null,
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
@ -175,7 +174,7 @@ var steps = [
|
||||
"&appName=arandomname" +
|
||||
"&appToFail1";
|
||||
PackagedTestHelper.checkAppDownloadError(miniManifestURL,
|
||||
"MANIFEST_MISMATCH", 2, false, true,
|
||||
"MANIFEST_MISMATCH", 1, false, true,
|
||||
"arandomname",
|
||||
function () {
|
||||
checkForUpdate(false, null, null, null, false,
|
||||
|
@ -247,4 +247,4 @@ addLoadEvent(go);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -240,7 +240,7 @@ CameraControlImpl::OnError(CameraControlListener::CameraErrorContext aContext,
|
||||
"init-failed",
|
||||
"invalid-configuration",
|
||||
"service-failed",
|
||||
"set-picture-size-failred",
|
||||
"set-picture-size-failed",
|
||||
"set-thumbnail-size-failed",
|
||||
"unknown"
|
||||
};
|
||||
|
@ -124,7 +124,7 @@ StartRecordingHelper::HandleEvent(nsIDOMEvent* aEvent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS0(mozilla::StartRecordingHelper)
|
||||
NS_IMPL_ISUPPORTS1(mozilla::StartRecordingHelper, nsIDOMEventListener)
|
||||
|
||||
nsDOMCameraControl::DOMCameraConfiguration::DOMCameraConfiguration()
|
||||
: CameraConfiguration()
|
||||
@ -621,7 +621,7 @@ nsDOMCameraControl::SensorAngle()
|
||||
{
|
||||
MOZ_ASSERT(mCameraControl);
|
||||
|
||||
int32_t angle;
|
||||
int32_t angle = 0;
|
||||
mCameraControl->Get(CAMERA_PARAM_SENSORANGLE, angle);
|
||||
return angle;
|
||||
}
|
||||
@ -1160,6 +1160,8 @@ nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
|
||||
void
|
||||
nsDOMCameraControl::OnError(CameraControlListener::CameraErrorContext aContext, const nsAString& aError)
|
||||
{
|
||||
DOM_CAMERA_LOGI("DOM OnError context=%d, error='%s'\n", aContext,
|
||||
NS_LossyConvertUTF16toASCII(aError).get());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<CameraErrorCallback>* errorCb;
|
||||
@ -1195,19 +1197,31 @@ nsDOMCameraControl::OnError(CameraControlListener::CameraErrorContext aContext,
|
||||
break;
|
||||
|
||||
case CameraControlListener::kInStopRecording:
|
||||
NS_WARNING("Failed to stop recording (which shouldn't happen)!");
|
||||
MOZ_CRASH();
|
||||
break;
|
||||
// This method doesn't have any callbacks, so all we can do is log the
|
||||
// failure. This only happens after the hardware has been released.
|
||||
NS_WARNING("Failed to stop recording");
|
||||
return;
|
||||
|
||||
case CameraControlListener::kInStartPreview:
|
||||
NS_WARNING("Failed to (re)start preview!");
|
||||
MOZ_CRASH();
|
||||
break;
|
||||
// This method doesn't have any callbacks, so all we can do is log the
|
||||
// failure. This only happens after the hardware has been released.
|
||||
NS_WARNING("Failed to (re)start preview");
|
||||
return;
|
||||
|
||||
case CameraControlListener::kInUnspecified:
|
||||
if (aError.EqualsASCII("ErrorServiceFailed")) {
|
||||
// If the camera service fails, we will get preview-stopped and
|
||||
// hardware-closed events, so nothing to do here.
|
||||
// hardware-closed events, so nothing to do here.
|
||||
NS_WARNING("Camera service failed");
|
||||
return;
|
||||
}
|
||||
if (aError.EqualsASCII("ErrorSetPictureSizeFailed") ||
|
||||
aError.EqualsASCII("ErrorSetThumbnailSizeFailed")) {
|
||||
// We currently don't handle attribute setter failure. Practically,
|
||||
// this only ever happens if a setter is called after the hardware
|
||||
// has gone away before an asynchronous set gets to happen, so we
|
||||
// swallow these.
|
||||
NS_WARNING("Failed to set either picture or thumbnail size");
|
||||
return;
|
||||
}
|
||||
// fallthrough
|
||||
@ -1220,7 +1234,7 @@ nsDOMCameraControl::OnError(CameraControlListener::CameraErrorContext aContext,
|
||||
MOZ_ASSERT(errorCb);
|
||||
|
||||
if (!*errorCb) {
|
||||
DOM_CAMERA_LOGW("DOM No error handler for error '%s' at %d\n",
|
||||
DOM_CAMERA_LOGW("DOM No error handler for error '%s' in context=%d\n",
|
||||
NS_LossyConvertUTF16toASCII(aError).get(), aContext);
|
||||
return;
|
||||
}
|
||||
|
@ -328,6 +328,14 @@ DOMCameraControlListener::OnError(CameraErrorContext aContext, CameraError aErro
|
||||
error = NS_LITERAL_STRING("ErrorServiceFailed");
|
||||
break;
|
||||
|
||||
case kErrorSetPictureSizeFailed:
|
||||
error = NS_LITERAL_STRING("ErrorSetPictureSizeFailed");
|
||||
break;
|
||||
|
||||
case kErrorSetThumbnailSizeFailed:
|
||||
error = NS_LITERAL_STRING("ErrorSetThumbnailSizeFailed");
|
||||
break;
|
||||
|
||||
case kErrorApiFailed:
|
||||
// XXXmikeh legacy error placeholder
|
||||
error = NS_LITERAL_STRING("FAILURE");
|
||||
|
@ -455,6 +455,7 @@ nsresult
|
||||
nsGonkCameraControl::Set(uint32_t aKey, int aValue)
|
||||
{
|
||||
if (aKey == CAMERA_PARAM_PICTURE_ROTATION) {
|
||||
RETURN_IF_NO_CAMERA_HW();
|
||||
aValue = RationalizeRotation(aValue + mCameraHw->GetSensorOrientation());
|
||||
}
|
||||
return SetAndPush(aKey, aValue);
|
||||
@ -464,9 +465,7 @@ nsresult
|
||||
nsGonkCameraControl::Get(uint32_t aKey, int& aRet)
|
||||
{
|
||||
if (aKey == CAMERA_PARAM_SENSORANGLE) {
|
||||
if (!mCameraHw.get()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
RETURN_IF_NO_CAMERA_HW();
|
||||
aRet = mCameraHw->GetSensorOrientation();
|
||||
return NS_OK;
|
||||
}
|
||||
@ -603,7 +602,7 @@ nsGonkCameraControl::SetThumbnailSizeImpl(const Size& aSize)
|
||||
}
|
||||
|
||||
Size size = supportedSizes[smallestDeltaIndex];
|
||||
DOM_CAMERA_LOGI("camera-param set picture-size = %ux%u (requested %ux%u)\n",
|
||||
DOM_CAMERA_LOGI("camera-param set thumbnail-size = %ux%u (requested %ux%u)\n",
|
||||
size.width, size.height, aSize.width, aSize.height);
|
||||
if (size.width > INT32_MAX || size.height > INT32_MAX) {
|
||||
DOM_CAMERA_LOGE("Supported thumbnail size is too big, no change\n");
|
||||
@ -1037,27 +1036,13 @@ nsGonkCameraControl::SetPreviewSize(const Size& aSize)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ICameraControlParameterSetAutoEnter set(this);
|
||||
|
||||
// Some camera drivers will ignore our preview size if it's larger
|
||||
// that the currently set video recording size, so we need to set
|
||||
// both here just in case.
|
||||
rv = SetAndPush(CAMERA_PARAM_PREVIEWSIZE, best);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to set picture mode preview size (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = SetAndPush(CAMERA_PARAM_VIDEOSIZE, best);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to bump up picture mode video size (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Some camera drivers will ignore our preview size if it's larger
|
||||
// that the currently set video recording size, so we need to set
|
||||
// both here just in case.
|
||||
mParams.Set(CAMERA_PARAM_PREVIEWSIZE, best);
|
||||
mParams.Set(CAMERA_PARAM_VIDEOSIZE, best);
|
||||
mCurrentConfiguration.mPreviewSize = best;
|
||||
return NS_OK;
|
||||
return PushParameters();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -6,3 +6,4 @@ support-files = camera_common.js
|
||||
[test_camera_3.html]
|
||||
[test_camera_hardware_init_failure.html]
|
||||
[test_camera_hardware_failures.html]
|
||||
[test_bug975472.html]
|
||||
|
222
dom/camera/test/test_bug975472.html
Normal file
222
dom/camera/test/test_bug975472.html
Normal file
@ -0,0 +1,222 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for bug 975472</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'cif',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
var options = {
|
||||
rotation: 0,
|
||||
position: {
|
||||
latitude: 43.645687,
|
||||
longitude: -79.393661
|
||||
},
|
||||
dateTime: Date.now()
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
}
|
||||
function next() {
|
||||
Camera.nextTest();
|
||||
}
|
||||
|
||||
// The array of tests
|
||||
var tests = [
|
||||
{
|
||||
key: "release-after-release",
|
||||
func: function testAutoFocus(camera) {
|
||||
function onSuccess(success) {
|
||||
ok(true, "release() succeeded");
|
||||
next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "release() failed with: " + error);
|
||||
}
|
||||
camera.release(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "set-picture-size-after-release",
|
||||
func: function testSetPictureSize(camera) {
|
||||
camera.pictureSize = { width: 0, height: 0 };
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "set-thumbnail-size-after-release",
|
||||
func: function testSetThumbnailSize(camera) {
|
||||
camera.thumbnailSize = { width: 0, height: 0 };
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "get-sensor-angle-after-release",
|
||||
func: function testGetSensorAngle(camera) {
|
||||
ok(camera.sensorAngle == 0, "camera.sensorAngle = " + camera.sensorAngle);
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "resume-preview-after-release",
|
||||
func: function testResumePreview(camera) {
|
||||
camera.resumePreview();
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "auto-focus-after-release",
|
||||
func: function testAutoFocus(camera) {
|
||||
function onSuccess(success) {
|
||||
ok(false, "autoFocus() succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "autoFocus() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.autoFocus(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "take-picture-after-release",
|
||||
func: function testTakePicture(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "takePicture() succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "takePicture() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null, onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "start-recording-after-release",
|
||||
func: function testStartRecording(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "startRecording() process succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "startRecording() process failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
var recordingOptions = {
|
||||
profile: 'cif',
|
||||
rotation: 0
|
||||
};
|
||||
camera.startRecording(recordingOptions,
|
||||
navigator.getDeviceStorage('videos'),
|
||||
'bug975472.mp4',
|
||||
onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "stop-recording-after-release",
|
||||
func: function testStopRecording(camera) {
|
||||
camera.stopRecording();
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "set-configuration-after-release",
|
||||
func: function testSetConfiguration(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "setConfiguration() process succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "setConfiguration() process failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.setConfiguration(config, onSuccess, onError);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i ) {
|
||||
yield tests[i];
|
||||
}
|
||||
}();
|
||||
|
||||
var Camera = {
|
||||
cameraObj: null,
|
||||
_otherPictureSize: null,
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
onCameraReady: function () {
|
||||
Camera.nextTest = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
info("test: " + t.key);
|
||||
t.func(Camera.cameraObj);
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Release the camera hardware, and call all of the asynchronous methods
|
||||
// to make sure they properly handle being in this state.
|
||||
Camera.cameraObj.release();
|
||||
next();
|
||||
},
|
||||
release: function release() {
|
||||
cameraObj = null;
|
||||
},
|
||||
start: function run_test() {
|
||||
function onSuccess(camera, config) {
|
||||
Camera.cameraObj = camera;
|
||||
Camera.viewfinder.mozSrcObject = camera;
|
||||
Camera.viewfinder.play();
|
||||
ok(camera.capabilities.pictureSizes.length > 0,
|
||||
"capabilities.pictureSizes.length = " +
|
||||
camera.capabilities.pictureSizes.length);
|
||||
Camera._otherPictureSize = camera.capabilities.pictureSizes.slice(-1)[0];
|
||||
camera.pictureSize = camera.capabilities.pictureSizes[0];
|
||||
options.pictureSize = Camera._otherPictureSize;
|
||||
options.fileFormat = camera.capabilities.fileFormats[0];
|
||||
info("getCamera callback, setting pictureSize = " + options.pictureSize.toSource());
|
||||
Camera.cameraObj.onPreviewStateChange = function(state) {
|
||||
if (state === 'started') {
|
||||
info("viewfinder is ready and playing");
|
||||
Camera.cameraObj.onPreviewStateChange = null;
|
||||
Camera.onCameraReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
});
|
||||
|
||||
Camera.start();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -794,6 +794,21 @@ ContactDB.prototype = {
|
||||
fail("No migration steps for the new version!");
|
||||
}
|
||||
|
||||
this.cpuLock = Cc["@mozilla.org/power/powermanagerservice;1"]
|
||||
.getService(Ci.nsIPowerManagerService)
|
||||
.newWakeLock("cpu");
|
||||
|
||||
function unlockCPU() {
|
||||
if (outer.cpuLock) {
|
||||
if (DEBUG) debug("unlocking cpu wakelock");
|
||||
outer.cpuLock.unlock();
|
||||
outer.cpuLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
aTransaction.addEventListener("complete", unlockCPU);
|
||||
aTransaction.addEventListener("abort", unlockCPU);
|
||||
|
||||
next();
|
||||
},
|
||||
|
||||
|
@ -12,7 +12,7 @@ Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
const NETWORKSERVICE_CONTRACTID = "@mozilla.org/network/service;1";
|
||||
const NETWORKSERVICE_CID = Components.ID("{c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c}");
|
||||
const NETWORKSERVICE_CID = Components.ID("{baec696c-c78d-42db-8b44-603f8fbfafb4}");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkWorker",
|
||||
"@mozilla.org/network/worker;1",
|
||||
@ -365,6 +365,30 @@ NetworkService.prototype = {
|
||||
this.controlMessage(options, function() {});
|
||||
},
|
||||
|
||||
addSecondaryRoute: function(ifname, route) {
|
||||
if(DEBUG) debug("Going to add route to secondary table on " + ifname);
|
||||
let options = {
|
||||
cmd: "addSecondaryRoute",
|
||||
ifname: ifname,
|
||||
ip: route.ip,
|
||||
prefix: route.prefix,
|
||||
gateway: route.gateway
|
||||
};
|
||||
this.controlMessage(options, function() {});
|
||||
},
|
||||
|
||||
removeSecondaryRoute: function(ifname, route) {
|
||||
if(DEBUG) debug("Going to remove route from secondary table on " + ifname);
|
||||
let options = {
|
||||
cmd: "removeSecondaryRoute",
|
||||
ifname: ifname,
|
||||
ip: route.ip,
|
||||
prefix: route.prefix,
|
||||
gateway: route.gateway
|
||||
};
|
||||
this.controlMessage(options, function() {});
|
||||
},
|
||||
|
||||
setNetworkProxy: function(network) {
|
||||
try {
|
||||
if (!network.httpProxyHost || network.httpProxyHost === "") {
|
||||
|
@ -1,3 +1,3 @@
|
||||
# NetworkService.js
|
||||
component {c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c} NetworkService.js
|
||||
contract @mozilla.org/network/service;1 {c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c}
|
||||
component {baec696c-c78d-42db-8b44-603f8fbfafb4} NetworkService.js
|
||||
contract @mozilla.org/network/service;1 {baec696c-c78d-42db-8b44-603f8fbfafb4}
|
||||
|
@ -907,6 +907,10 @@ void NetworkUtils::ExecuteCommand(NetworkParams aOptions)
|
||||
removeHostRoute(aOptions);
|
||||
} else if (aOptions.mCmd.EqualsLiteral("removeHostRoutes")) {
|
||||
removeHostRoutes(aOptions);
|
||||
} else if (aOptions.mCmd.EqualsLiteral("addSecondaryRoute")) {
|
||||
addSecondaryRoute(aOptions);
|
||||
} else if (aOptions.mCmd.EqualsLiteral("removeSecondaryRoute")) {
|
||||
removeSecondaryRoute(aOptions);
|
||||
} else if (aOptions.mCmd.EqualsLiteral("getNetworkInterfaceStats")) {
|
||||
getNetworkInterfaceStats(aOptions);
|
||||
} else if (aOptions.mCmd.EqualsLiteral("setNetworkInterfaceAlarm")) {
|
||||
@ -1133,6 +1137,34 @@ bool NetworkUtils::removeNetworkRoute(NetworkParams& aOptions)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkUtils::addSecondaryRoute(NetworkParams& aOptions)
|
||||
{
|
||||
char command[MAX_COMMAND_SIZE];
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1,
|
||||
"interface route add %s secondary %s %s %s",
|
||||
GET_CHAR(mIfname),
|
||||
GET_CHAR(mIp),
|
||||
GET_CHAR(mPrefix),
|
||||
GET_CHAR(mGateway));
|
||||
|
||||
doCommand(command, nullptr, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkUtils::removeSecondaryRoute(NetworkParams& aOptions)
|
||||
{
|
||||
char command[MAX_COMMAND_SIZE];
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1,
|
||||
"interface route remove %s secondary %s %s %s",
|
||||
GET_CHAR(mIfname),
|
||||
GET_CHAR(mIp),
|
||||
GET_CHAR(mPrefix),
|
||||
GET_CHAR(mGateway));
|
||||
|
||||
doCommand(command, nullptr, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkUtils::getNetworkInterfaceStats(NetworkParams& aOptions)
|
||||
{
|
||||
DEBUG("getNetworkInterfaceStats: %s", GET_CHAR(mIfname));
|
||||
|
@ -268,6 +268,8 @@ private:
|
||||
bool removeHostRoute(NetworkParams& aOptions);
|
||||
bool removeHostRoutes(NetworkParams& aOptions);
|
||||
bool removeNetworkRoute(NetworkParams& aOptions);
|
||||
bool addSecondaryRoute(NetworkParams& aOptions);
|
||||
bool removeSecondaryRoute(NetworkParams& aOptions);
|
||||
bool getNetworkInterfaceStats(NetworkParams& aOptions);
|
||||
bool setNetworkInterfaceAlarm(NetworkParams& aOptions);
|
||||
bool enableNetworkInterfaceAlarm(NetworkParams& aOptions);
|
||||
|
@ -686,7 +686,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
|
||||
},
|
||||
|
||||
_createTimer: function() {
|
||||
if (_timer) {
|
||||
if (!_timer) {
|
||||
_timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
}
|
||||
_timer.initWithCallback(this._executeRequest.bind(this),
|
||||
|
@ -104,7 +104,7 @@ interface nsIUpdateUpStreamCallback : nsISupports
|
||||
/**
|
||||
* Provide network services.
|
||||
*/
|
||||
[scriptable, uuid(c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c)]
|
||||
[scriptable, uuid(baec696c-c78d-42db-8b44-603f8fbfafb4)]
|
||||
interface nsINetworkService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -295,6 +295,32 @@ interface nsINetworkService : nsISupports
|
||||
*/
|
||||
void removeHostRouteWithResolve(in nsINetworkInterface network, in jsval hosts);
|
||||
|
||||
/**
|
||||
* Add route to secondary routing table.
|
||||
*
|
||||
* @param interfaceName
|
||||
* The network interface for this route.
|
||||
* @param route
|
||||
* The route info should have the following fields:
|
||||
* .ip: destination ip address
|
||||
* .prefix: destination prefix
|
||||
* .gateway: gateway ip address
|
||||
*/
|
||||
void addSecondaryRoute(in DOMString interfaceName, in jsval route);
|
||||
|
||||
/**
|
||||
* Remove route from secondary routing table.
|
||||
*
|
||||
* @param interfaceName
|
||||
* The network interface for the route we want to remove.
|
||||
* @param route
|
||||
* The route info should have the following fields:
|
||||
* .ip: destination ip address
|
||||
* .prefix: destination prefix
|
||||
* .gateway: gateway ip address
|
||||
*/
|
||||
void removeSecondaryRoute(in DOMString interfaceName, in jsval route);
|
||||
|
||||
/**
|
||||
* Enable or disable usb rndis.
|
||||
*
|
||||
|
@ -18,6 +18,7 @@ extern "C" {
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
|
||||
namespace {
|
||||
struct NetworkInterface {
|
||||
@ -104,12 +105,11 @@ nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
|
||||
|
||||
// Get network interface list.
|
||||
std::vector<NetworkInterface> interfaces;
|
||||
if (NS_FAILED(NS_DispatchToMainThread(
|
||||
mozilla::WrapRunnableNMRet(&GetInterfaces, &interfaces, &rv),
|
||||
NS_DISPATCH_SYNC))) {
|
||||
return R_FAILED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
mozilla::SyncRunnable::DispatchToThread(
|
||||
mainThread.get(),
|
||||
mozilla::WrapRunnableNMRet(&GetInterfaces, &interfaces, &rv),
|
||||
false);
|
||||
if (NS_FAILED(rv)) {
|
||||
return R_FAILED;
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ WebappsActor.prototype = {
|
||||
reg.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aApp,
|
||||
manifest: manifest,
|
||||
manifestURL: aApp.manifestURL
|
||||
id: aApp.id
|
||||
});
|
||||
reg.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
|
Loading…
Reference in New Issue
Block a user