mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
Merge m-c to mozilla-inbound
This commit is contained in:
commit
a7fa779dc7
@ -842,6 +842,7 @@ pref("general.useragent.updates.retry", 86400); // 1 day
|
||||
pref("media.useAudioChannelService", true);
|
||||
|
||||
pref("b2g.version", @MOZ_B2G_VERSION@);
|
||||
pref("b2g.osName", @MOZ_B2G_OS_NAME@);
|
||||
|
||||
// Disable console buffering to save memory.
|
||||
pref("consoleservice.buffered", false);
|
||||
|
@ -474,13 +474,6 @@ SettingsListener.observe('debugger.remote-mode', false, function(value) {
|
||||
#endif
|
||||
});
|
||||
|
||||
// If debug access to certified apps is allowed, we need to preserve system
|
||||
// sources so that they are visible in the debugger.
|
||||
let forbidCertified =
|
||||
Services.prefs.getBoolPref('devtools.debugger.forbid-certified-apps');
|
||||
Services.prefs.setBoolPref('javascript.options.discardSystemSource',
|
||||
forbidCertified);
|
||||
|
||||
// =================== Device Storage ====================
|
||||
SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
|
||||
if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {
|
||||
|
@ -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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
|
||||
|
@ -17,7 +17,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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
|
||||
@ -131,6 +131,6 @@
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="07f695559cf1834e908fce0ec2a8531582369bac"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="bc70af75eac79073c4c935bf1f71c0cb10e821b7"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="83e1560bef0988bbdec49d15cb8eef402857d4ef"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="f620016437dd2f050e044eccef5e70e3f689ccbe"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||
</manifest>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
|
@ -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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
|
||||
@ -141,7 +141,7 @@
|
||||
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
||||
<project name="platform/system/core" path="system/core" revision="e284280277c1312017a9450956a9676584441cdf"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="83e1560bef0988bbdec49d15cb8eef402857d4ef"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="f620016437dd2f050e044eccef5e70e3f689ccbe"/>
|
||||
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="b3001d5f1686f89995b7bf70963cf69c8faebd83"/>
|
||||
</manifest>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "d390f67c5661d9c4846eeeccd74385c033ebdeef",
|
||||
"revision": "16395cc21812c26f896ad2fc9931acc8ca83a50c",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -15,7 +15,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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -17,7 +17,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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -17,7 +17,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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
|
||||
@ -127,7 +127,7 @@
|
||||
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="83e1560bef0988bbdec49d15cb8eef402857d4ef"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="f620016437dd2f050e044eccef5e70e3f689ccbe"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||
|
@ -17,7 +17,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="4af716f09747edfbea637f5b60f7fd7d0183f19b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cfc40f41bf417c2d242033fefd53b7aa3f3bf71c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -635,7 +635,7 @@
|
||||
<method name="handleEvent">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
if (aEvent.type == "resize" && aEvent.eventPhase == aEvent.BUBBLING_PHASE) {
|
||||
if (aEvent.type == "resize") {
|
||||
this.resize();
|
||||
}
|
||||
]]></body>
|
||||
@ -682,10 +682,10 @@
|
||||
this.nub.removeAttribute("activity");
|
||||
]]></handler>
|
||||
<handler event="load"><![CDATA[
|
||||
window.addEventListener("resize", this);
|
||||
window.addEventListener("resize", this, true);
|
||||
]]></handler>
|
||||
<handler event="unload"><![CDATA[
|
||||
window.removeEventListener("resize", this);
|
||||
window.removeEventListener("resize", this, true);
|
||||
]]></handler>
|
||||
|
||||
<handler event="dragstart"><![CDATA[
|
||||
|
@ -514,23 +514,19 @@ function resizeWindowToChatAreaWidth(desired, cb, count = 0) {
|
||||
return;
|
||||
}
|
||||
function resize_handler(event) {
|
||||
// for whatever reason, sometimes we get called twice for different event
|
||||
// phases, only handle one of them.
|
||||
if (event.eventPhase != event.AT_TARGET)
|
||||
return;
|
||||
// we did resize - but did we get far enough to be able to continue?
|
||||
let newSize = window.SocialChatBar.chatbar.getBoundingClientRect().width;
|
||||
let sizedOk = widthDeltaCloseEnough(newSize - desired);
|
||||
if (!sizedOk)
|
||||
return;
|
||||
window.removeEventListener("resize", resize_handler);
|
||||
window.removeEventListener("resize", resize_handler, true);
|
||||
info(count + ": resized window width is " + newSize);
|
||||
executeSoon(function() {
|
||||
cb(sizedOk);
|
||||
});
|
||||
}
|
||||
// Otherwise we request resize and expect a resize event
|
||||
window.addEventListener("resize", resize_handler);
|
||||
window.addEventListener("resize", resize_handler, true);
|
||||
window.resizeBy(delta, 0);
|
||||
}
|
||||
|
||||
|
@ -772,8 +772,6 @@ BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||
|
||||
BluetoothValue v = InfallibleTArray<BluetoothNamedValue>();
|
||||
|
||||
BT_APPEND_NAMED_VALUE(v.get_ArrayOfBluetoothNamedValue(),
|
||||
@ -791,10 +789,7 @@ BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
|
||||
BT_APPEND_NAMED_VALUE(v.get_ArrayOfBluetoothNamedValue(),
|
||||
"Devices", sAdapterBondedAddressArray);
|
||||
|
||||
nsAutoString replyError;
|
||||
DispatchBluetoothReply(runnable.get(), v, replyError);
|
||||
|
||||
unused << runnable.forget(); // picked up in DispatchBluetoothReply
|
||||
DispatchBluetoothReply(aRunnable, v, EmptyString());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -971,7 +971,7 @@ ContactDB.prototype = {
|
||||
if (DEBUG) debug("invalidate cache");
|
||||
this.newTxn("readwrite", SAVED_GETALL_STORE_NAME, function (txn, store) {
|
||||
store.clear();
|
||||
}, aErrorCb);
|
||||
}, null, aErrorCb);
|
||||
},
|
||||
|
||||
incrementRevision: function CDB_incrementRevision(txn) {
|
||||
@ -1042,9 +1042,11 @@ ContactDB.prototype = {
|
||||
contactsArray.push(aContacts[i]);
|
||||
}
|
||||
|
||||
let contactIdsArray = contactsArray.map(function(el) el.id);
|
||||
|
||||
// save contact ids in cache
|
||||
this.newTxn("readwrite", SAVED_GETALL_STORE_NAME, function(txn, store) {
|
||||
store.put(contactsArray.map(function(el) el.id), aQuery);
|
||||
store.put(contactIdsArray, aQuery);
|
||||
}, null, aFailureCb);
|
||||
|
||||
// send full contacts
|
||||
|
@ -53,6 +53,14 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
|
||||
|
||||
ClientLayerManager::~ClientLayerManager()
|
||||
{
|
||||
ClearCachedResources();
|
||||
// Stop receiveing AsyncParentMessage at Forwarder.
|
||||
// After the call, the message is directly handled by LayerTransactionChild.
|
||||
// Basically this function should be called in ShadowLayerForwarder's
|
||||
// destructor. But when the destructor is triggered by
|
||||
// CompositorChild::Destroy(), the destructor can not handle it correctly.
|
||||
// See Bug 1000525.
|
||||
mForwarder->StopReceiveAsyncParentMessge();
|
||||
mRoot = nullptr;
|
||||
|
||||
MOZ_COUNT_DTOR(ClientLayerManager);
|
||||
@ -266,9 +274,7 @@ ClientLayerManager::GetRemoteRenderer()
|
||||
void
|
||||
ClientLayerManager::Composite()
|
||||
{
|
||||
if (LayerTransactionChild* manager = mForwarder->GetShadowManager()) {
|
||||
manager->SendForceComposite();
|
||||
}
|
||||
mForwarder->Composite();
|
||||
}
|
||||
|
||||
void
|
||||
@ -428,6 +434,7 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
}
|
||||
|
||||
mForwarder->RemoveTexturesIfNecessary();
|
||||
mForwarder->SendPendingAsyncMessge();
|
||||
mPhase = PHASE_NONE;
|
||||
|
||||
// this may result in Layers being deleted, which results in
|
||||
@ -498,9 +505,7 @@ void
|
||||
ClientLayerManager::ClearCachedResources(Layer* aSubtree)
|
||||
{
|
||||
MOZ_ASSERT(!HasShadowManager() || !aSubtree);
|
||||
if (LayerTransactionChild* manager = mForwarder->GetShadowManager()) {
|
||||
manager->SendClearCachedResources();
|
||||
}
|
||||
mForwarder->ClearCachedResources();
|
||||
if (aSubtree) {
|
||||
ClearLayer(aSubtree);
|
||||
} else if (mRoot) {
|
||||
|
@ -90,17 +90,9 @@ public:
|
||||
|
||||
bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
||||
bool RecvCompositorRecycle(const MaybeFenceHandle& aFence)
|
||||
bool RecvCompositorRecycle()
|
||||
{
|
||||
RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
|
||||
if (aFence.type() != aFence.Tnull_t) {
|
||||
FenceHandle fence = aFence.get_FenceHandle();
|
||||
if (fence.IsValid() && mTextureClient) {
|
||||
mTextureClient->SetReleaseFenceHandle(aFence);
|
||||
// HWC might not provide Fence.
|
||||
// In this case, HWC implicitly handles buffer's fence.
|
||||
}
|
||||
}
|
||||
mWaitForRecycle = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "gfx2DGlue.h" // for ToIntSize
|
||||
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
|
||||
#include "mozilla/ipc/Shmem.h" // for Shmem
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
|
||||
#include "mozilla/layers/CompositableTransactionParent.h" // for CompositableParentManager
|
||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
@ -36,6 +38,36 @@ struct nsIntPoint;
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
// FenceDeliveryTracker puts off releasing a Fence until a transaction complete.
|
||||
class FenceDeliveryTracker : public AsyncTransactionTracker {
|
||||
public:
|
||||
FenceDeliveryTracker(const android::sp<android::Fence>& aFence)
|
||||
: mFence(aFence)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FenceDeliveryTracker);
|
||||
}
|
||||
|
||||
~FenceDeliveryTracker()
|
||||
{
|
||||
MOZ_COUNT_DTOR(FenceDeliveryTracker);
|
||||
}
|
||||
|
||||
virtual void Complete() MOZ_OVERRIDE
|
||||
{
|
||||
mFence = nullptr;
|
||||
}
|
||||
|
||||
virtual void Cancel() MOZ_OVERRIDE
|
||||
{
|
||||
mFence = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
android::sp<android::Fence> mFence;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TextureParent is the host-side IPDL glue between TextureClient and TextureHost.
|
||||
* It is an IPDL actor just like LayerParent, CompositableParent, etc.
|
||||
@ -43,7 +75,7 @@ namespace layers {
|
||||
class TextureParent : public PTextureParent
|
||||
{
|
||||
public:
|
||||
TextureParent(ISurfaceAllocator* aAllocator);
|
||||
TextureParent(CompositableParentManager* aManager);
|
||||
|
||||
~TextureParent();
|
||||
|
||||
@ -61,24 +93,24 @@ public:
|
||||
|
||||
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
||||
ISurfaceAllocator* mAllocator;
|
||||
CompositableParentManager* mCompositableManager;
|
||||
RefPtr<TextureHost> mWaitForClientRecycle;
|
||||
RefPtr<TextureHost> mTextureHost;
|
||||
};
|
||||
|
||||
// static
|
||||
PTextureParent*
|
||||
TextureHost::CreateIPDLActor(ISurfaceAllocator* aAllocator,
|
||||
TextureHost::CreateIPDLActor(CompositableParentManager* aManager,
|
||||
const SurfaceDescriptor& aSharedData,
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorMemory &&
|
||||
!aAllocator->IsSameProcess())
|
||||
!aManager->IsSameProcess())
|
||||
{
|
||||
NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
|
||||
return nullptr;
|
||||
}
|
||||
TextureParent* actor = new TextureParent(aAllocator);
|
||||
TextureParent* actor = new TextureParent(aManager);
|
||||
if (!actor->Init(aSharedData, aFlags)) {
|
||||
delete actor;
|
||||
return nullptr;
|
||||
@ -604,8 +636,8 @@ size_t MemoryTextureHost::GetBufferSize()
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
TextureParent::TextureParent(ISurfaceAllocator* aAllocator)
|
||||
: mAllocator(aAllocator)
|
||||
TextureParent::TextureParent(CompositableParentManager* aCompositableManager)
|
||||
: mCompositableManager(aCompositableManager)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextureParent);
|
||||
}
|
||||
@ -628,23 +660,25 @@ TextureParent::CompositorRecycle()
|
||||
{
|
||||
mTextureHost->ClearRecycleCallback();
|
||||
|
||||
MaybeFenceHandle handle = null_t();
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
if (mTextureHost) {
|
||||
TextureHostOGL* hostOGL = mTextureHost->AsHostOGL();
|
||||
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
|
||||
if (fence.get() && fence->isValid()) {
|
||||
handle = FenceHandle(fence);
|
||||
// HWC might not provide Fence.
|
||||
// In this case, HWC implicitly handles buffer's fence.
|
||||
|
||||
FenceHandle handle = FenceHandle(fence);
|
||||
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
|
||||
mCompositableManager->SendFenceHandle(tracker, this, handle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mozilla::unused << SendCompositorRecycle(handle);
|
||||
|
||||
// Don't forget to prepare for the next reycle
|
||||
// if TextureClient request it.
|
||||
if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
|
||||
mozilla::unused << SendCompositorRecycle();
|
||||
// Don't forget to prepare for the next reycle
|
||||
// if TextureClient request it.
|
||||
mWaitForClientRecycle = mTextureHost;
|
||||
}
|
||||
}
|
||||
@ -667,7 +701,7 @@ TextureParent::Init(const SurfaceDescriptor& aSharedData,
|
||||
const TextureFlags& aFlags)
|
||||
{
|
||||
mTextureHost = TextureHost::Create(aSharedData,
|
||||
mAllocator,
|
||||
mCompositableManager,
|
||||
aFlags);
|
||||
if (mTextureHost) {
|
||||
mTextureHost->mActor = this;
|
||||
|
@ -41,6 +41,7 @@ namespace layers {
|
||||
class Compositor;
|
||||
class CompositableHost;
|
||||
class CompositableBackendSpecificData;
|
||||
class CompositableParentManager;
|
||||
class SurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureHostOGL;
|
||||
@ -392,7 +393,7 @@ public:
|
||||
* are for use with the managing IPDL protocols only (so that they can
|
||||
* implement AllocPTextureParent and DeallocPTextureParent).
|
||||
*/
|
||||
static PTextureParent* CreateIPDLActor(ISurfaceAllocator* aAllocator,
|
||||
static PTextureParent* CreateIPDLActor(CompositableParentManager* aManager,
|
||||
const SurfaceDescriptor& aSharedData,
|
||||
TextureFlags aFlags);
|
||||
static bool DestroyIPDLActor(PTextureParent* actor);
|
||||
|
129
gfx/layers/ipc/AsyncTransactionTracker.cpp
Normal file
129
gfx/layers/ipc/AsyncTransactionTracker.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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/. */
|
||||
|
||||
#include "AsyncTransactionTracker.h"
|
||||
|
||||
#include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
uint64_t AsyncTransactionTracker::sSerialCounter(0);
|
||||
Mutex* AsyncTransactionTracker::sLock = nullptr;
|
||||
|
||||
AsyncTransactionTracker::AsyncTransactionTracker()
|
||||
: mSerial(GetNextSerial())
|
||||
, mCompletedMonitor("AsyncTransactionTracker.mCompleted")
|
||||
, mCompleted(false)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncTransactionTracker::~AsyncTransactionTracker()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTracker::WaitComplete()
|
||||
{
|
||||
MOZ_ASSERT(!InImageBridgeChildThread());
|
||||
|
||||
MonitorAutoLock mon(mCompletedMonitor);
|
||||
int count = 0;
|
||||
while (!mCompleted) {
|
||||
if (!NS_SUCCEEDED(mCompletedMonitor.Wait(PR_MillisecondsToInterval(10000)))) {
|
||||
NS_WARNING("Failed to wait Monitor");
|
||||
return;
|
||||
}
|
||||
if (count > 1) {
|
||||
NS_WARNING("Waiting async transaction complete.");
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTracker::NotifyComplete()
|
||||
{
|
||||
MonitorAutoLock mon(mCompletedMonitor);
|
||||
MOZ_ASSERT(!mCompleted);
|
||||
mCompleted = true;
|
||||
Complete();
|
||||
mCompletedMonitor.Notify();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTracker::NotifyCancel()
|
||||
{
|
||||
MonitorAutoLock mon(mCompletedMonitor);
|
||||
MOZ_ASSERT(!mCompleted);
|
||||
mCompleted = true;
|
||||
Cancel();
|
||||
mCompletedMonitor.Notify();
|
||||
}
|
||||
|
||||
AsyncTransactionTrackersHolder::AsyncTransactionTrackersHolder()
|
||||
: mIsTrackersHolderDestroyed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(AsyncTransactionTrackersHolder);
|
||||
}
|
||||
|
||||
AsyncTransactionTrackersHolder::~AsyncTransactionTrackersHolder()
|
||||
{
|
||||
if (!mIsTrackersHolderDestroyed) {
|
||||
DestroyAsyncTransactionTrackersHolder();
|
||||
}
|
||||
MOZ_COUNT_DTOR(AsyncTransactionTrackersHolder);
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTrackersHolder::HoldUntilComplete(AsyncTransactionTracker* aTransactionTracker)
|
||||
{
|
||||
if (!aTransactionTracker) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsTrackersHolderDestroyed && aTransactionTracker) {
|
||||
aTransactionTracker->NotifyComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTransactionTracker) {
|
||||
mAsyncTransactionTrackeres[aTransactionTracker->GetId()] = aTransactionTracker;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTrackersHolder::TransactionCompleteted(uint64_t aTransactionId)
|
||||
{
|
||||
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it
|
||||
= mAsyncTransactionTrackeres.find(aTransactionId);
|
||||
if (it != mAsyncTransactionTrackeres.end()) {
|
||||
it->second->NotifyCancel();
|
||||
mAsyncTransactionTrackeres.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTrackersHolder::ClearAllAsyncTransactionTrackers()
|
||||
{
|
||||
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it;
|
||||
for (it = mAsyncTransactionTrackeres.begin();
|
||||
it != mAsyncTransactionTrackeres.end(); it++) {
|
||||
it->second->NotifyCancel();
|
||||
}
|
||||
mAsyncTransactionTrackeres.clear();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTrackersHolder::DestroyAsyncTransactionTrackersHolder() {
|
||||
mIsTrackersHolderDestroyed = true;
|
||||
ClearAllAsyncTransactionTrackers();
|
||||
}
|
||||
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
134
gfx/layers/ipc/AsyncTransactionTracker.h
Normal file
134
gfx/layers/ipc/AsyncTransactionTracker.h
Normal file
@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_layers_AsyncTransactionTracker_h
|
||||
#define mozilla_layers_AsyncTransactionTracker_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/layers/TextureClient.h" // for TextureClient
|
||||
#include "mozilla/Monitor.h" // for Monitor
|
||||
#include "mozilla/RefPtr.h" // for AtomicRefCounted
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* AsyncTransactionTracker tracks asynchronous transaction.
|
||||
* It is typically used for asynchronous layer transaction handling.
|
||||
*/
|
||||
class AsyncTransactionTracker
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncTransactionTracker)
|
||||
|
||||
AsyncTransactionTracker();
|
||||
|
||||
static void Initialize()
|
||||
{
|
||||
if (!sLock) {
|
||||
sLock = new Mutex("AsyncTransactionTracker::sLock");
|
||||
}
|
||||
}
|
||||
|
||||
static void Finalize()
|
||||
{
|
||||
if (sLock) {
|
||||
delete sLock;
|
||||
sLock = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Monitor& GetReentrantMonitor()
|
||||
{
|
||||
return mCompletedMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until asynchronous transaction complete.
|
||||
*/
|
||||
void WaitComplete();
|
||||
|
||||
/**
|
||||
* Notify async transaction complete.
|
||||
*/
|
||||
void NotifyComplete();
|
||||
|
||||
/**
|
||||
* Notify async transaction cancel.
|
||||
*/
|
||||
void NotifyCancel();
|
||||
|
||||
uint64_t GetId()
|
||||
{
|
||||
return mSerial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when asynchronous transaction complete.
|
||||
*/
|
||||
virtual void Complete()= 0;
|
||||
|
||||
/**
|
||||
* Called when asynchronous transaction is cancelled.
|
||||
* The cancel typically happens when IPC is disconnected
|
||||
*/
|
||||
virtual void Cancel()= 0;
|
||||
|
||||
virtual void SetTextureClient(TextureClient* aTextureClient) {}
|
||||
|
||||
protected:
|
||||
virtual ~AsyncTransactionTracker();
|
||||
|
||||
static uint64_t GetNextSerial()
|
||||
{
|
||||
MOZ_ASSERT(sLock);
|
||||
if(sLock) {
|
||||
sLock->Lock();
|
||||
}
|
||||
++sSerialCounter;
|
||||
if(sLock) {
|
||||
sLock->Unlock();
|
||||
}
|
||||
return sSerialCounter;
|
||||
}
|
||||
|
||||
uint64_t mSerial;
|
||||
Monitor mCompletedMonitor;
|
||||
bool mCompleted;
|
||||
|
||||
/**
|
||||
* gecko does not provide atomic operation for uint64_t.
|
||||
* Ensure atomicity by using Mutex.
|
||||
*/
|
||||
static uint64_t sSerialCounter;
|
||||
static Mutex* sLock;
|
||||
};
|
||||
|
||||
class AsyncTransactionTrackersHolder
|
||||
{
|
||||
public:
|
||||
AsyncTransactionTrackersHolder();
|
||||
virtual ~AsyncTransactionTrackersHolder();
|
||||
|
||||
void HoldUntilComplete(AsyncTransactionTracker* aTransactionTracker);
|
||||
|
||||
void TransactionCompleteted(uint64_t aTransactionId);
|
||||
|
||||
protected:
|
||||
void ClearAllAsyncTransactionTrackers();
|
||||
|
||||
void DestroyAsyncTransactionTrackersHolder();
|
||||
|
||||
bool mIsTrackersHolderDestroyed;
|
||||
std::map<uint64_t, RefPtr<AsyncTransactionTracker> > mAsyncTransactionTrackeres;
|
||||
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_AsyncTransactionTracker_h
|
@ -139,6 +139,16 @@ public:
|
||||
mTexturesToRemove.Clear();
|
||||
}
|
||||
|
||||
virtual void HoldTransactionsToRespond(uint64_t aTransactionId)
|
||||
{
|
||||
mTransactionsToRespond.push_back(aTransactionId);
|
||||
}
|
||||
|
||||
virtual void ClearTransactionsToRespond()
|
||||
{
|
||||
mTransactionsToRespond.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the CompositableHost on the compositor side what texture to use for
|
||||
* the next composition.
|
||||
@ -196,6 +206,7 @@ public:
|
||||
protected:
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
|
||||
std::vector<uint64_t> mTransactionsToRespond;
|
||||
const int32_t mSerial;
|
||||
static mozilla::Atomic<int32_t> sSerialCounter;
|
||||
};
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
|
||||
#include "mozilla/layers/ThebesLayerComposite.h"
|
||||
#include "mozilla/mozalloc.h" // for operator delete
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <vector> // for vector
|
||||
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
|
||||
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
|
||||
#include "mozilla/layers/LayersMessages.h" // for EditReply, etc
|
||||
|
||||
@ -17,6 +18,7 @@ namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CompositableHost;
|
||||
class PTextureChild;
|
||||
|
||||
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
|
||||
|
||||
@ -25,7 +27,13 @@ typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
|
||||
// so both manager protocols implement this and we keep a reference to them
|
||||
// through this interface.
|
||||
class CompositableParentManager : public ISurfaceAllocator
|
||||
, public AsyncTransactionTrackersHolder
|
||||
{
|
||||
public:
|
||||
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
|
||||
PTextureParent* aTexture,
|
||||
const FenceHandle& aFence) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handle the IPDL messages that affect PCompositable actors.
|
||||
|
@ -474,6 +474,7 @@ ImageBridgeChild::EndTransaction()
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
}
|
||||
SendPendingAsyncMessge();
|
||||
}
|
||||
|
||||
|
||||
@ -751,6 +752,29 @@ ImageBridgeChild::DeallocPTextureChild(PTextureChild* actor)
|
||||
return TextureClient::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeChild::RecvParentAsyncMessage(const mozilla::layers::AsyncParentMessageData& aMessage)
|
||||
{
|
||||
switch (aMessage.type()) {
|
||||
case AsyncParentMessageData::TOpDeliverFence: {
|
||||
const OpDeliverFence& op = aMessage.get_OpDeliverFence();
|
||||
FenceHandle fence = op.fence();
|
||||
PTextureChild* child = op.textureChild();
|
||||
|
||||
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
|
||||
if (texture) {
|
||||
texture->SetReleaseFenceHandle(fence);
|
||||
}
|
||||
HoldTransactionsToRespond(op.transactionId());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncParentMessageData type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PTextureChild*
|
||||
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
TextureFlags aFlags)
|
||||
@ -809,5 +833,21 @@ bool ImageBridgeChild::IsSameProcess() const
|
||||
return OtherProcess() == ipc::kInvalidProcessHandle;
|
||||
}
|
||||
|
||||
void ImageBridgeChild::SendPendingAsyncMessge()
|
||||
{
|
||||
if (!IsCreated() ||
|
||||
mTransactionsToRespond.empty()) {
|
||||
return;
|
||||
}
|
||||
// Send OpReplyDeliverFence messages
|
||||
InfallibleTArray<AsyncChildMessageData> replies;
|
||||
replies.SetCapacity(mTransactionsToRespond.size());
|
||||
for (size_t i = 0; i < mTransactionsToRespond.size(); i++) {
|
||||
replies.AppendElement(OpReplyDeliverFence(mTransactionsToRespond[i]));
|
||||
}
|
||||
mTransactionsToRespond.clear();
|
||||
SendChildAsyncMessages(replies);
|
||||
}
|
||||
|
||||
} // layers
|
||||
} // mozilla
|
||||
|
@ -192,6 +192,9 @@ public:
|
||||
virtual bool
|
||||
DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvParentAsyncMessage(const mozilla::layers::AsyncParentMessageData& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
TemporaryRef<ImageClient> CreateImageClient(CompositableType aType);
|
||||
TemporaryRef<ImageClient> CreateImageClientNow(CompositableType aType);
|
||||
|
||||
@ -302,6 +305,8 @@ public:
|
||||
|
||||
virtual bool IsSameProcess() const MOZ_OVERRIDE;
|
||||
|
||||
void SendPendingAsyncMessge();
|
||||
|
||||
protected:
|
||||
ImageBridgeChild();
|
||||
bool DispatchAllocShmemInternal(size_t aSize,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "mozilla/layers/PImageBridgeParent.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsDebug.h" // for NS_RUNTIMEABORT, etc
|
||||
#include "nsISupportsImpl.h" // for ImageBridgeParent::Release, etc
|
||||
@ -186,6 +187,37 @@ ImageBridgeParent::DeallocPTextureParent(PTextureParent* actor)
|
||||
return TextureHost::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
|
||||
PTextureParent* aTexture,
|
||||
const FenceHandle& aFence)
|
||||
{
|
||||
HoldUntilComplete(aTracker);
|
||||
mozilla::unused << SendParentAsyncMessage(OpDeliverFence(aTracker->GetId(),
|
||||
aTexture, nullptr,
|
||||
aFence));
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeParent::RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages)
|
||||
{
|
||||
for (AsyncChildMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
|
||||
const AsyncChildMessageData& message = aMessages[i];
|
||||
|
||||
switch (message.type()) {
|
||||
case AsyncChildMessageData::TOpReplyDeliverFence: {
|
||||
const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
|
||||
TransactionCompleteted(op.transactionId());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncChildMessageData type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MessageLoop * ImageBridgeParent::GetMessageLoop() {
|
||||
return mMessageLoop;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ class ImageBridgeParent : public PImageBridgeParent,
|
||||
public:
|
||||
typedef InfallibleTArray<CompositableOperation> EditArray;
|
||||
typedef InfallibleTArray<EditReply> EditReplyArray;
|
||||
typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
|
||||
|
||||
ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport);
|
||||
~ImageBridgeParent();
|
||||
@ -53,6 +54,11 @@ public:
|
||||
static PImageBridgeParent*
|
||||
Create(Transport* aTransport, ProcessId aOtherProcess);
|
||||
|
||||
// CompositableParentManager
|
||||
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
|
||||
PTextureParent* aTexture,
|
||||
const FenceHandle& aFence) MOZ_OVERRIDE;
|
||||
|
||||
// PImageBridge
|
||||
virtual bool RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply) MOZ_OVERRIDE;
|
||||
virtual bool RecvUpdateNoSwap(const EditArray& aEdits) MOZ_OVERRIDE;
|
||||
@ -67,6 +73,9 @@ public:
|
||||
const TextureFlags& aFlags) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages) MOZ_OVERRIDE;
|
||||
|
||||
bool RecvStop() MOZ_OVERRIDE;
|
||||
|
||||
MessageLoop * GetMessageLoop();
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableChild
|
||||
#include "mozilla/layers/PCompositableChild.h" // for PCompositableChild
|
||||
#include "mozilla/layers/PLayerChild.h" // for PLayerChild
|
||||
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "nsDebug.h" // for NS_RUNTIMEABORT, etc
|
||||
#include "nsTArray.h" // for nsTArray
|
||||
@ -55,6 +56,36 @@ LayerTransactionChild::DeallocPCompositableChild(PCompositableChild* actor)
|
||||
return CompositableClient::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionChild::RecvParentAsyncMessage(const mozilla::layers::AsyncParentMessageData& aMessage)
|
||||
{
|
||||
switch (aMessage.type()) {
|
||||
case AsyncParentMessageData::TOpDeliverFence: {
|
||||
const OpDeliverFence& op = aMessage.get_OpDeliverFence();
|
||||
FenceHandle fence = op.fence();
|
||||
PTextureChild* child = op.textureChild();
|
||||
|
||||
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
|
||||
if (texture) {
|
||||
texture->SetReleaseFenceHandle(fence);
|
||||
}
|
||||
if (mForwarder) {
|
||||
mForwarder->HoldTransactionsToRespond(op.transactionId());
|
||||
} else {
|
||||
// Send back a response.
|
||||
InfallibleTArray<AsyncChildMessageData> replies;
|
||||
replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
|
||||
SendChildAsyncMessages(replies);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncParentMessageData type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -18,6 +18,7 @@ namespace mozilla {
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameChild;
|
||||
class ShadowLayerForwarder;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
@ -37,6 +38,11 @@ public:
|
||||
|
||||
bool IPCOpen() const { return mIPCOpen; }
|
||||
|
||||
void SetForwarder(ShadowLayerForwarder* aForwarder)
|
||||
{
|
||||
mForwarder = aForwarder;
|
||||
}
|
||||
|
||||
protected:
|
||||
LayerTransactionChild()
|
||||
: mIPCOpen(false)
|
||||
@ -53,6 +59,9 @@ protected:
|
||||
const TextureFlags& aFlags) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvParentAsyncMessage(const mozilla::layers::AsyncParentMessageData& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
||||
void AddIPDLReference() {
|
||||
@ -69,6 +78,7 @@ protected:
|
||||
friend class layout::RenderFrameChild;
|
||||
|
||||
bool mIPCOpen;
|
||||
ShadowLayerForwarder* mForwarder;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "mozilla/layers/PLayerParent.h" // for PLayerParent
|
||||
#include "mozilla/layers/ThebesLayerComposite.h"
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsCoord.h" // for NSAppUnitsToFloatPixels
|
||||
#include "nsDebug.h" // for NS_RUNTIMEABORT
|
||||
#include "nsDeviceContext.h" // for AppUnitsPerCSSPixel
|
||||
@ -174,13 +175,6 @@ LayerTransactionParent::GetCompositorBackendType() const
|
||||
return mLayerManager->GetBackendType();
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
void
|
||||
LayerTransactionParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
// Implement me! Bug 1005171
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset,
|
||||
const TargetConfig& targetConfig,
|
||||
@ -784,10 +778,47 @@ LayerTransactionParent::DeallocPTextureParent(PTextureParent* actor)
|
||||
return TextureHost::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionParent::RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages)
|
||||
{
|
||||
for (AsyncChildMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
|
||||
const AsyncChildMessageData& message = aMessages[i];
|
||||
|
||||
switch (message.type()) {
|
||||
case AsyncChildMessageData::TOpReplyDeliverFence: {
|
||||
const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
|
||||
TransactionCompleteted(op.transactionId());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncChildMessageData type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
DestroyAsyncTransactionTrackersHolder();
|
||||
}
|
||||
|
||||
bool LayerTransactionParent::IsSameProcess() const
|
||||
{
|
||||
return OtherProcess() == ipc::kInvalidProcessHandle;
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
|
||||
PTextureParent* aTexture,
|
||||
const FenceHandle& aFence)
|
||||
{
|
||||
HoldUntilComplete(aTracker);
|
||||
mozilla::unused << SendParentAsyncMessage(OpDeliverFence(aTracker->GetId(),
|
||||
aTexture, nullptr,
|
||||
aFence));
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -43,6 +43,7 @@ class LayerTransactionParent : public PLayerTransactionParent,
|
||||
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
|
||||
typedef InfallibleTArray<Edit> EditArray;
|
||||
typedef InfallibleTArray<EditReply> EditReplyArray;
|
||||
typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
|
||||
|
||||
public:
|
||||
LayerTransactionParent(LayerManagerComposite* aManager,
|
||||
@ -79,9 +80,11 @@ public:
|
||||
|
||||
virtual bool IsSameProcess() const MOZ_OVERRIDE;
|
||||
|
||||
// CompositableParentManager
|
||||
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
|
||||
PTextureParent* aTexture,
|
||||
const FenceHandle& aFence) MOZ_OVERRIDE;
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvUpdate(const EditArray& cset,
|
||||
const TargetConfig& targetConfig,
|
||||
const bool& isFirstPaint,
|
||||
@ -115,6 +118,11 @@ protected:
|
||||
const TextureFlags& aFlags) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
||||
bool Attach(ShadowLayerParent* aLayerParent,
|
||||
CompositableHost* aCompositable,
|
||||
bool aIsAsyncVideo);
|
||||
|
@ -357,6 +357,16 @@ struct OpUpdateTexture {
|
||||
MaybeRegion region;
|
||||
};
|
||||
|
||||
struct OpDeliverFence {
|
||||
uint64_t transactionId;
|
||||
PTexture texture;
|
||||
FenceHandle fence;
|
||||
};
|
||||
|
||||
struct OpReplyDeliverFence {
|
||||
uint64_t transactionId;
|
||||
};
|
||||
|
||||
union CompositableOperation {
|
||||
OpUpdatePictureRect;
|
||||
|
||||
@ -428,5 +438,13 @@ union EditReply {
|
||||
ReturnReleaseFence;
|
||||
};
|
||||
|
||||
union AsyncParentMessageData {
|
||||
OpDeliverFence;
|
||||
};
|
||||
|
||||
union AsyncChildMessageData {
|
||||
OpReplyDeliverFence;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
@ -28,6 +28,9 @@ intr protocol PImageBridge
|
||||
manages PCompositable;
|
||||
manages PTexture;
|
||||
|
||||
child:
|
||||
async ParentAsyncMessage(AsyncParentMessageData aMessage);
|
||||
|
||||
parent:
|
||||
|
||||
sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
|
||||
@ -44,6 +47,8 @@ parent:
|
||||
|
||||
sync PCompositable(TextureInfo aInfo) returns (uint64_t id);
|
||||
async PTexture(SurfaceDescriptor aSharedData, TextureFlags aTextureFlags);
|
||||
|
||||
async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
|
||||
};
|
||||
|
||||
|
||||
|
@ -41,6 +41,9 @@ sync protocol PLayerTransaction {
|
||||
manages PCompositable;
|
||||
manages PTexture;
|
||||
|
||||
child:
|
||||
async ParentAsyncMessage(AsyncParentMessageData aMessage);
|
||||
|
||||
parent:
|
||||
async PLayer();
|
||||
async PCompositable(TextureInfo aTextureInfo);
|
||||
@ -80,10 +83,12 @@ parent:
|
||||
// Drop any front buffers that might be retained on the compositor
|
||||
// side.
|
||||
async ClearCachedResources();
|
||||
|
||||
|
||||
// Schedule a composite if one isn't already scheduled.
|
||||
async ForceComposite();
|
||||
|
||||
async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
|
@ -11,16 +11,10 @@ include protocol PImageBridge;
|
||||
include "mozilla/GfxMessageUtils.h";
|
||||
|
||||
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
|
||||
using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
union MaybeFenceHandle {
|
||||
FenceHandle;
|
||||
null_t;
|
||||
};
|
||||
|
||||
/**
|
||||
* PTexture is the IPDL glue between a TextureClient and a TextureHost.
|
||||
*/
|
||||
@ -30,7 +24,7 @@ sync protocol PTexture {
|
||||
child:
|
||||
async __delete__();
|
||||
|
||||
async CompositorRecycle(MaybeFenceHandle aFence);
|
||||
async CompositorRecycle();
|
||||
|
||||
parent:
|
||||
|
||||
|
@ -177,6 +177,9 @@ ShadowLayerForwarder::~ShadowLayerForwarder()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mTxn->Finished(), "unfinished transaction?");
|
||||
delete mTxn;
|
||||
if (mShadowManager) {
|
||||
mShadowManager->SetForwarder(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -572,7 +575,8 @@ ShadowLayerForwarder::AllocShmem(size_t aSize,
|
||||
ipc::Shmem* aShmem)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager");
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return false;
|
||||
}
|
||||
return mShadowManager->AllocShmem(aSize, aType, aShmem);
|
||||
@ -583,7 +587,8 @@ ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize,
|
||||
ipc::Shmem* aShmem)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager");
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return false;
|
||||
}
|
||||
return mShadowManager->AllocUnsafeShmem(aSize, aType, aShmem);
|
||||
@ -592,7 +597,8 @@ void
|
||||
ShadowLayerForwarder::DeallocShmem(ipc::Shmem& aShmem)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager");
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
mShadowManager->DeallocShmem(aShmem);
|
||||
@ -622,7 +628,8 @@ PLayerChild*
|
||||
ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mShadowManager->SendPLayerConstructor(new ShadowLayerChild(aLayer));
|
||||
@ -645,7 +652,8 @@ ShadowLayerForwarder::Connect(CompositableClient* aCompositable)
|
||||
#endif
|
||||
MOZ_ASSERT(aCompositable);
|
||||
MOZ_ASSERT(mShadowManager);
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
PCompositableChild* actor =
|
||||
@ -687,7 +695,8 @@ PTextureChild*
|
||||
ShadowLayerForwarder::CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mShadowManager->SendPTextureConstructor(aSharedData, aFlags);
|
||||
@ -697,8 +706,54 @@ ShadowLayerForwarder::CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
void ShadowLayerForwarder::SetShadowManager(PLayerTransactionChild* aShadowManager)
|
||||
{
|
||||
mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager);
|
||||
mShadowManager->SetForwarder(this);
|
||||
}
|
||||
|
||||
void ShadowLayerForwarder::StopReceiveAsyncParentMessge()
|
||||
{
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
SendPendingAsyncMessge();
|
||||
mShadowManager->SetForwarder(nullptr);
|
||||
}
|
||||
|
||||
void ShadowLayerForwarder::ClearCachedResources()
|
||||
{
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
SendPendingAsyncMessge();
|
||||
mShadowManager->SendClearCachedResources();
|
||||
}
|
||||
|
||||
void ShadowLayerForwarder::Composite()
|
||||
{
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
mShadowManager->SendForceComposite();
|
||||
}
|
||||
|
||||
void ShadowLayerForwarder::SendPendingAsyncMessge()
|
||||
{
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen() ||
|
||||
mTransactionsToRespond.empty()) {
|
||||
return;
|
||||
}
|
||||
// Send OpReplyDeliverFence messages
|
||||
InfallibleTArray<AsyncChildMessageData> replies;
|
||||
replies.SetCapacity(mTransactionsToRespond.size());
|
||||
for (size_t i = 0; i < mTransactionsToRespond.size(); i++) {
|
||||
replies.AppendElement(OpReplyDeliverFence(mTransactionsToRespond[i]));
|
||||
}
|
||||
mTransactionsToRespond.clear();
|
||||
mShadowManager->SendChildAsyncMessages(replies);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -299,6 +299,14 @@ public:
|
||||
*/
|
||||
void SetShadowManager(PLayerTransactionChild* aShadowManager);
|
||||
|
||||
void StopReceiveAsyncParentMessge();
|
||||
|
||||
void ClearCachedResources();
|
||||
|
||||
void Composite();
|
||||
|
||||
void SendPendingAsyncMessge();
|
||||
|
||||
/**
|
||||
* True if this is forwarding to a LayerManagerComposite.
|
||||
*/
|
||||
|
@ -135,6 +135,7 @@ EXPORTS.mozilla.layers += [
|
||||
'D3D9SurfaceImage.h',
|
||||
'Effects.h',
|
||||
'ImageDataSerializer.h',
|
||||
'ipc/AsyncTransactionTracker.h',
|
||||
'ipc/CompositableForwarder.h',
|
||||
'ipc/CompositableTransactionParent.h',
|
||||
'ipc/CompositorChild.h',
|
||||
@ -273,6 +274,7 @@ UNIFIED_SOURCES += [
|
||||
'Effects.cpp',
|
||||
'ImageDataSerializer.cpp',
|
||||
'ImageLayers.cpp',
|
||||
'ipc/AsyncTransactionTracker.cpp',
|
||||
'ipc/CompositableTransactionParent.cpp',
|
||||
'ipc/CompositorChild.cpp',
|
||||
'ipc/CompositorParent.cpp',
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define FORCE_PR_LOG /* Allow logging in the release build */
|
||||
#endif
|
||||
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
|
||||
#include "mozilla/layers/CompositorChild.h"
|
||||
#include "mozilla/layers/CompositorParent.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
@ -335,6 +336,8 @@ gfxPlatform::Init()
|
||||
|
||||
gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
|
||||
|
||||
AsyncTransactionTracker::Initialize();
|
||||
|
||||
/* Initialize the GfxInfo service.
|
||||
* Note: we can't call functions on GfxInfo that depend
|
||||
* on gPlatform until after it has been initialized
|
||||
@ -505,6 +508,8 @@ gfxPlatform::Shutdown()
|
||||
#endif
|
||||
CompositorParent::ShutDown();
|
||||
|
||||
AsyncTransactionTracker::Finalize();
|
||||
|
||||
delete gGfxPlatformPrefsLock;
|
||||
|
||||
gfxPrefs::DestroySingleton();
|
||||
|
@ -219,15 +219,20 @@ public class Tab {
|
||||
return mThumbnailBitmap;
|
||||
}
|
||||
|
||||
public void updateThumbnail(final Bitmap b) {
|
||||
public void updateThumbnail(final Bitmap b, final ThumbnailHelper.CachePolicy cachePolicy) {
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (b != null) {
|
||||
try {
|
||||
mThumbnail = new BitmapDrawable(mAppContext.getResources(), b);
|
||||
if (mState == Tab.STATE_SUCCESS)
|
||||
if (mState == Tab.STATE_SUCCESS && cachePolicy == ThumbnailHelper.CachePolicy.STORE) {
|
||||
saveThumbnailToDB();
|
||||
} else {
|
||||
// If the page failed to load, or requested that we not cache info about it, clear any previous
|
||||
// thumbnails we've stored.
|
||||
clearThumbnailFromDB();
|
||||
}
|
||||
} catch (OutOfMemoryError oom) {
|
||||
Log.w(LOGTAG, "Unable to create/scale bitmap.", oom);
|
||||
mThumbnail = null;
|
||||
@ -717,6 +722,19 @@ public class Tab {
|
||||
}
|
||||
}
|
||||
|
||||
private void clearThumbnailFromDB() {
|
||||
try {
|
||||
String url = getURL();
|
||||
if (url == null)
|
||||
return;
|
||||
|
||||
// Passing in a null thumbnail will delete the stored thumbnail for this url
|
||||
BrowserDB.updateThumbnailForUrl(getContentResolver(), url, null);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void addPluginView(View view) {
|
||||
mPluginViews.add(view);
|
||||
}
|
||||
|
@ -33,6 +33,11 @@ public final class ThumbnailHelper {
|
||||
|
||||
public static final float THUMBNAIL_ASPECT_RATIO = 0.571f; // this is a 4:7 ratio (as per UX decision)
|
||||
|
||||
public static enum CachePolicy {
|
||||
STORE,
|
||||
NO_STORE
|
||||
}
|
||||
|
||||
// static singleton stuff
|
||||
|
||||
private static ThumbnailHelper sInstance;
|
||||
@ -63,7 +68,7 @@ public final class ThumbnailHelper {
|
||||
|
||||
public void getAndProcessThumbnailFor(Tab tab) {
|
||||
if (AboutPages.isAboutHome(tab.getURL())) {
|
||||
tab.updateThumbnail(null);
|
||||
tab.updateThumbnail(null, CachePolicy.NO_STORE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -72,7 +77,8 @@ public final class ThumbnailHelper {
|
||||
if (url != null) {
|
||||
byte[] thumbnail = BrowserDB.getThumbnailForUrl(GeckoAppShell.getContext().getContentResolver(), url);
|
||||
if (thumbnail != null) {
|
||||
setTabThumbnail(tab, null, thumbnail);
|
||||
// Since this thumbnail is from the database, its ok to store it
|
||||
setTabThumbnail(tab, null, thumbnail, CachePolicy.STORE);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -155,11 +161,11 @@ public final class ThumbnailHelper {
|
||||
|
||||
/* This method is invoked by JNI once the thumbnail data is ready. */
|
||||
@WrapElementForJNI(stubName = "SendThumbnail")
|
||||
public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success) {
|
||||
public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success, boolean shouldStore) {
|
||||
Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
ThumbnailHelper helper = ThumbnailHelper.getInstance();
|
||||
if (success && tab != null) {
|
||||
helper.handleThumbnailData(tab, data);
|
||||
helper.handleThumbnailData(tab, data, shouldStore ? CachePolicy.STORE : CachePolicy.NO_STORE);
|
||||
}
|
||||
helper.processNextThumbnail(tab);
|
||||
}
|
||||
@ -181,7 +187,7 @@ public final class ThumbnailHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleThumbnailData(Tab tab, ByteBuffer data) {
|
||||
private void handleThumbnailData(Tab tab, ByteBuffer data, CachePolicy cachePolicy) {
|
||||
Log.d(LOGTAG, "handleThumbnailData: " + data.capacity());
|
||||
if (data != mBuffer) {
|
||||
// This should never happen, but log it and recover gracefully
|
||||
@ -189,18 +195,18 @@ public final class ThumbnailHelper {
|
||||
}
|
||||
|
||||
if (shouldUpdateThumbnail(tab)) {
|
||||
processThumbnailData(tab, data);
|
||||
processThumbnailData(tab, data, cachePolicy);
|
||||
}
|
||||
}
|
||||
|
||||
private void processThumbnailData(Tab tab, ByteBuffer data) {
|
||||
private void processThumbnailData(Tab tab, ByteBuffer data, CachePolicy cachePolicy) {
|
||||
Bitmap b = tab.getThumbnailBitmap(mWidth, mHeight);
|
||||
data.position(0);
|
||||
b.copyPixelsFromBuffer(data);
|
||||
setTabThumbnail(tab, b, null);
|
||||
setTabThumbnail(tab, b, null, cachePolicy);
|
||||
}
|
||||
|
||||
private void setTabThumbnail(Tab tab, Bitmap bitmap, byte[] compressed) {
|
||||
private void setTabThumbnail(Tab tab, Bitmap bitmap, byte[] compressed, CachePolicy cachePolicy) {
|
||||
if (bitmap == null) {
|
||||
if (compressed == null) {
|
||||
Log.w(LOGTAG, "setTabThumbnail: one of bitmap or compressed must be non-null!");
|
||||
@ -208,7 +214,7 @@ public final class ThumbnailHelper {
|
||||
}
|
||||
bitmap = BitmapUtils.decodeByteArray(compressed);
|
||||
}
|
||||
tab.updateThumbnail(bitmap);
|
||||
tab.updateThumbnail(bitmap, cachePolicy);
|
||||
}
|
||||
|
||||
private boolean shouldUpdateThumbnail(Tab tab) {
|
||||
|
@ -838,6 +838,13 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
||||
@Override
|
||||
public void updateThumbnailForUrl(ContentResolver cr, String uri,
|
||||
BitmapDrawable thumbnail) {
|
||||
|
||||
// If a null thumbnail was passed in, delete the stored thumbnail for this url.
|
||||
if (thumbnail == null) {
|
||||
cr.delete(mThumbnailsUriWithProfile, Thumbnails.URL + " == ?", new String[] { uri });
|
||||
return;
|
||||
}
|
||||
|
||||
Bitmap bitmap = thumbnail.getBitmap();
|
||||
|
||||
byte[] data = null;
|
||||
@ -849,8 +856,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Thumbnails.DATA, data);
|
||||
values.put(Thumbnails.URL, uri);
|
||||
values.put(Thumbnails.DATA, data);
|
||||
|
||||
Uri thumbnailsUri = mThumbnailsUriWithProfile.buildUpon().
|
||||
appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
|
||||
|
@ -10,6 +10,7 @@ pref("datareporting.policy.dataSubmissionPolicyResponseType", "");
|
||||
pref("datareporting.policy.dataSubmissionPolicyResponseTime", "0");
|
||||
pref("datareporting.policy.firstRunTime", "0");
|
||||
|
||||
pref("datareporting.policy.currentPolicyVersion", 2);
|
||||
pref("datareporting.policy.minimumPolicyVersion", 1);
|
||||
pref("datareporting.policy.minimumPolicyVersion.channel-beta", 2);
|
||||
|
||||
|
@ -38,8 +38,6 @@ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
// implemented in 2012, so any earlier dates indicate an incorrect clock.
|
||||
const OLDEST_ALLOWED_YEAR = 2012;
|
||||
|
||||
const CURRENT_POLICY_VERSION = 2;
|
||||
|
||||
/**
|
||||
* Represents a request to display data policy.
|
||||
*
|
||||
@ -292,8 +290,19 @@ this.DataReportingPolicy = function (prefs, healthReportPrefs, listener) {
|
||||
this._healthReportPrefs = healthReportPrefs;
|
||||
this._listener = listener;
|
||||
|
||||
// If we've never run before, record the current time.
|
||||
if (!this.firstRunDate.getTime()) {
|
||||
// If the policy version has changed, reset all preferences, so that
|
||||
// the notification reappears.
|
||||
let acceptedVersion = this._prefs.get("dataSubmissionPolicyAcceptedVersion");
|
||||
if (typeof(acceptedVersion) == "number" &&
|
||||
acceptedVersion < this.minimumPolicyVersion) {
|
||||
this._log.info("policy version has changed - resetting all prefs");
|
||||
// We don't want to delay the notification in this case.
|
||||
let firstRunToRestore = this.firstRunDate;
|
||||
this._prefs.resetBranch();
|
||||
this.firstRunDate = firstRunToRestore.getTime() ?
|
||||
firstRunToRestore : this.now();
|
||||
} else if (!this.firstRunDate.getTime()) {
|
||||
// If we've never run before, record the current time.
|
||||
this.firstRunDate = this.now();
|
||||
}
|
||||
|
||||
@ -517,20 +526,17 @@ this.DataReportingPolicy.prototype = Object.freeze({
|
||||
*/
|
||||
get dataSubmissionPolicyAccepted() {
|
||||
// Be conservative and default to false.
|
||||
let enabled = this._prefs.get("dataSubmissionPolicyAccepted", false);
|
||||
if (!enabled)
|
||||
return false;
|
||||
|
||||
let acceptedVersion = this._prefs.get("dataSubmissionPolicyAcceptedVersion");
|
||||
return acceptedVersion >= this.minimumPolicyVersion;
|
||||
return this._prefs.get("dataSubmissionPolicyAccepted", false);
|
||||
},
|
||||
|
||||
set dataSubmissionPolicyAccepted(value) {
|
||||
this._prefs.set("dataSubmissionPolicyAccepted", !!value);
|
||||
if (!!value)
|
||||
this._prefs.set("dataSubmissionPolicyAcceptedVersion", CURRENT_POLICY_VERSION);
|
||||
else
|
||||
if (!!value) {
|
||||
let currentPolicyVersion = this._prefs.get("currentPolicyVersion", 1);
|
||||
this._prefs.set("dataSubmissionPolicyAcceptedVersion", currentPolicyVersion);
|
||||
} else {
|
||||
this._prefs.reset("dataSubmissionPolicyAcceptedVersion");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -8,10 +8,26 @@ const {utils: Cu} = Components;
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
|
||||
Cu.import("resource://testing-common/services/datareporting/mocks.jsm");
|
||||
Cu.import("resource://gre/modules/UpdateChannel.jsm");
|
||||
|
||||
|
||||
function getPolicy(name) {
|
||||
function getPolicy(name,
|
||||
aCurrentPolicyVersion = 1,
|
||||
aMinimumPolicyVersion = 1,
|
||||
aBranchMinimumVersionOverride) {
|
||||
let branch = "testing.datareporting." + name;
|
||||
|
||||
// The version prefs should not be removed on reset, so set them in the
|
||||
// default branch.
|
||||
let defaultPolicyPrefs = new Preferences({ branch: branch + ".policy."
|
||||
, defaultBranch: true });
|
||||
defaultPolicyPrefs.set("currentPolicyVersion", aCurrentPolicyVersion);
|
||||
defaultPolicyPrefs.set("minimumPolicyVersion", aMinimumPolicyVersion);
|
||||
let branchOverridePrefName = "minimumPolicyVersion.channel-" + UpdateChannel.get(false);
|
||||
if (aBranchMinimumVersionOverride !== undefined)
|
||||
defaultPolicyPrefs.set(branchOverridePrefName, aBranchMinimumVersionOverride);
|
||||
else
|
||||
defaultPolicyPrefs.reset(branchOverridePrefName);
|
||||
|
||||
let policyPrefs = new Preferences(branch + ".policy.");
|
||||
let healthReportPrefs = new Preferences(branch + ".healthreport.");
|
||||
|
||||
@ -776,3 +792,72 @@ add_test(function test_pref_change_initiates_deletion() {
|
||||
hrPrefs.set("uploadEnabled", false);
|
||||
});
|
||||
|
||||
add_task(function* test_policy_version() {
|
||||
let policy, policyPrefs, hrPrefs, listener, now, firstRunTime;
|
||||
function createPolicy(shouldBeAccepted = false,
|
||||
currentPolicyVersion = 1, minimumPolicyVersion = 1,
|
||||
branchMinimumVersionOverride) {
|
||||
[policy, policyPrefs, hrPrefs, listener] =
|
||||
getPolicy("policy_version_test", currentPolicyVersion,
|
||||
minimumPolicyVersion, branchMinimumVersionOverride);
|
||||
let firstRun = now === undefined;
|
||||
if (firstRun) {
|
||||
firstRunTime = policy.firstRunDate.getTime();
|
||||
do_check_true(firstRunTime > 0);
|
||||
now = new Date(policy.firstRunDate.getTime() +
|
||||
policy.SUBMISSION_NOTIFY_INTERVAL_MSEC);
|
||||
}
|
||||
else {
|
||||
// The first-run time should not be reset even after policy-version
|
||||
// upgrades.
|
||||
do_check_eq(policy.firstRunDate.getTime(), firstRunTime);
|
||||
}
|
||||
defineNow(policy, now);
|
||||
do_check_eq(policy.dataSubmissionPolicyAccepted, shouldBeAccepted);
|
||||
}
|
||||
|
||||
function* triggerPolicyCheckAndEnsureNotified(notified = true, accept = true) {
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.notifyUserCount, Number(notified));
|
||||
if (notified) {
|
||||
yield listener.lastNotifyRequest.onUserNotifyComplete();
|
||||
if (accept) {
|
||||
listener.lastNotifyRequest.onUserAccept("because,");
|
||||
do_check_true(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"),
|
||||
policyPrefs.get("currentPolicyVersion"));
|
||||
}
|
||||
else {
|
||||
do_check_false(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createPolicy();
|
||||
yield triggerPolicyCheckAndEnsureNotified();
|
||||
|
||||
// We shouldn't be notified again if the current version is still valid;
|
||||
createPolicy(true);
|
||||
yield triggerPolicyCheckAndEnsureNotified(false);
|
||||
|
||||
// Just increasing the current version isn't enough. The minimum
|
||||
// version must be changed.
|
||||
let currentPolicyVersion = policyPrefs.get("currentPolicyVersion");
|
||||
let minimumPolicyVersion = policyPrefs.get("minimumPolicyVersion");
|
||||
createPolicy(true, ++currentPolicyVersion, minimumPolicyVersion);
|
||||
yield triggerPolicyCheckAndEnsureNotified(false);
|
||||
do_check_true(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"),
|
||||
minimumPolicyVersion);
|
||||
|
||||
// Increase the minimum policy version and check if we're notified.
|
||||
createPolicy(false, currentPolicyVersion, ++minimumPolicyVersion);
|
||||
do_check_false(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
|
||||
yield triggerPolicyCheckAndEnsureNotified();
|
||||
|
||||
// Test increasing the minimum version just on the current channel.
|
||||
createPolicy(true, currentPolicyVersion, minimumPolicyVersion);
|
||||
yield triggerPolicyCheckAndEnsureNotified(false);
|
||||
createPolicy(false, ++currentPolicyVersion, minimumPolicyVersion, minimumPolicyVersion + 1);
|
||||
yield triggerPolicyCheckAndEnsureNotified(true);
|
||||
});
|
||||
|
@ -48,7 +48,7 @@ else
|
||||
fi
|
||||
|
||||
# Create a virtualenv:
|
||||
curl https://raw.github.com/pypa/virtualenv/1.9.1/virtualenv.py | ${PYTHON} - ${TARGET}
|
||||
curl -L https://raw.github.com/pypa/virtualenv/1.9.1/virtualenv.py | ${PYTHON} - ${TARGET}
|
||||
cd ${TARGET}
|
||||
. $BIN_NAME
|
||||
if [ -z "${VIRTUAL_ENV}" ]
|
||||
|
@ -11,28 +11,7 @@ const CACHE_MAX_GROUP_ENTRIES = 100;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
/**
|
||||
* Remotes the service. All the remoting/electrolysis code is in here,
|
||||
* so the regular service code below remains uncluttered and maintainable.
|
||||
*/
|
||||
function electrolify(service) {
|
||||
// FIXME: For now, use the wrappedJSObject hack, until bug
|
||||
// 593407 which will clean that up.
|
||||
// Note that we also use this in the xpcshell tests, separately.
|
||||
service.wrappedJSObject = service;
|
||||
|
||||
var appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
if (appInfo && appInfo.getService(Ci.nsIXULRuntime).processType !=
|
||||
Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT)
|
||||
{
|
||||
// Child process
|
||||
service._dbInit = function(){}; // No local DB
|
||||
}
|
||||
}
|
||||
|
||||
function ContentPrefService() {
|
||||
electrolify(this);
|
||||
|
||||
// If this throws an exception, it causes the getService call to fail,
|
||||
// but the next time a consumer tries to retrieve the service, we'll try
|
||||
// to initialize the database again, which might work if the failure
|
||||
@ -72,7 +51,6 @@ ContentPrefService.prototype = {
|
||||
QueryInterface: function CPS_QueryInterface(iid) {
|
||||
let supportedIIDs = [
|
||||
Ci.nsIContentPrefService,
|
||||
Ci.nsIFrameMessageListener,
|
||||
Ci.nsISupports,
|
||||
];
|
||||
if (supportedIIDs.some(function (i) iid.equals(i)))
|
||||
|
@ -2,5 +2,4 @@ component {e3f772f3-023f-4b32-b074-36cf0fd5d414} nsContentPrefService.js
|
||||
contract @mozilla.org/content-pref/service;1 {e3f772f3-023f-4b32-b074-36cf0fd5d414}
|
||||
component {8df290ae-dcaa-4c11-98a5-2429a4dc97bb} nsContentPrefService.js
|
||||
contract @mozilla.org/content-pref/hostname-grouper;1 {8df290ae-dcaa-4c11-98a5-2429a4dc97bb}
|
||||
category wakeup-request nsContentPrefService @mozilla.org/content-pref/service;1,nsIContentPrefService,getService,ContentPref:getPref,ContentPref:setPref
|
||||
|
||||
|
@ -322,7 +322,7 @@ Preferences.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
resetBranch: function(prefBranch) {
|
||||
resetBranch: function(prefBranch = "") {
|
||||
try {
|
||||
this._prefSvc.resetBranch(prefBranch);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
@ -40,6 +41,7 @@
|
||||
#include "NativeJSContainer.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget::android;
|
||||
@ -305,6 +307,68 @@ AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() {
|
||||
Dispose();
|
||||
}
|
||||
|
||||
// Decides if we should store thumbnails for a given docshell based on the presence
|
||||
// of a Cache-Control: no-store header and the "browser.cache.disk_cache_ssl" pref.
|
||||
static bool ShouldStoreThumbnail(nsIDocShell* docshell) {
|
||||
if (!docshell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
|
||||
docshell->GetCurrentDocumentChannel(getter_AddRefs(channel));
|
||||
if (!channel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel;
|
||||
rv = channel->QueryInterface(NS_GET_IID(nsIHttpChannel), getter_AddRefs(httpChannel));
|
||||
if (!NS_SUCCEEDED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't store thumbnails for sites that didn't load
|
||||
uint32_t responseStatus;
|
||||
rv = httpChannel->GetResponseStatus(&responseStatus);
|
||||
if (!NS_SUCCEEDED(rv) || floor((double) (responseStatus / 100)) != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cache-Control: no-store.
|
||||
bool isNoStoreResponse = false;
|
||||
httpChannel->IsNoStoreResponse(&isNoStoreResponse);
|
||||
if (isNoStoreResponse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deny storage if we're viewing a HTTPS page with a
|
||||
// 'Cache-Control' header having a value that is not 'public'.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = channel->GetURI(getter_AddRefs(uri));
|
||||
if (!NS_SUCCEEDED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't capture HTTPS pages unless the user enabled it
|
||||
// or the page has a Cache-Control:public header.
|
||||
bool isHttps = false;
|
||||
uri->SchemeIs("https", &isHttps);
|
||||
if (isHttps && !Preferences::GetBool("browser.cache.disk_cache_ssl", false)) {
|
||||
nsAutoCString cacheControl;
|
||||
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Cache-Control"), cacheControl);
|
||||
if (!NS_SUCCEEDED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cacheControl.IsEmpty() && !cacheControl.LowerCaseEqualsLiteral("public")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
|
||||
nsIMutableArray *aHandlersArray,
|
||||
@ -1694,7 +1758,7 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId,
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer)
|
||||
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer, bool &shouldStore)
|
||||
{
|
||||
nsresult rv;
|
||||
float scale = 1.0;
|
||||
@ -1744,10 +1808,16 @@ nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int
|
||||
if (!win)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
|
||||
// Decide if callers should store this thumbnail for later use.
|
||||
shouldStore = ShouldStoreThumbnail(docshell);
|
||||
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
|
||||
if (!presContext)
|
||||
return NS_ERROR_FAILURE;
|
||||
nscolor bgColor = NS_RGB(255, 255, 255);
|
||||
|
@ -195,7 +195,7 @@ public:
|
||||
bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
|
||||
bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
|
||||
|
||||
nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer);
|
||||
nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer, bool &shouldStore);
|
||||
void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
|
||||
void ContentDocumentChanged();
|
||||
bool IsContentDocumentDisplayed();
|
||||
|
@ -1534,7 +1534,7 @@ void ThumbnailHelper::InitStubs(JNIEnv *jEnv) {
|
||||
initInit();
|
||||
|
||||
mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper");
|
||||
jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZ)V");
|
||||
jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZZ)V");
|
||||
}
|
||||
|
||||
ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
|
||||
@ -1544,17 +1544,18 @@ ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ThumbnailHelper::SendThumbnail(jobject a0, int32_t a1, bool a2) {
|
||||
void ThumbnailHelper::SendThumbnail(jobject a0, int32_t a1, bool a2, bool a3) {
|
||||
JNIEnv *env = AndroidBridge::GetJNIEnv();
|
||||
if (env->PushLocalFrame(1) != 0) {
|
||||
AndroidBridge::HandleUncaughtException(env);
|
||||
MOZ_CRASH("Exception should have caused crash.");
|
||||
}
|
||||
|
||||
jvalue args[3];
|
||||
jvalue args[4];
|
||||
args[0].l = a0;
|
||||
args[1].i = a1;
|
||||
args[2].z = a2;
|
||||
args[3].z = a3;
|
||||
|
||||
env->CallStaticVoidMethodA(mThumbnailHelperClass, jSendThumbnail, args);
|
||||
AndroidBridge::HandleUncaughtException(env);
|
||||
|
@ -260,7 +260,7 @@ public:
|
||||
static void InitStubs(JNIEnv *jEnv);
|
||||
static ThumbnailHelper* Wrap(jobject obj);
|
||||
ThumbnailHelper(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
|
||||
static void SendThumbnail(jobject a0, int32_t a1, bool a2);
|
||||
static void SendThumbnail(jobject a0, int32_t a1, bool a2, bool a3);
|
||||
ThumbnailHelper() : AutoGlobalWrappedJavaObject() {};
|
||||
protected:
|
||||
static jclass mThumbnailHelperClass;
|
||||
|
@ -85,20 +85,21 @@ public:
|
||||
nsCOMPtr<nsIBrowserTab> tab;
|
||||
mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
|
||||
if (!tab) {
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
tab->GetWindow(getter_AddRefs(domWindow));
|
||||
if (!domWindow) {
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mPoints.Length() == 1, "Thumbnail event does not have enough coordinates");
|
||||
|
||||
nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv));
|
||||
bool shouldStore = true;
|
||||
nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer, shouldStore);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv), shouldStore);
|
||||
return rv;
|
||||
}
|
||||
private:
|
||||
|
@ -33,6 +33,7 @@ using namespace mozilla::widget::android;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <sys/system_properties.h>
|
||||
#include "mozilla/Preferences.h"
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
@ -289,13 +290,35 @@ nsSystemInfo::Init()
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
char sdk[PROP_VALUE_MAX], characteristics[PROP_VALUE_MAX];
|
||||
if (__system_property_get("ro.build.version.sdk", sdk))
|
||||
char sdk[PROP_VALUE_MAX];
|
||||
if (__system_property_get("ro.build.version.sdk", sdk)) {
|
||||
android_sdk_version = atoi(sdk);
|
||||
SetPropertyAsInt32(NS_LITERAL_STRING("sdk_version"), android_sdk_version);
|
||||
}
|
||||
|
||||
char characteristics[PROP_VALUE_MAX];
|
||||
if (__system_property_get("ro.build.characteristics", characteristics)) {
|
||||
if (!strcmp(characteristics, "tablet"))
|
||||
SetPropertyAsBool(NS_LITERAL_STRING("tablet"), true);
|
||||
}
|
||||
|
||||
nsAutoString str;
|
||||
rv = GetPropertyAsAString(NS_LITERAL_STRING("version"), str);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetPropertyAsAString(NS_LITERAL_STRING("kernel_version"), str);
|
||||
}
|
||||
|
||||
const nsAdoptingString& b2g_os_name =
|
||||
mozilla::Preferences::GetString("b2g.osName");
|
||||
if (b2g_os_name) {
|
||||
SetPropertyAsAString(NS_LITERAL_STRING("name"), b2g_os_name);
|
||||
}
|
||||
|
||||
const nsAdoptingString& b2g_version =
|
||||
mozilla::Preferences::GetString("b2g.version");
|
||||
if (b2g_version) {
|
||||
SetPropertyAsAString(NS_LITERAL_STRING("version"), b2g_version);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user