зеркало из https://github.com/mozilla/gecko-dev.git
Merge b2g-inbound to m-c
This commit is contained in:
Коммит
c1b0f6e109
5
CLOBBER
5
CLOBBER
|
@ -18,7 +18,4 @@
|
||||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||||
#
|
#
|
||||||
|
|
||||||
Bug 934646 needs a clobber -- the icon resources previously copied
|
Bug 946047 - Windows needs a clobber for webidl changes.
|
||||||
into $OBJDIR/mobile/android/base/res will conflict with those in
|
|
||||||
$BRANDING_DIRECTORY/res.
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.html");
|
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.html");
|
||||||
pref("browser.chromeURL", "chrome://browser/content/");
|
pref("browser.chromeURL", "chrome://browser/content/");
|
||||||
|
|
||||||
|
// Bug 945235: Prevent all bars to be considered visible:
|
||||||
|
pref("toolkit.defaultChromeFeatures", "chrome,dialog=no,close,resizable,scrollbars,extrachrome");
|
||||||
|
|
||||||
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
|
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
|
||||||
pref("browser.viewport.scaleRatio", -1);
|
pref("browser.viewport.scaleRatio", -1);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"revision": "5bfef5faac50d14e055f642a44ed2df8483fb2fe",
|
"revision": "9271d94f35a54995e4442da711e51cff0244741d",
|
||||||
"repo_path": "/integration/gaia-central"
|
"repo_path": "/integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,9 +148,7 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
||||||
VideoChunk chunk = *iter;
|
VideoChunk chunk = *iter;
|
||||||
if (!chunk.IsNull()) {
|
if (!chunk.IsNull()) {
|
||||||
gfxIntSize imgsize = chunk.mFrame.GetImage()->GetSize();
|
gfxIntSize imgsize = chunk.mFrame.GetImage()->GetSize();
|
||||||
int width = (imgsize.width + 1) / 2 * 2;
|
nsresult rv = Init(imgsize.width, imgsize.height, aTrackRate);
|
||||||
int height = (imgsize.height + 1) / 2 * 2;
|
|
||||||
nsresult rv = Init(width, height, aTrackRate);
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG("[VideoTrackEncoder]: Fail to initialize the encoder!");
|
LOG("[VideoTrackEncoder]: Fail to initialize the encoder!");
|
||||||
NotifyCancel();
|
NotifyCancel();
|
||||||
|
|
|
@ -41,6 +41,25 @@ using namespace mozilla;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ReleaseOmxDecoderRunnable : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReleaseOmxDecoderRunnable(const android::sp<android::OmxDecoder>& aOmxDecoder)
|
||||||
|
: mOmxDecoder(aOmxDecoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_METHOD Run() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mOmxDecoder = nullptr; // release OmxDecoder
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
android::sp<android::OmxDecoder> mOmxDecoder;
|
||||||
|
};
|
||||||
|
|
||||||
class OmxDecoderProcessCachedDataTask : public Task
|
class OmxDecoderProcessCachedDataTask : public Task
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -53,7 +72,13 @@ public:
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
MOZ_ASSERT(mOmxDecoder.get());
|
MOZ_ASSERT(mOmxDecoder.get());
|
||||||
mOmxDecoder->ProcessCachedData(mOffset, false);
|
int64_t rem = mOmxDecoder->ProcessCachedData(mOffset, false);
|
||||||
|
|
||||||
|
if (rem <= 0) {
|
||||||
|
ReleaseOmxDecoderRunnable* r = new ReleaseOmxDecoderRunnable(mOmxDecoder);
|
||||||
|
mOmxDecoder.clear();
|
||||||
|
NS_DispatchToMainThread(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -292,6 +317,8 @@ OmxDecoder::OmxDecoder(MediaResource *aResource,
|
||||||
|
|
||||||
OmxDecoder::~OmxDecoder()
|
OmxDecoder::~OmxDecoder()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
ReleaseMediaResources();
|
ReleaseMediaResources();
|
||||||
|
|
||||||
// unregister AMessage handler from ALooper.
|
// unregister AMessage handler from ALooper.
|
||||||
|
@ -398,7 +425,7 @@ bool OmxDecoder::TryLoad() {
|
||||||
// Feed MP3 parser with cached data. Local files will be fully
|
// Feed MP3 parser with cached data. Local files will be fully
|
||||||
// cached already, network streams will update with sucessive
|
// cached already, network streams will update with sucessive
|
||||||
// calls to NotifyDataArrived.
|
// calls to NotifyDataArrived.
|
||||||
if (ProcessCachedData(0, true)) {
|
if (ProcessCachedData(0, true) >= 0) {
|
||||||
durationUs = mMP3FrameParser.GetDuration();
|
durationUs = mMP3FrameParser.GetDuration();
|
||||||
if (durationUs > totalDurationUs) {
|
if (durationUs > totalDurationUs) {
|
||||||
totalDurationUs = durationUs;
|
totalDurationUs = durationUs;
|
||||||
|
@ -1017,7 +1044,7 @@ void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
|
||||||
releasingVideoBuffers.clear();
|
releasingVideoBuffers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
|
int64_t OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
|
||||||
{
|
{
|
||||||
// We read data in chunks of 32 KiB. We can reduce this
|
// We read data in chunks of 32 KiB. We can reduce this
|
||||||
// value if media, such as sdcards, is too slow.
|
// value if media, such as sdcards, is too slow.
|
||||||
|
@ -1030,10 +1057,10 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
|
||||||
MOZ_ASSERT(mResource);
|
MOZ_ASSERT(mResource);
|
||||||
|
|
||||||
int64_t resourceLength = mResource->GetCachedDataEnd(0);
|
int64_t resourceLength = mResource->GetCachedDataEnd(0);
|
||||||
NS_ENSURE_TRUE(resourceLength >= 0, false);
|
NS_ENSURE_TRUE(resourceLength >= 0, -1);
|
||||||
|
|
||||||
if (aOffset >= resourceLength) {
|
if (aOffset >= resourceLength) {
|
||||||
return true; // Cache is empty, nothing to do
|
return 0; // Cache is empty, nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t bufferLength = std::min<int64_t>(resourceLength-aOffset, sReadSize);
|
int64_t bufferLength = std::min<int64_t>(resourceLength-aOffset, sReadSize);
|
||||||
|
@ -1041,7 +1068,7 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
|
||||||
nsAutoArrayPtr<char> buffer(new char[bufferLength]);
|
nsAutoArrayPtr<char> buffer(new char[bufferLength]);
|
||||||
|
|
||||||
nsresult rv = mResource->ReadFromCache(buffer.get(), aOffset, bufferLength);
|
nsresult rv = mResource->ReadFromCache(buffer.get(), aOffset, bufferLength);
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
NS_ENSURE_SUCCESS(rv, -1);
|
||||||
|
|
||||||
nsRefPtr<OmxDecoderNotifyDataArrivedRunnable> runnable(
|
nsRefPtr<OmxDecoderNotifyDataArrivedRunnable> runnable(
|
||||||
new OmxDecoderNotifyDataArrivedRunnable(this,
|
new OmxDecoderNotifyDataArrivedRunnable(this,
|
||||||
|
@ -1051,11 +1078,11 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
|
||||||
resourceLength));
|
resourceLength));
|
||||||
|
|
||||||
rv = NS_DispatchToMainThread(runnable.get());
|
rv = NS_DispatchToMainThread(runnable.get());
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
NS_ENSURE_SUCCESS(rv, -1);
|
||||||
|
|
||||||
if (aWaitForCompletion) {
|
if (aWaitForCompletion) {
|
||||||
runnable->WaitForCompletion();
|
runnable->WaitForCompletion();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return resourceLength - aOffset - bufferLength;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,7 @@ public:
|
||||||
// Called on ALooper thread.
|
// Called on ALooper thread.
|
||||||
void onMessageReceived(const sp<AMessage> &msg);
|
void onMessageReceived(const sp<AMessage> &msg);
|
||||||
|
|
||||||
bool ProcessCachedData(int64_t aOffset, bool aWaitForCompletion);
|
int64_t ProcessCachedData(int64_t aOffset, bool aWaitForCompletion);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,44 +22,5 @@ MediaDecoderStateMachine* RtspOmxDecoder::CreateStateMachine()
|
||||||
mResource->IsRealTime());
|
mResource->IsRealTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtspOmxDecoder::ApplyStateToStateMachine(PlayState aState)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
|
||||||
|
|
||||||
MediaDecoder::ApplyStateToStateMachine(aState);
|
|
||||||
|
|
||||||
|
|
||||||
// Send play/pause commands here through the nsIStreamingProtocolController
|
|
||||||
// except seek command. We need to clear the decoded/un-decoded buffer data
|
|
||||||
// before sending seek command. So the seek calling path to controller is:
|
|
||||||
// mDecoderStateMachine::Seek-> RtspOmxReader::Seek-> RtspResource::SeekTime->
|
|
||||||
// controller->Seek(). RtspOmxReader::Seek will clear the decoded buffer and
|
|
||||||
// the RtspResource::SeekTime will clear the un-decoded buffer.
|
|
||||||
|
|
||||||
RtspMediaResource* rtspResource = mResource->GetRtspPointer();
|
|
||||||
MOZ_ASSERT(rtspResource);
|
|
||||||
|
|
||||||
nsIStreamingProtocolController* controller =
|
|
||||||
rtspResource->GetMediaStreamController();
|
|
||||||
if (mDecoderStateMachine) {
|
|
||||||
switch (aState) {
|
|
||||||
case PLAY_STATE_PLAYING:
|
|
||||||
if (controller) {
|
|
||||||
controller->Play();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PLAY_STATE_PAUSED:
|
|
||||||
if (controller) {
|
|
||||||
controller->Pause();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* No action needed */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,6 @@ public:
|
||||||
|
|
||||||
virtual MediaDecoder* Clone() MOZ_OVERRIDE;
|
virtual MediaDecoder* Clone() MOZ_OVERRIDE;
|
||||||
virtual MediaDecoderStateMachine* CreateStateMachine() MOZ_OVERRIDE;
|
virtual MediaDecoderStateMachine* CreateStateMachine() MOZ_OVERRIDE;
|
||||||
// Called by |ChangeState|, override it to send the Rtsp play/pause commands
|
|
||||||
// through |nsIStreamingProtocolController|.
|
|
||||||
// Call on the main thread only and the lock must be obtained.
|
|
||||||
virtual void ApplyStateToStateMachine(PlayState aState) MOZ_OVERRIDE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -289,4 +289,44 @@ nsresult RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||||
return MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
return MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtspOmxReader::OnDecodeThreadStart() {
|
||||||
|
// Start RTSP streaming right after starting the decoding thread in
|
||||||
|
// MediaDecoderStateMachine and before starting OMXCodec decoding.
|
||||||
|
if (mRtspResource) {
|
||||||
|
nsIStreamingProtocolController* controller =
|
||||||
|
mRtspResource->GetMediaStreamController();
|
||||||
|
if (controller) {
|
||||||
|
controller->Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call parent class to start OMXCodec decoding.
|
||||||
|
MediaOmxReader::OnDecodeThreadStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtspOmxReader::OnDecodeThreadFinish() {
|
||||||
|
// Call parent class to pause OMXCodec decoding.
|
||||||
|
MediaOmxReader::OnDecodeThreadFinish();
|
||||||
|
|
||||||
|
// Stop RTSP streaming right before destroying the decoding thread in
|
||||||
|
// MediaDecoderStateMachine and after pausing OMXCodec decoding.
|
||||||
|
// RTSP streaming should not be paused until OMXCodec has been paused and
|
||||||
|
// until the decoding thread in MediaDecoderStateMachine is about to be
|
||||||
|
// destroyed. Otherwise, RtspMediaSource::read() would block the binder
|
||||||
|
// thread of OMXCodecObserver::onMessage() --> OMXCodec::on_message() -->
|
||||||
|
// OMXCodec::drainInputBuffer() due to network data starvation. Because
|
||||||
|
// OMXCodec::mLock is held by the binder thread in this case, all other
|
||||||
|
// threads would be blocked when they try to lock this mutex. As a result, the
|
||||||
|
// decoding thread in MediaDecoderStateMachine would be blocked forever in
|
||||||
|
// OMXCodec::read() if there is no enough data for RtspMediaSource::read() to
|
||||||
|
// return.
|
||||||
|
if (mRtspResource) {
|
||||||
|
nsIStreamingProtocolController* controller =
|
||||||
|
mRtspResource->GetMediaStreamController();
|
||||||
|
if (controller) {
|
||||||
|
controller->Pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -71,6 +71,10 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void OnDecodeThreadStart() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void OnDecodeThreadFinish() MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// A pointer to RtspMediaResource for calling the Rtsp specific function.
|
// A pointer to RtspMediaResource for calling the Rtsp specific function.
|
||||||
// The lifetime of mRtspResource is controlled by MediaDecoder. MediaDecoder
|
// The lifetime of mRtspResource is controlled by MediaDecoder. MediaDecoder
|
||||||
|
|
|
@ -108,6 +108,9 @@ extern bool gBluetoothDebugFlag;
|
||||||
#define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00"
|
#define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00"
|
||||||
#define BLUETOOTH_ADDRESS_BYTES 6
|
#define BLUETOOTH_ADDRESS_BYTES 6
|
||||||
|
|
||||||
|
// Bluetooth stack internal error, such as I/O error
|
||||||
|
#define ERR_INTERNAL_ERROR "InternalError"
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
enum BluetoothSocketType {
|
enum BluetoothSocketType {
|
||||||
|
|
|
@ -167,12 +167,6 @@ static const char* sBluetoothDBusSignals[] =
|
||||||
"type='signal',interface='org.bluez.Control'"
|
"type='signal',interface='org.bluez.Control'"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* DBus Connection held for the BluetoothCommandThread to use. Should never be
|
|
||||||
* used by any other thread.
|
|
||||||
*/
|
|
||||||
static nsRefPtr<RawDBusConnection> gThreadConnection;
|
|
||||||
|
|
||||||
// Only A2DP and HID are authorized.
|
// Only A2DP and HID are authorized.
|
||||||
static nsTArray<BluetoothServiceClass> sAuthorizedServiceClass;
|
static nsTArray<BluetoothServiceClass> sAuthorizedServiceClass;
|
||||||
|
|
||||||
|
@ -497,6 +491,14 @@ RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
||||||
nsAutoString replyError;
|
nsAutoString replyError;
|
||||||
BluetoothValue v;
|
BluetoothValue v;
|
||||||
aFunc(aMsg, nullptr, v, replyError);
|
aFunc(aMsg, nullptr, v, replyError);
|
||||||
|
|
||||||
|
// Bug 941462. When blueZ replys 'I/O error', we treat it as 'internal error'.
|
||||||
|
// This usually happned when the first pairing request has not yet finished,
|
||||||
|
// the second pairing request issued immediately.
|
||||||
|
if (replyError.EqualsLiteral("I/O error")) {
|
||||||
|
replyError.AssignLiteral(ERR_INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
DispatchBluetoothReply(replyRunnable, v, replyError);
|
DispatchBluetoothReply(replyRunnable, v, replyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,9 +968,9 @@ AppendDeviceName(BluetoothSignal& aSignal)
|
||||||
|
|
||||||
nsString devicePath = arr[0].value().get_nsString();
|
nsString devicePath = arr[0].value().get_nsString();
|
||||||
|
|
||||||
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
|
||||||
if (!threadConnection.get()) {
|
if (!connection) {
|
||||||
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -977,7 +979,7 @@ AppendDeviceName(BluetoothSignal& aSignal)
|
||||||
new AppendDeviceNameReplyHandler(nsCString(DBUS_DEVICE_IFACE),
|
new AppendDeviceNameReplyHandler(nsCString(DBUS_DEVICE_IFACE),
|
||||||
devicePath, aSignal);
|
devicePath, aSignal);
|
||||||
|
|
||||||
bool success = threadConnection->SendWithReply(
|
bool success = connection->SendWithReply(
|
||||||
AppendDeviceNameReplyHandler::Callback, handler.get(), 1000,
|
AppendDeviceNameReplyHandler::Callback, handler.get(), 1000,
|
||||||
NS_ConvertUTF16toUTF8(devicePath).get(), DBUS_DEVICE_IFACE,
|
NS_ConvertUTF16toUTF8(devicePath).get(), DBUS_DEVICE_IFACE,
|
||||||
"GetProperties", DBUS_TYPE_INVALID);
|
"GetProperties", DBUS_TYPE_INVALID);
|
||||||
|
@ -1211,9 +1213,9 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
|
||||||
if (!threadConnection.get()) {
|
if (!connection) {
|
||||||
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1221,7 +1223,7 @@ public:
|
||||||
// There is no "RegisterAgent" function defined in device interface.
|
// There is no "RegisterAgent" function defined in device interface.
|
||||||
// When we call "CreatePairedDevice", it will do device agent registration
|
// When we call "CreatePairedDevice", it will do device agent registration
|
||||||
// for us. (See maemo.org/api_refs/5.0/beta/bluez/adapter.html)
|
// for us. (See maemo.org/api_refs/5.0/beta/bluez/adapter.html)
|
||||||
if (!dbus_connection_register_object_path(threadConnection->GetConnection(),
|
if (!dbus_connection_register_object_path(connection->GetConnection(),
|
||||||
KEY_REMOTE_AGENT,
|
KEY_REMOTE_AGENT,
|
||||||
mAgentVTable,
|
mAgentVTable,
|
||||||
nullptr)) {
|
nullptr)) {
|
||||||
|
@ -1297,9 +1299,9 @@ private:
|
||||||
const char* agentPath = KEY_LOCAL_AGENT;
|
const char* agentPath = KEY_LOCAL_AGENT;
|
||||||
const char* capabilities = B2G_AGENT_CAPABILITIES;
|
const char* capabilities = B2G_AGENT_CAPABILITIES;
|
||||||
|
|
||||||
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
|
||||||
if (!threadConnection.get()) {
|
if (!connection) {
|
||||||
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1310,7 +1312,7 @@ private:
|
||||||
// signal will be passed to local agent. If we start pairing process with
|
// signal will be passed to local agent. If we start pairing process with
|
||||||
// calling CreatePairedDevice, we'll get signal which should be passed to
|
// calling CreatePairedDevice, we'll get signal which should be passed to
|
||||||
// device agent.
|
// device agent.
|
||||||
if (!dbus_connection_register_object_path(threadConnection->GetConnection(),
|
if (!dbus_connection_register_object_path(connection->GetConnection(),
|
||||||
KEY_LOCAL_AGENT,
|
KEY_LOCAL_AGENT,
|
||||||
aAgentVTable,
|
aAgentVTable,
|
||||||
nullptr)) {
|
nullptr)) {
|
||||||
|
@ -1324,7 +1326,7 @@ private:
|
||||||
MOZ_ASSERT(handler.get());
|
MOZ_ASSERT(handler.get());
|
||||||
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
||||||
|
|
||||||
bool success = threadConnection->SendWithReply(
|
bool success = connection->SendWithReply(
|
||||||
RegisterAgentReplyHandler::Callback, handler.get(), -1,
|
RegisterAgentReplyHandler::Callback, handler.get(), -1,
|
||||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||||
DBUS_ADAPTER_IFACE, "RegisterAgent",
|
DBUS_ADAPTER_IFACE, "RegisterAgent",
|
||||||
|
@ -1359,9 +1361,9 @@ public:
|
||||||
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
|
||||||
if (!threadConnection.get()) {
|
if (!connection) {
|
||||||
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -1375,7 +1377,7 @@ public:
|
||||||
|
|
||||||
const dbus_uint32_t* services = sServices;
|
const dbus_uint32_t* services = sServices;
|
||||||
|
|
||||||
bool success = threadConnection->SendWithReply(
|
bool success = connection->SendWithReply(
|
||||||
DBusReplyHandler::Callback, handler.get(), -1,
|
DBusReplyHandler::Callback, handler.get(), -1,
|
||||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||||
DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
|
DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
|
||||||
|
@ -1719,7 +1721,7 @@ OnDefaultAdapterReply(DBusMessage* aReply, void* aData)
|
||||||
bool
|
bool
|
||||||
BluetoothDBusService::IsReady()
|
BluetoothDBusService::IsReady()
|
||||||
{
|
{
|
||||||
if (!IsEnabled() || !mConnection || !gThreadConnection || IsToggling()) {
|
if (!IsEnabled() || !GetDBusConnection() || IsToggling()) {
|
||||||
BT_WARNING("Bluetooth service is not ready yet!");
|
BT_WARNING("Bluetooth service is not ready yet!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1737,25 +1739,8 @@ BluetoothDBusService::StartInternal()
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mConnection) {
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
return NS_OK;
|
MOZ_ASSERT(connection);
|
||||||
}
|
|
||||||
|
|
||||||
mConnection = new RawDBusConnection();
|
|
||||||
|
|
||||||
if (NS_FAILED(mConnection->EstablishDBusConnection())) {
|
|
||||||
BT_WARNING("Cannot start Main Thread DBus connection!");
|
|
||||||
StopDBus();
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gThreadConnection = new RawDBusConnection();
|
|
||||||
|
|
||||||
if (NS_FAILED(gThreadConnection->EstablishDBusConnection())) {
|
|
||||||
BT_WARNING("Cannot start Sync Thread DBus connection!");
|
|
||||||
StopDBus();
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusError err;
|
DBusError err;
|
||||||
dbus_error_init(&err);
|
dbus_error_init(&err);
|
||||||
|
@ -1765,7 +1750,7 @@ BluetoothDBusService::StartInternal()
|
||||||
// signals we want, register all of them in this thread at startup.
|
// signals we want, register all of them in this thread at startup.
|
||||||
// The event handler will sort the destinations out as needed.
|
// The event handler will sort the destinations out as needed.
|
||||||
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
|
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
|
||||||
dbus_bus_add_match(mConnection->GetConnection(),
|
dbus_bus_add_match(connection->GetConnection(),
|
||||||
sBluetoothDBusSignals[i],
|
sBluetoothDBusSignals[i],
|
||||||
&err);
|
&err);
|
||||||
if (dbus_error_is_set(&err)) {
|
if (dbus_error_is_set(&err)) {
|
||||||
|
@ -1774,7 +1759,7 @@ BluetoothDBusService::StartInternal()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a filter for all incoming messages_base
|
// Add a filter for all incoming messages_base
|
||||||
if (!dbus_connection_add_filter(mConnection->GetConnection(),
|
if (!dbus_connection_add_filter(connection->GetConnection(),
|
||||||
EventFilter, nullptr, nullptr)) {
|
EventFilter, nullptr, nullptr)) {
|
||||||
BT_WARNING("Cannot create DBus Event Filter for DBus Thread!");
|
BT_WARNING("Cannot create DBus Event Filter for DBus Thread!");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
@ -1792,7 +1777,7 @@ BluetoothDBusService::StartInternal()
|
||||||
* explicitly here.
|
* explicitly here.
|
||||||
*/
|
*/
|
||||||
if (sAdapterPath.IsEmpty()) {
|
if (sAdapterPath.IsEmpty()) {
|
||||||
bool success = mConnection->SendWithReply(OnDefaultAdapterReply, nullptr,
|
bool success = connection->SendWithReply(OnDefaultAdapterReply, nullptr,
|
||||||
1000, "/",
|
1000, "/",
|
||||||
DBUS_MANAGER_IFACE,
|
DBUS_MANAGER_IFACE,
|
||||||
"DefaultAdapter",
|
"DefaultAdapter",
|
||||||
|
@ -1826,15 +1811,16 @@ BluetoothDBusService::StopInternal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mConnection) {
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
StopDBus();
|
|
||||||
|
if (!connection) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusError err;
|
DBusError err;
|
||||||
dbus_error_init(&err);
|
dbus_error_init(&err);
|
||||||
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
|
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
|
||||||
dbus_bus_remove_match(mConnection->GetConnection(),
|
dbus_bus_remove_match(connection->GetConnection(),
|
||||||
sBluetoothDBusSignals[i],
|
sBluetoothDBusSignals[i],
|
||||||
&err);
|
&err);
|
||||||
if (dbus_error_is_set(&err)) {
|
if (dbus_error_is_set(&err)) {
|
||||||
|
@ -1842,24 +1828,21 @@ BluetoothDBusService::StopInternal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_connection_remove_filter(mConnection->GetConnection(),
|
dbus_connection_remove_filter(connection->GetConnection(),
|
||||||
EventFilter, nullptr);
|
EventFilter, nullptr);
|
||||||
|
|
||||||
if (!dbus_connection_unregister_object_path(gThreadConnection->GetConnection(),
|
if (!dbus_connection_unregister_object_path(connection->GetConnection(),
|
||||||
KEY_LOCAL_AGENT)) {
|
KEY_LOCAL_AGENT)) {
|
||||||
BT_WARNING("%s: Can't unregister object path %s for agent!",
|
BT_WARNING("%s: Can't unregister object path %s for agent!",
|
||||||
__FUNCTION__, KEY_LOCAL_AGENT);
|
__FUNCTION__, KEY_LOCAL_AGENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbus_connection_unregister_object_path(gThreadConnection->GetConnection(),
|
if (!dbus_connection_unregister_object_path(connection->GetConnection(),
|
||||||
KEY_REMOTE_AGENT)) {
|
KEY_REMOTE_AGENT)) {
|
||||||
BT_WARNING("%s: Can't unregister object path %s for agent!",
|
BT_WARNING("%s: Can't unregister object path %s for agent!",
|
||||||
__FUNCTION__, KEY_REMOTE_AGENT);
|
__FUNCTION__, KEY_REMOTE_AGENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
mConnection = nullptr;
|
|
||||||
gThreadConnection = nullptr;
|
|
||||||
|
|
||||||
// unref stored DBusMessages before clear the hashtable
|
// unref stored DBusMessages before clear the hashtable
|
||||||
sPairingReqTable->EnumerateRead(UnrefDBusMessages, nullptr);
|
sPairingReqTable->EnumerateRead(UnrefDBusMessages, nullptr);
|
||||||
sPairingReqTable->Clear();
|
sPairingReqTable->Clear();
|
||||||
|
@ -1943,14 +1926,14 @@ protected:
|
||||||
// Acquire another reference to this reply handler
|
// Acquire another reference to this reply handler
|
||||||
nsRefPtr<DefaultAdapterPathReplyHandler> handler = this;
|
nsRefPtr<DefaultAdapterPathReplyHandler> handler = this;
|
||||||
|
|
||||||
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
|
||||||
if (!threadConnection.get()) {
|
if (!connection) {
|
||||||
aReplyError = NS_LITERAL_STRING("DBus connection has been closed.");
|
aReplyError = NS_LITERAL_STRING("DBus connection has been closed.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = threadConnection->SendWithReply(
|
bool success = connection->SendWithReply(
|
||||||
DefaultAdapterPathReplyHandler::Callback, handler.get(), 1000,
|
DefaultAdapterPathReplyHandler::Callback, handler.get(), 1000,
|
||||||
NS_ConvertUTF16toUTF8(mAdapterPath).get(),
|
NS_ConvertUTF16toUTF8(mAdapterPath).get(),
|
||||||
DBUS_ADAPTER_IFACE, "GetProperties", DBUS_TYPE_INVALID);
|
DBUS_ADAPTER_IFACE, "GetProperties", DBUS_TYPE_INVALID);
|
||||||
|
@ -2011,7 +1994,10 @@ BluetoothDBusService::GetDefaultAdapterPathInternal(
|
||||||
nsRefPtr<DefaultAdapterPathReplyHandler> handler =
|
nsRefPtr<DefaultAdapterPathReplyHandler> handler =
|
||||||
new DefaultAdapterPathReplyHandler(aRunnable);
|
new DefaultAdapterPathReplyHandler(aRunnable);
|
||||||
|
|
||||||
bool success = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool success = connection->SendWithReply(
|
||||||
DefaultAdapterPathReplyHandler::Callback,
|
DefaultAdapterPathReplyHandler::Callback,
|
||||||
handler.get(), 1000,
|
handler.get(), 1000,
|
||||||
"/", DBUS_MANAGER_IFACE, "DefaultAdapter",
|
"/", DBUS_MANAGER_IFACE, "DefaultAdapter",
|
||||||
|
@ -2056,7 +2042,10 @@ BluetoothDBusService::SendDiscoveryMessage(const char* aMessageName,
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||||
|
|
||||||
bool success = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool success = connection->SendWithReply(
|
||||||
OnSendDiscoveryMessageReply,
|
OnSendDiscoveryMessageReply,
|
||||||
static_cast<void*>(aRunnable), -1,
|
static_cast<void*>(aRunnable), -1,
|
||||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||||
|
@ -2096,13 +2085,12 @@ BluetoothDBusService::SendAsyncDBusMessage(const nsAString& aObjectPath,
|
||||||
DBusReplyCallback aCallback)
|
DBusReplyCallback aCallback)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mConnection);
|
|
||||||
MOZ_ASSERT(IsEnabled());
|
MOZ_ASSERT(IsEnabled());
|
||||||
MOZ_ASSERT(aCallback);
|
MOZ_ASSERT(aCallback);
|
||||||
MOZ_ASSERT(!aObjectPath.IsEmpty());
|
MOZ_ASSERT(!aObjectPath.IsEmpty());
|
||||||
MOZ_ASSERT(aInterface);
|
MOZ_ASSERT(aInterface);
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mConnection, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(GetDBusConnection(), NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsAutoPtr<BluetoothServiceClass> serviceClass(new BluetoothServiceClass());
|
nsAutoPtr<BluetoothServiceClass> serviceClass(new BluetoothServiceClass());
|
||||||
if (!strcmp(aInterface, DBUS_SINK_IFACE)) {
|
if (!strcmp(aInterface, DBUS_SINK_IFACE)) {
|
||||||
|
@ -2114,7 +2102,10 @@ BluetoothDBusService::SendAsyncDBusMessage(const nsAString& aObjectPath,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool ret = connection->SendWithReply(
|
||||||
aCallback, static_cast<void*>(serviceClass.forget()), -1,
|
aCallback, static_cast<void*>(serviceClass.forget()), -1,
|
||||||
NS_ConvertUTF16toUTF8(aObjectPath).get(),
|
NS_ConvertUTF16toUTF8(aObjectPath).get(),
|
||||||
aInterface, NS_ConvertUTF16toUTF8(aMessage).get(),
|
aInterface, NS_ConvertUTF16toUTF8(aMessage).get(),
|
||||||
|
@ -2259,16 +2250,16 @@ protected:
|
||||||
mObjectPath = GetObjectPathFromAddress(sAdapterPath,
|
mObjectPath = GetObjectPathFromAddress(sAdapterPath,
|
||||||
mDeviceAddresses[mProcessedDeviceAddresses]);
|
mDeviceAddresses[mProcessedDeviceAddresses]);
|
||||||
|
|
||||||
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
|
||||||
if (!threadConnection.get()) {
|
if (!connection) {
|
||||||
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<BluetoothArrayOfDevicePropertiesReplyHandler> handler = this;
|
nsRefPtr<BluetoothArrayOfDevicePropertiesReplyHandler> handler = this;
|
||||||
|
|
||||||
bool success = threadConnection->SendWithReply(
|
bool success = connection->SendWithReply(
|
||||||
BluetoothArrayOfDevicePropertiesReplyHandler::Callback,
|
BluetoothArrayOfDevicePropertiesReplyHandler::Callback,
|
||||||
handler.get(), 1000,
|
handler.get(), 1000,
|
||||||
NS_ConvertUTF16toUTF8(mObjectPath).get(),
|
NS_ConvertUTF16toUTF8(mObjectPath).get(),
|
||||||
|
@ -2427,8 +2418,11 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||||
|
|
||||||
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
// msg is unref'd as part of SendWithReply
|
// msg is unref'd as part of SendWithReply
|
||||||
bool success = mConnection->SendWithReply(GetVoidCallback,
|
bool success = connection->SendWithReply(GetVoidCallback,
|
||||||
(void*)aRunnable,
|
(void*)aRunnable,
|
||||||
1000, msg);
|
1000, msg);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -2468,9 +2462,12 @@ BluetoothDBusService::CreatePairedDeviceInternal(
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||||
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
||||||
|
|
||||||
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
// Then send CreatePairedDevice, it will register a temp device agent then
|
// Then send CreatePairedDevice, it will register a temp device agent then
|
||||||
// unregister it after pairing process is over
|
// unregister it after pairing process is over
|
||||||
bool ret = mConnection->SendWithReply(
|
bool ret = connection->SendWithReply(
|
||||||
GetObjectPathCallback, (void*)runnable, aTimeout,
|
GetObjectPathCallback, (void*)runnable, aTimeout,
|
||||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||||
DBUS_ADAPTER_IFACE,
|
DBUS_ADAPTER_IFACE,
|
||||||
|
@ -2523,7 +2520,10 @@ BluetoothDBusService::RemoveDeviceInternal(const nsAString& aDeviceAddress,
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||||
|
|
||||||
bool success = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool success = connection->SendWithReply(
|
||||||
OnRemoveDeviceReply, static_cast<void*>(runnable.get()), -1,
|
OnRemoveDeviceReply, static_cast<void*>(runnable.get()), -1,
|
||||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||||
DBUS_ADAPTER_IFACE, "RemoveDevice",
|
DBUS_ADAPTER_IFACE, "RemoveDevice",
|
||||||
|
@ -2574,7 +2574,9 @@ BluetoothDBusService::SetPinCodeInternal(const nsAString& aDeviceAddress,
|
||||||
errorStr.AssignLiteral("Couldn't append arguments to dbus message.");
|
errorStr.AssignLiteral("Couldn't append arguments to dbus message.");
|
||||||
result = false;
|
result = false;
|
||||||
} else {
|
} else {
|
||||||
result = mConnection->Send(reply);
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
result = connection->Send(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
@ -2620,7 +2622,9 @@ BluetoothDBusService::SetPasskeyInternal(const nsAString& aDeviceAddress,
|
||||||
errorStr.AssignLiteral("Couldn't append arguments to dbus message.");
|
errorStr.AssignLiteral("Couldn't append arguments to dbus message.");
|
||||||
result = false;
|
result = false;
|
||||||
} else {
|
} else {
|
||||||
result = mConnection->Send(reply);
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
result = connection->Send(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
@ -2664,7 +2668,10 @@ BluetoothDBusService::SetPairingConfirmationInternal(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = mConnection->Send(reply);
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool result = connection->Send(reply);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
errorStr.AssignLiteral("Can't send message!");
|
errorStr.AssignLiteral("Can't send message!");
|
||||||
}
|
}
|
||||||
|
@ -2907,7 +2914,10 @@ BluetoothDBusService::GetServiceChannel(const nsAString& aDeviceAddress,
|
||||||
nsRefPtr<OnGetServiceChannelReplyHandler> handler =
|
nsRefPtr<OnGetServiceChannelReplyHandler> handler =
|
||||||
new OnGetServiceChannelReplyHandler(objectPath, aServiceUUID, aManager);
|
new OnGetServiceChannelReplyHandler(objectPath, aServiceUUID, aManager);
|
||||||
|
|
||||||
bool success = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool success = connection->SendWithReply(
|
||||||
OnGetServiceChannelReplyHandler::Callback, handler, -1,
|
OnGetServiceChannelReplyHandler::Callback, handler, -1,
|
||||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
|
DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
|
||||||
|
@ -2952,7 +2962,6 @@ BluetoothDBusService::UpdateSdpRecords(const nsAString& aDeviceAddress,
|
||||||
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
||||||
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
||||||
MOZ_ASSERT(aManager);
|
MOZ_ASSERT(aManager);
|
||||||
MOZ_ASSERT(mConnection);
|
|
||||||
|
|
||||||
nsString objectPath(GetObjectPathFromAddress(sAdapterPath, aDeviceAddress));
|
nsString objectPath(GetObjectPathFromAddress(sAdapterPath, aDeviceAddress));
|
||||||
|
|
||||||
|
@ -2961,7 +2970,10 @@ BluetoothDBusService::UpdateSdpRecords(const nsAString& aDeviceAddress,
|
||||||
OnUpdateSdpRecordsRunnable* callbackRunnable =
|
OnUpdateSdpRecordsRunnable* callbackRunnable =
|
||||||
new OnUpdateSdpRecordsRunnable(objectPath, aManager);
|
new OnUpdateSdpRecordsRunnable(objectPath, aManager);
|
||||||
|
|
||||||
return mConnection->SendWithReply(DiscoverServicesCallback,
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
return connection->SendWithReply(DiscoverServicesCallback,
|
||||||
(void*)callbackRunnable, -1,
|
(void*)callbackRunnable, -1,
|
||||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
DBUS_DEVICE_IFACE,
|
DBUS_DEVICE_IFACE,
|
||||||
|
@ -3144,7 +3156,10 @@ BluetoothDBusService::SendMetaData(const nsAString& aTitle,
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||||
|
|
||||||
bool ret = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool ret = connection->SendWithReply(
|
||||||
GetVoidCallback, (void*)runnable.get(), -1,
|
GetVoidCallback, (void*)runnable.get(), -1,
|
||||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
DBUS_CTL_IFACE, "UpdateMetaData",
|
DBUS_CTL_IFACE, "UpdateMetaData",
|
||||||
|
@ -3243,7 +3258,10 @@ BluetoothDBusService::SendPlayStatus(int64_t aDuration,
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||||
|
|
||||||
bool ret = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool ret = connection->SendWithReply(
|
||||||
GetVoidCallback, (void*)runnable.get(), -1,
|
GetVoidCallback, (void*)runnable.get(), -1,
|
||||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
DBUS_CTL_IFACE, "UpdatePlayStatus",
|
DBUS_CTL_IFACE, "UpdatePlayStatus",
|
||||||
|
@ -3292,7 +3310,10 @@ BluetoothDBusService::UpdatePlayStatus(uint32_t aDuration,
|
||||||
|
|
||||||
uint32_t tempPlayStatus = aPlayStatus;
|
uint32_t tempPlayStatus = aPlayStatus;
|
||||||
|
|
||||||
bool ret = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool ret = connection->SendWithReply(
|
||||||
ControlCallback, nullptr, -1,
|
ControlCallback, nullptr, -1,
|
||||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
DBUS_CTL_IFACE, "UpdatePlayStatus",
|
DBUS_CTL_IFACE, "UpdatePlayStatus",
|
||||||
|
@ -3322,7 +3343,10 @@ BluetoothDBusService::UpdateNotification(ControlEventId aEventId,
|
||||||
GetObjectPathFromAddress(sAdapterPath, address);
|
GetObjectPathFromAddress(sAdapterPath, address);
|
||||||
uint16_t eventId = aEventId;
|
uint16_t eventId = aEventId;
|
||||||
|
|
||||||
bool ret = mConnection->SendWithReply(
|
RawDBusConnection* connection = GetDBusConnection();
|
||||||
|
MOZ_ASSERT(connection);
|
||||||
|
|
||||||
|
bool ret = connection->SendWithReply(
|
||||||
ControlCallback, nullptr, -1,
|
ControlCallback, nullptr, -1,
|
||||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
DBUS_CTL_IFACE, "UpdateNotification",
|
DBUS_CTL_IFACE, "UpdateNotification",
|
||||||
|
|
|
@ -194,8 +194,6 @@ private:
|
||||||
const char* aInterface,
|
const char* aInterface,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
mozilla::ipc::DBusReplyCallback aCallback);
|
mozilla::ipc::DBusReplyCallback aCallback);
|
||||||
|
|
||||||
nsRefPtr<mozilla::ipc::RawDBusConnection> mConnection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
|
@ -45,10 +45,6 @@ const ContentPanning = {
|
||||||
this.watchedEventsType = 'mouse';
|
this.watchedEventsType = 'mouse';
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are using an AsyncPanZoomController for the parent frame,
|
|
||||||
// it will handle subframe scrolling too. We don't need to listen for
|
|
||||||
// these events.
|
|
||||||
if (!docShell.asyncPanZoomEnabled) {
|
|
||||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||||
.getService(Ci.nsIEventListenerService);
|
.getService(Ci.nsIEventListenerService);
|
||||||
|
|
||||||
|
@ -59,7 +55,6 @@ const ContentPanning = {
|
||||||
this.handleEvent.bind(this),
|
this.handleEvent.bind(this),
|
||||||
/* useCapture = */ false);
|
/* useCapture = */ false);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
|
||||||
|
|
||||||
addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
|
addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
|
||||||
addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
|
addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
|
||||||
|
@ -70,6 +65,8 @@ const ContentPanning = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent: function cp_handleEvent(evt) {
|
handleEvent: function cp_handleEvent(evt) {
|
||||||
|
this._tryDelayMouseEvents();
|
||||||
|
|
||||||
if (evt.defaultPrevented || evt.multipleActionsPrevented) {
|
if (evt.defaultPrevented || evt.multipleActionsPrevented) {
|
||||||
// clean up panning state even if touchend/mouseup has been preventDefault.
|
// clean up panning state even if touchend/mouseup has been preventDefault.
|
||||||
if(evt.type === 'touchend' || evt.type === 'mouseup') {
|
if(evt.type === 'touchend' || evt.type === 'mouseup') {
|
||||||
|
@ -82,13 +79,6 @@ const ContentPanning = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = Date.now();
|
|
||||||
let thread = Services.tm.currentThread;
|
|
||||||
while (this._delayEvents && (Date.now() - start) < this._activeDurationMs) {
|
|
||||||
thread.processNextEvent(true);
|
|
||||||
}
|
|
||||||
this._delayEvents = false;
|
|
||||||
|
|
||||||
switch (evt.type) {
|
switch (evt.type) {
|
||||||
case 'mousedown':
|
case 'mousedown':
|
||||||
case 'touchstart':
|
case 'touchstart':
|
||||||
|
@ -189,7 +179,8 @@ const ContentPanning = {
|
||||||
|
|
||||||
// We prevent start events to avoid sending a focus event at the end of this
|
// We prevent start events to avoid sending a focus event at the end of this
|
||||||
// touch series. See bug 889717.
|
// touch series. See bug 889717.
|
||||||
if (this.panning || this.preventNextClick) {
|
if (docShell.asyncPanZoomEnabled === false &&
|
||||||
|
(this.panning || this.preventNextClick)) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -228,7 +219,7 @@ const ContentPanning = {
|
||||||
let view = target.ownerDocument ? target.ownerDocument.defaultView
|
let view = target.ownerDocument ? target.ownerDocument.defaultView
|
||||||
: target;
|
: target;
|
||||||
view.addEventListener('click', this, true, true);
|
view.addEventListener('click', this, true, true);
|
||||||
} else {
|
} else if (docShell.asyncPanZoomEnabled === false) {
|
||||||
// We prevent end events to avoid sending a focus event. See bug 889717.
|
// We prevent end events to avoid sending a focus event. See bug 889717.
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -236,12 +227,7 @@ const ContentPanning = {
|
||||||
this.notify(this._activationTimer);
|
this.notify(this._activationTimer);
|
||||||
|
|
||||||
this._delayEvents = true;
|
this._delayEvents = true;
|
||||||
let start = Date.now();
|
this._tryDelayMouseEvents();
|
||||||
let thread = Services.tm.currentThread;
|
|
||||||
while (this._delayEvents && (Date.now() - start) < this._activeDurationMs) {
|
|
||||||
thread.processNextEvent(true);
|
|
||||||
}
|
|
||||||
this._delayEvents = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._finishPanning();
|
this._finishPanning();
|
||||||
|
@ -278,7 +264,12 @@ const ContentPanning = {
|
||||||
}
|
}
|
||||||
|
|
||||||
let isPan = KineticPanning.isPan();
|
let isPan = KineticPanning.isPan();
|
||||||
|
|
||||||
|
// If the application is not managed by the AsyncPanZoomController, then
|
||||||
|
// scroll manually.
|
||||||
|
if (docShell.asyncPanZoomEnabled === false) {
|
||||||
this.scrollCallback(delta.scale(-1));
|
this.scrollCallback(delta.scale(-1));
|
||||||
|
}
|
||||||
|
|
||||||
// If we've detected a pan gesture, cancel the active state of the
|
// If we've detected a pan gesture, cancel the active state of the
|
||||||
// current target.
|
// current target.
|
||||||
|
@ -454,6 +445,15 @@ const ContentPanning = {
|
||||||
return this._activeDurationMs = duration;
|
return this._activeDurationMs = duration;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_tryDelayMouseEvents: function cp_tryDelayMouseEvents() {
|
||||||
|
let start = Date.now();
|
||||||
|
let thread = Services.tm.currentThread;
|
||||||
|
while (this._delayEvents && (Date.now() - start) < this._activeDurationMs) {
|
||||||
|
thread.processNextEvent(true);
|
||||||
|
}
|
||||||
|
this._delayEvents = false;
|
||||||
|
},
|
||||||
|
|
||||||
_resetActive: function cp_resetActive() {
|
_resetActive: function cp_resetActive() {
|
||||||
let elt = this.pointerDownTarget || this.target;
|
let elt = this.pointerDownTarget || this.target;
|
||||||
let root = elt.ownerDocument || elt.document;
|
let root = elt.ownerDocument || elt.document;
|
||||||
|
@ -594,7 +594,9 @@ const ContentPanning = {
|
||||||
delete this.primaryPointerId;
|
delete this.primaryPointerId;
|
||||||
this._activationTimer.cancel();
|
this._activationTimer.cancel();
|
||||||
|
|
||||||
if (this.panning) {
|
// If there is a scroll action but the application is not managed by
|
||||||
|
// the AsyncPanZoom controller, let's do a manual kinetic panning action.
|
||||||
|
if (this.panning && docShell.asyncPanZoomEnabled === false) {
|
||||||
KineticPanning.start(this);
|
KineticPanning.start(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const Cu = Components.utils;
|
||||||
const Cc = Components.classes;
|
const Cc = Components.classes;
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = [];
|
this.EXPORTED_SYMBOLS = ["ContactService"];
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
@ -31,7 +31,7 @@ let ContactService = {
|
||||||
"child-process-shutdown", "Contacts:GetRevision",
|
"child-process-shutdown", "Contacts:GetRevision",
|
||||||
"Contacts:GetCount"];
|
"Contacts:GetCount"];
|
||||||
this._children = [];
|
this._children = [];
|
||||||
this._cursors = {};
|
this._cursors = new Map();
|
||||||
this._messages.forEach(function(msgName) {
|
this._messages.forEach(function(msgName) {
|
||||||
ppmm.addMessageListener(msgName, this);
|
ppmm.addMessageListener(msgName, this);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -120,18 +120,21 @@ let ContactService = {
|
||||||
if (!this.assertPermission(aMessage, "contacts-read")) {
|
if (!this.assertPermission(aMessage, "contacts-read")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!this._cursors[mm]) {
|
let cursorList = this._cursors.get(mm);
|
||||||
this._cursors[mm] = [];
|
if (!cursorList) {
|
||||||
|
cursorList = [];
|
||||||
|
this._cursors.set(mm, cursorList);
|
||||||
}
|
}
|
||||||
this._cursors[mm].push(msg.cursorId);
|
cursorList.push(msg.cursorId);
|
||||||
|
|
||||||
this._db.getAll(
|
this._db.getAll(
|
||||||
function(aContacts) {
|
function(aContacts) {
|
||||||
try {
|
try {
|
||||||
mm.sendAsyncMessage("Contacts:GetAll:Next", {cursorId: msg.cursorId, contacts: aContacts});
|
mm.sendAsyncMessage("Contacts:GetAll:Next", {cursorId: msg.cursorId, contacts: aContacts});
|
||||||
if (aContacts === null) {
|
if (aContacts === null) {
|
||||||
let index = this._cursors[mm].indexOf(msg.cursorId);
|
let cursorList = this._cursors.get(mm);
|
||||||
this._cursors[mm].splice(index, 1);
|
let index = cursorList.indexOf(msg.cursorId);
|
||||||
|
cursorList.splice(index, 1);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (DEBUG) debug("Child is dead, DB should stop sending contacts");
|
if (DEBUG) debug("Child is dead, DB should stop sending contacts");
|
||||||
|
@ -240,11 +243,12 @@ let ContactService = {
|
||||||
if (DEBUG) debug("Unregister index: " + index);
|
if (DEBUG) debug("Unregister index: " + index);
|
||||||
this._children.splice(index, 1);
|
this._children.splice(index, 1);
|
||||||
}
|
}
|
||||||
if (this._cursors[mm]) {
|
cursorList = this._cursors.get(mm);
|
||||||
for (let id of this._cursors[mm]) {
|
if (cursorList) {
|
||||||
|
for (let id of cursorList) {
|
||||||
this._db.clearDispatcher(id);
|
this._db.clearDispatcher(id);
|
||||||
}
|
}
|
||||||
delete this._cursors[mm];
|
this._cursors.delete(mm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
|
[test_contacts_shutdown.xul]
|
||||||
|
skip-if = os == "android"
|
||||||
|
|
||||||
[test_contacts_upgrade.xul]
|
[test_contacts_upgrade.xul]
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||||
|
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<window title="Mozilla Bug 945948"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||||
|
|
||||||
|
<script type="application/javascript;version=1.7">
|
||||||
|
<![CDATA[
|
||||||
|
"use strict";
|
||||||
|
const { 'utils': Cu } = Components;
|
||||||
|
Cu.import("resource://gre/modules/ContactService.jsm", window);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mock message manager
|
||||||
|
//
|
||||||
|
function MockMessageManager() { }
|
||||||
|
MockMessageManager.prototype.assertPermission = function() { return true; };
|
||||||
|
MockMessageManager.prototype.sendAsyncMessage = function(name, data) { };
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mock ContactDB
|
||||||
|
//
|
||||||
|
function MockContactDB() { }
|
||||||
|
MockContactDB.prototype.getAll = function(cb) {
|
||||||
|
cb([]);
|
||||||
|
};
|
||||||
|
MockContactDB.prototype.clearDispatcher = function() { }
|
||||||
|
MockContactDB.prototype.close = function() { }
|
||||||
|
|
||||||
|
let realContactDB = ContactService._db;
|
||||||
|
|
||||||
|
function before() {
|
||||||
|
ok(true, "Install mock ContactDB object");
|
||||||
|
ContactService._db = new MockContactDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
function after() {
|
||||||
|
ok(true, "Restore real ContactDB object");
|
||||||
|
ContactService._db = realContactDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
function steps() {
|
||||||
|
let mm1 = new MockMessageManager();
|
||||||
|
let mm2 = new MockMessageManager();
|
||||||
|
|
||||||
|
is(ContactService._cursors.size, 0, "Verify clean contact init");
|
||||||
|
|
||||||
|
ContactService.receiveMessage({
|
||||||
|
target: mm1,
|
||||||
|
name: "Contacts:GetAll",
|
||||||
|
data: { cursorId: 1 },
|
||||||
|
findOptions: {}
|
||||||
|
});
|
||||||
|
is(ContactService._cursors.size, 1, "Add contact cursor 1");
|
||||||
|
|
||||||
|
ContactService.receiveMessage({
|
||||||
|
target: mm2,
|
||||||
|
name: "Contacts:GetAll",
|
||||||
|
data: { cursorId: 2 },
|
||||||
|
findOptions: {}
|
||||||
|
});
|
||||||
|
is(ContactService._cursors.size, 2, "Add contact cursor 2");
|
||||||
|
|
||||||
|
ContactService.receiveMessage({
|
||||||
|
target: mm1,
|
||||||
|
name: "child-process-shutdown"
|
||||||
|
});
|
||||||
|
is(ContactService._cursors.size, 1, "Shutdown contact cursor 1");
|
||||||
|
|
||||||
|
ContactService.receiveMessage({
|
||||||
|
target: mm2,
|
||||||
|
name: "child-process-shutdown"
|
||||||
|
});
|
||||||
|
is(ContactService._cursors.size, 0, "Shutdown contact cursor 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
try {
|
||||||
|
before();
|
||||||
|
steps();
|
||||||
|
} finally {
|
||||||
|
after();
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runTests();
|
||||||
|
]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=945948"
|
||||||
|
target="_blank">Mozilla Bug 945948</a>
|
||||||
|
</body>
|
||||||
|
</window>
|
|
@ -385,7 +385,6 @@ var interfaceNamesInGlobalScope =
|
||||||
"MozMobileMessageThread",
|
"MozMobileMessageThread",
|
||||||
"MozNamedAttrMap",
|
"MozNamedAttrMap",
|
||||||
{name: "MozNdefRecord", b2g: true},
|
{name: "MozNdefRecord", b2g: true},
|
||||||
{name: "MozNfc", b2g: true},
|
|
||||||
{name: "MozNFCPeer", b2g: true},
|
{name: "MozNFCPeer", b2g: true},
|
||||||
{name: "MozNFCTag", b2g: true},
|
{name: "MozNFCTag", b2g: true},
|
||||||
{name: "MozOtaStatusEvent", b2g: true, pref: "dom.mobileconnection.enabled"},
|
{name: "MozOtaStatusEvent", b2g: true, pref: "dom.mobileconnection.enabled"},
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
/* Copyright © 2013 Deutsche Telekom, Inc. */
|
/* Copyright © 2013 Deutsche Telekom, Inc. */
|
||||||
|
|
||||||
[JSImplementation="@mozilla.org/navigatorNfc;1",
|
[JSImplementation="@mozilla.org/navigatorNfc;1",
|
||||||
NavigatorProperty="mozNfc"]
|
NavigatorProperty="mozNfc",
|
||||||
|
Func="Navigator::HasNfcSupport"]
|
||||||
interface MozNfc : EventTarget {
|
interface MozNfc : EventTarget {
|
||||||
MozNFCTag getNFCTag(DOMString sessionId);
|
MozNFCTag getNFCTag(DOMString sessionId);
|
||||||
MozNFCPeer getNFCPeer(DOMString sessionId);
|
MozNFCPeer getNFCPeer(DOMString sessionId);
|
||||||
|
|
|
@ -175,7 +175,8 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
|
||||||
mIsFixedPosition(false),
|
mIsFixedPosition(false),
|
||||||
mMargins(0, 0, 0, 0),
|
mMargins(0, 0, 0, 0),
|
||||||
mStickyPositionData(nullptr),
|
mStickyPositionData(nullptr),
|
||||||
mIsScrollbar(false),
|
mScrollbarTargetId(FrameMetrics::NULL_SCROLL_ID),
|
||||||
|
mScrollbarDirection(ScrollDirection::NONE),
|
||||||
mDebugColorIndex(0),
|
mDebugColorIndex(0),
|
||||||
mAnimationGeneration(0)
|
mAnimationGeneration(0)
|
||||||
{}
|
{}
|
||||||
|
@ -1268,12 +1269,11 @@ Layer::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||||
if (GetContentFlags() & CONTENT_COMPONENT_ALPHA) {
|
if (GetContentFlags() & CONTENT_COMPONENT_ALPHA) {
|
||||||
aTo += " [componentAlpha]";
|
aTo += " [componentAlpha]";
|
||||||
}
|
}
|
||||||
if (GetIsScrollbar()) {
|
|
||||||
if (GetScrollbarDirection() == VERTICAL) {
|
if (GetScrollbarDirection() == VERTICAL) {
|
||||||
aTo.AppendPrintf(" [vscrollbar=%lld]", GetScrollbarTargetContainerId());
|
aTo.AppendPrintf(" [vscrollbar=%lld]", GetScrollbarTargetContainerId());
|
||||||
} else {
|
|
||||||
aTo.AppendPrintf(" [hscrollbar=%lld]", GetScrollbarTargetContainerId());
|
|
||||||
}
|
}
|
||||||
|
if (GetScrollbarDirection() == HORIZONTAL) {
|
||||||
|
aTo.AppendPrintf(" [hscrollbar=%lld]", GetScrollbarTargetContainerId());
|
||||||
}
|
}
|
||||||
if (GetIsFixedPosition()) {
|
if (GetIsFixedPosition()) {
|
||||||
aTo.AppendPrintf(" [isFixedPosition anchor=%f,%f]", mAnchor.x, mAnchor.y);
|
aTo.AppendPrintf(" [isFixedPosition anchor=%f,%f]", mAnchor.x, mAnchor.y);
|
||||||
|
|
|
@ -967,6 +967,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ScrollDirection {
|
enum ScrollDirection {
|
||||||
|
NONE,
|
||||||
VERTICAL,
|
VERTICAL,
|
||||||
HORIZONTAL
|
HORIZONTAL
|
||||||
};
|
};
|
||||||
|
@ -978,11 +979,9 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir)
|
void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir)
|
||||||
{
|
{
|
||||||
if (mIsScrollbar ||
|
if (mScrollbarTargetId != aScrollId ||
|
||||||
mScrollbarTargetId != aScrollId ||
|
|
||||||
mScrollbarDirection != aDir) {
|
mScrollbarDirection != aDir) {
|
||||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this));
|
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this));
|
||||||
mIsScrollbar = true;
|
|
||||||
mScrollbarTargetId = aScrollId;
|
mScrollbarTargetId = aScrollId;
|
||||||
mScrollbarDirection = aDir;
|
mScrollbarDirection = aDir;
|
||||||
Mutated();
|
Mutated();
|
||||||
|
@ -1013,7 +1012,6 @@ public:
|
||||||
FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
|
FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
|
||||||
const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
|
const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
|
||||||
const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
|
const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
|
||||||
bool GetIsScrollbar() { return mIsScrollbar; }
|
|
||||||
FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; }
|
FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; }
|
||||||
ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; }
|
ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; }
|
||||||
Layer* GetMaskLayer() const { return mMaskLayer; }
|
Layer* GetMaskLayer() const { return mMaskLayer; }
|
||||||
|
@ -1387,7 +1385,6 @@ protected:
|
||||||
LayerRect mInner;
|
LayerRect mInner;
|
||||||
};
|
};
|
||||||
nsAutoPtr<StickyPositionData> mStickyPositionData;
|
nsAutoPtr<StickyPositionData> mStickyPositionData;
|
||||||
bool mIsScrollbar;
|
|
||||||
FrameMetrics::ViewID mScrollbarTargetId;
|
FrameMetrics::ViewID mScrollbarTargetId;
|
||||||
ScrollDirection mScrollbarDirection;
|
ScrollDirection mScrollbarDirection;
|
||||||
DebugOnly<uint32_t> mDebugColorIndex;
|
DebugOnly<uint32_t> mDebugColorIndex;
|
||||||
|
|
|
@ -525,7 +525,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||||
appliedTransform = true;
|
appliedTransform = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container->GetIsScrollbar()) {
|
if (container->GetScrollbarDirection() != Layer::NONE) {
|
||||||
ApplyAsyncTransformToScrollbar(container);
|
ApplyAsyncTransformToScrollbar(container);
|
||||||
}
|
}
|
||||||
return appliedTransform;
|
return appliedTransform;
|
||||||
|
|
|
@ -1276,7 +1276,9 @@ void AsyncPanZoomController::RequestContentRepaint() {
|
||||||
mFrameMetrics.mScrollOffset.x) < EPSILON &&
|
mFrameMetrics.mScrollOffset.x) < EPSILON &&
|
||||||
fabsf(mLastPaintRequestMetrics.mScrollOffset.y -
|
fabsf(mLastPaintRequestMetrics.mScrollOffset.y -
|
||||||
mFrameMetrics.mScrollOffset.y) < EPSILON &&
|
mFrameMetrics.mScrollOffset.y) < EPSILON &&
|
||||||
mFrameMetrics.mZoom == mLastPaintRequestMetrics.mZoom) {
|
mFrameMetrics.mZoom == mLastPaintRequestMetrics.mZoom &&
|
||||||
|
fabsf(mFrameMetrics.mViewport.width - mLastPaintRequestMetrics.mViewport.width) < EPSILON &&
|
||||||
|
fabsf(mFrameMetrics.mViewport.height - mLastPaintRequestMetrics.mViewport.height) < EPSILON) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1463,8 +1465,10 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
|
||||||
aLayerMetrics.mCompositionBounds.height == mFrameMetrics.mCompositionBounds.height) {
|
aLayerMetrics.mCompositionBounds.height == mFrameMetrics.mCompositionBounds.height) {
|
||||||
// Remote content has sync'd up to the composition geometry
|
// Remote content has sync'd up to the composition geometry
|
||||||
// change, so we can accept the viewport it's calculated.
|
// change, so we can accept the viewport it's calculated.
|
||||||
if (mFrameMetrics.mViewport.width != aLayerMetrics.mViewport.width)
|
if (mFrameMetrics.mViewport.width != aLayerMetrics.mViewport.width ||
|
||||||
|
mFrameMetrics.mViewport.height != aLayerMetrics.mViewport.height) {
|
||||||
needContentRepaint = true;
|
needContentRepaint = true;
|
||||||
|
}
|
||||||
mFrameMetrics.mViewport = aLayerMetrics.mViewport;
|
mFrameMetrics.mViewport = aLayerMetrics.mViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,10 +280,8 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||||
common.stickyScrollRangeOuter(),
|
common.stickyScrollRangeOuter(),
|
||||||
common.stickyScrollRangeInner());
|
common.stickyScrollRangeInner());
|
||||||
}
|
}
|
||||||
if (common.isScrollbar()) {
|
|
||||||
layer->SetScrollbarData(common.scrollbarTargetContainerId(),
|
layer->SetScrollbarData(common.scrollbarTargetContainerId(),
|
||||||
static_cast<Layer::ScrollDirection>(common.scrollbarDirection()));
|
static_cast<Layer::ScrollDirection>(common.scrollbarDirection()));
|
||||||
}
|
|
||||||
if (PLayerParent* maskLayer = common.maskLayerParent()) {
|
if (PLayerParent* maskLayer = common.maskLayerParent()) {
|
||||||
layer->SetMaskLayer(cast(maskLayer)->AsLayer());
|
layer->SetMaskLayer(cast(maskLayer)->AsLayer());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -198,7 +198,6 @@ struct CommonLayerAttributes {
|
||||||
uint64_t stickyScrollContainerId;
|
uint64_t stickyScrollContainerId;
|
||||||
LayerRect stickyScrollRangeOuter;
|
LayerRect stickyScrollRangeOuter;
|
||||||
LayerRect stickyScrollRangeInner;
|
LayerRect stickyScrollRangeInner;
|
||||||
bool isScrollbar;
|
|
||||||
uint64_t scrollbarTargetContainerId;
|
uint64_t scrollbarTargetContainerId;
|
||||||
uint32_t scrollbarDirection;
|
uint32_t scrollbarDirection;
|
||||||
nullable PLayer maskLayer;
|
nullable PLayer maskLayer;
|
||||||
|
|
|
@ -501,11 +501,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, bool
|
||||||
common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter();
|
common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter();
|
||||||
common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner();
|
common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner();
|
||||||
}
|
}
|
||||||
common.isScrollbar() = mutant->GetIsScrollbar();
|
|
||||||
if (mutant->GetIsScrollbar()) {
|
|
||||||
common.scrollbarTargetContainerId() = mutant->GetScrollbarTargetContainerId();
|
common.scrollbarTargetContainerId() = mutant->GetScrollbarTargetContainerId();
|
||||||
common.scrollbarDirection() = mutant->GetScrollbarDirection();
|
common.scrollbarDirection() = mutant->GetScrollbarDirection();
|
||||||
}
|
|
||||||
if (Layer* maskLayer = mutant->GetMaskLayer()) {
|
if (Layer* maskLayer = mutant->GetMaskLayer()) {
|
||||||
common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer());
|
common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -66,544 +66,214 @@
|
||||||
#define LOG(args...) if (BTDEBUG) printf(args);
|
#define LOG(args...) if (BTDEBUG) printf(args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_INITIAL_POLLFD_COUNT 8
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
class DBusWatcher : public RawDBusConnection
|
class DBusWatcher : public MessageLoopForIO::Watcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DBusWatcher()
|
DBusWatcher(RawDBusConnection* aConnection, DBusWatch* aWatch)
|
||||||
{ }
|
: mConnection(aConnection),
|
||||||
|
mWatch(aWatch)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mConnection);
|
||||||
|
MOZ_ASSERT(mWatch);
|
||||||
|
}
|
||||||
|
|
||||||
~DBusWatcher()
|
~DBusWatcher()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool Initialize();
|
void StartWatching();
|
||||||
void CleanUp();
|
void StopWatching();
|
||||||
|
|
||||||
void WakeUp();
|
|
||||||
bool Stop();
|
|
||||||
|
|
||||||
bool Poll();
|
|
||||||
|
|
||||||
bool AddWatch(DBusWatch* aWatch);
|
|
||||||
void RemoveWatch(DBusWatch* aWatch);
|
|
||||||
|
|
||||||
void HandleWatchAdd();
|
|
||||||
void HandleWatchRemove();
|
|
||||||
|
|
||||||
// Information about the sockets we're polling. Socket counts
|
|
||||||
// increase/decrease depending on how many add/remove watch signals
|
|
||||||
// we're received via the control sockets.
|
|
||||||
nsTArray<pollfd> mPollData;
|
|
||||||
nsTArray<DBusWatch*> mWatchData;
|
|
||||||
|
|
||||||
// Sockets for receiving dbus control information (watch
|
|
||||||
// add/removes, loop shutdown, etc...)
|
|
||||||
ScopedClose mControlFdR;
|
|
||||||
ScopedClose mControlFdW;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct PollFdComparator {
|
|
||||||
bool Equals(const pollfd& a, const pollfd& b) const {
|
|
||||||
return ((a.fd == b.fd) && (a.events == b.events));
|
|
||||||
}
|
|
||||||
bool LessThan(const pollfd& a, const pollfd&b) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DBusEventTypes {
|
|
||||||
DBUS_EVENT_LOOP_EXIT = 1,
|
|
||||||
DBUS_EVENT_LOOP_ADD = 2,
|
|
||||||
DBUS_EVENT_LOOP_REMOVE = 3,
|
|
||||||
DBUS_EVENT_LOOP_WAKEUP = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned int UnixEventsToDBusFlags(short events);
|
|
||||||
static short DBusFlagsToUnixEvents(unsigned int flags);
|
|
||||||
|
|
||||||
|
static void FreeFunction(void* aData);
|
||||||
static dbus_bool_t AddWatchFunction(DBusWatch* aWatch, void* aData);
|
static dbus_bool_t AddWatchFunction(DBusWatch* aWatch, void* aData);
|
||||||
static void RemoveWatchFunction(DBusWatch* aWatch, void* aData);
|
static void RemoveWatchFunction(DBusWatch* aWatch, void* aData);
|
||||||
static void ToggleWatchFunction(DBusWatch* aWatch, void* aData);
|
static void ToggleWatchFunction(DBusWatch* aWatch, void* aData);
|
||||||
static void DBusWakeupFunction(void* aData);
|
|
||||||
|
|
||||||
bool SetUp();
|
RawDBusConnection* GetConnection();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnFileCanReadWithoutBlocking(int aFd);
|
||||||
|
void OnFileCanWriteWithoutBlocking(int aFd);
|
||||||
|
|
||||||
|
// Read watcher for libevent. Only to be accessed on IO Thread.
|
||||||
|
MessageLoopForIO::FileDescriptorWatcher mReadWatcher;
|
||||||
|
|
||||||
|
// Write watcher for libevent. Only to be accessed on IO Thread.
|
||||||
|
MessageLoopForIO::FileDescriptorWatcher mWriteWatcher;
|
||||||
|
|
||||||
|
// DBus structures
|
||||||
|
RawDBusConnection* mConnection;
|
||||||
|
DBusWatch* mWatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
RawDBusConnection*
|
||||||
DBusWatcher::Initialize()
|
DBusWatcher::GetConnection()
|
||||||
{
|
{
|
||||||
if (!SetUp()) {
|
return mConnection;
|
||||||
CleanUp();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void DBusWatcher::StartWatching()
|
||||||
DBusWatcher::CleanUp()
|
{
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mWatch);
|
||||||
|
|
||||||
|
int fd = dbus_watch_get_unix_fd(mWatch);
|
||||||
|
|
||||||
|
MessageLoopForIO* ioLoop = MessageLoopForIO::current();
|
||||||
|
ioLoop->WatchFileDescriptor(fd, true, MessageLoopForIO::WATCH_READ,
|
||||||
|
&mReadWatcher, this);
|
||||||
|
ioLoop->WatchFileDescriptor(fd, true, MessageLoopForIO::WATCH_WRITE,
|
||||||
|
&mWriteWatcher, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DBusWatcher::StopWatching()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
dbus_connection_set_wakeup_main_function(mConnection, nullptr,
|
mReadWatcher.StopWatchingFileDescriptor();
|
||||||
nullptr, nullptr);
|
mWriteWatcher.StopWatchingFileDescriptor();
|
||||||
dbus_bool_t success = dbus_connection_set_watch_functions(mConnection,
|
|
||||||
nullptr, nullptr,
|
|
||||||
nullptr, nullptr,
|
|
||||||
nullptr);
|
|
||||||
if (success != TRUE) {
|
|
||||||
NS_WARNING("dbus_connection_set_watch_functions failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
LOG("Removing DBus Sockets\n");
|
|
||||||
#endif
|
|
||||||
if (mControlFdW.get()) {
|
|
||||||
mControlFdW.dispose();
|
|
||||||
}
|
|
||||||
if (mControlFdR.get()) {
|
|
||||||
mControlFdR.dispose();
|
|
||||||
}
|
|
||||||
mPollData.Clear();
|
|
||||||
|
|
||||||
// DBusWatch pointers are maintained by DBus, so we won't leak by
|
|
||||||
// clearing.
|
|
||||||
mWatchData.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DBusWatcher::WakeUp()
|
|
||||||
{
|
|
||||||
static const char control = DBUS_EVENT_LOOP_WAKEUP;
|
|
||||||
|
|
||||||
struct pollfd fds = {
|
|
||||||
mControlFdW.get(),
|
|
||||||
POLLOUT,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
int nfds = TEMP_FAILURE_RETRY(poll(&fds, 1, 0));
|
|
||||||
NS_ENSURE_TRUE_VOID(nfds == 1);
|
|
||||||
NS_ENSURE_TRUE_VOID(fds.revents == POLLOUT);
|
|
||||||
|
|
||||||
ssize_t res = TEMP_FAILURE_RETRY(
|
|
||||||
write(mControlFdW.get(), &control, sizeof(control)));
|
|
||||||
if (res < 0) {
|
|
||||||
NS_WARNING("Cannot write wakeup bit to DBus controller!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DBusWatcher::Stop()
|
|
||||||
{
|
|
||||||
static const char data = DBUS_EVENT_LOOP_EXIT;
|
|
||||||
|
|
||||||
ssize_t res =
|
|
||||||
TEMP_FAILURE_RETRY(write(mControlFdW.get(), &data, sizeof(data)));
|
|
||||||
NS_ENSURE_TRUE(res == 1, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DBusWatcher::Poll()
|
|
||||||
{
|
|
||||||
int res = TEMP_FAILURE_RETRY(poll(mPollData.Elements(),
|
|
||||||
mPollData.Length(), -1));
|
|
||||||
NS_ENSURE_TRUE(res > 0, false);
|
|
||||||
|
|
||||||
bool continueThread = true;
|
|
||||||
|
|
||||||
nsTArray<pollfd>::size_type i = 0;
|
|
||||||
|
|
||||||
while (i < mPollData.Length()) {
|
|
||||||
if (mPollData[i].revents == POLLIN) {
|
|
||||||
if (mPollData[i].fd == mControlFdR.get()) {
|
|
||||||
char data;
|
|
||||||
res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &data, sizeof(data)));
|
|
||||||
NS_ENSURE_TRUE(res > 0, false);
|
|
||||||
|
|
||||||
switch (data) {
|
|
||||||
case DBUS_EVENT_LOOP_EXIT:
|
|
||||||
continueThread = false;
|
|
||||||
break;
|
|
||||||
case DBUS_EVENT_LOOP_ADD:
|
|
||||||
HandleWatchAdd();
|
|
||||||
break;
|
|
||||||
case DBUS_EVENT_LOOP_REMOVE:
|
|
||||||
HandleWatchRemove();
|
|
||||||
// don't increment i, or we'll skip one element
|
|
||||||
continue;
|
|
||||||
case DBUS_EVENT_LOOP_WAKEUP:
|
|
||||||
NS_ProcessPendingEvents(NS_GetCurrentThread(),
|
|
||||||
PR_INTERVAL_NO_TIMEOUT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
#if DEBUG
|
|
||||||
nsCString warning("unknown command ");
|
|
||||||
warning.AppendInt(data);
|
|
||||||
NS_WARNING(warning.get());
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
short events = mPollData[i].revents;
|
|
||||||
mPollData[i].revents = 0;
|
|
||||||
|
|
||||||
dbus_watch_handle(mWatchData[i], UnixEventsToDBusFlags(events));
|
|
||||||
|
|
||||||
DBusDispatchStatus dbusDispatchStatus;
|
|
||||||
do {
|
|
||||||
dbusDispatchStatus = dbus_connection_dispatch(GetConnection());
|
|
||||||
} while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS);
|
|
||||||
|
|
||||||
// Break at this point since we don't know if the operation
|
|
||||||
// was destructive
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return continueThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DBusWatcher::AddWatch(DBusWatch* aWatch)
|
|
||||||
{
|
|
||||||
static const char control = DBUS_EVENT_LOOP_ADD;
|
|
||||||
|
|
||||||
if (dbus_watch_get_enabled(aWatch) == FALSE) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note that we can't just send the watch and inspect it later
|
|
||||||
// because we may get a removeWatch call before this data is reacted
|
|
||||||
// to by our eventloop and remove this watch.. reading the add first
|
|
||||||
// and then inspecting the recently deceased watch would be bad.
|
|
||||||
ssize_t res =
|
|
||||||
TEMP_FAILURE_RETRY(write(mControlFdW.get(),&control, sizeof(control)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus add watch control data to socket!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = dbus_watch_get_unix_fd(aWatch);
|
|
||||||
res = TEMP_FAILURE_RETRY(write(mControlFdW.get(), &fd, sizeof(fd)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus add watch descriptor data to socket!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int flags = dbus_watch_get_flags(aWatch);
|
|
||||||
res = TEMP_FAILURE_RETRY(write(mControlFdW.get(), &flags, sizeof(flags)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus add watch flag data to socket!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = TEMP_FAILURE_RETRY(write(mControlFdW.get(), &aWatch, sizeof(aWatch)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus add watch struct data to socket!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DBusWatcher::RemoveWatch(DBusWatch* aWatch)
|
|
||||||
{
|
|
||||||
static const char control = DBUS_EVENT_LOOP_REMOVE;
|
|
||||||
|
|
||||||
ssize_t res =
|
|
||||||
TEMP_FAILURE_RETRY(write(mControlFdW.get(), &control, sizeof(control)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus remove watch control data to socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = dbus_watch_get_unix_fd(aWatch);
|
|
||||||
res = TEMP_FAILURE_RETRY(write(mControlFdW.get(), &fd, sizeof(fd)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus remove watch descriptor data to socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int flags = dbus_watch_get_flags(aWatch);
|
|
||||||
res = TEMP_FAILURE_RETRY(write(mControlFdW.get(), &flags, sizeof(flags)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot write DBus remove watch flag data to socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DBusWatcher::HandleWatchAdd()
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
ssize_t res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &fd, sizeof(fd)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot read DBus watch add descriptor data from socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int flags;
|
|
||||||
res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &flags, sizeof(flags)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot read DBus watch add flag data from socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusWatch* watch;
|
|
||||||
res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &watch, sizeof(watch)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot read DBus watch add watch data from socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pollfd p = {
|
|
||||||
fd, // .fd
|
|
||||||
DBusFlagsToUnixEvents(flags), // .events
|
|
||||||
0 // .revents
|
|
||||||
};
|
|
||||||
if (mPollData.Contains(p, PollFdComparator())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mPollData.AppendElement(p);
|
|
||||||
mWatchData.AppendElement(watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DBusWatcher::HandleWatchRemove()
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
ssize_t res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &fd, sizeof(fd)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot read DBus watch remove descriptor data from socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int flags;
|
|
||||||
res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &flags, sizeof(flags)));
|
|
||||||
if (res < 0) {
|
|
||||||
LOG("Cannot read DBus watch remove flag data from socket!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pollfd p = {
|
|
||||||
fd, // .fd
|
|
||||||
DBusFlagsToUnixEvents(flags), // .events
|
|
||||||
0 // .revents
|
|
||||||
};
|
|
||||||
int index = mPollData.IndexOf(p, 0, PollFdComparator());
|
|
||||||
// There are times where removes can be requested for watches that
|
|
||||||
// haven't been added (for example, whenever gecko comes up after
|
|
||||||
// adapters have already been enabled), so check to make sure we're
|
|
||||||
// using the watch in the first place
|
|
||||||
if (index < 0) {
|
|
||||||
LOG("DBus requested watch removal of non-existant socket, ignoring...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mPollData.RemoveElementAt(index);
|
|
||||||
|
|
||||||
// DBusWatch pointers are maintained by DBus, so we won't leak by
|
|
||||||
// removing.
|
|
||||||
mWatchData.RemoveElementAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flag conversion
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
DBusWatcher::UnixEventsToDBusFlags(short events)
|
|
||||||
{
|
|
||||||
return (events & DBUS_WATCH_READABLE ? POLLIN : 0) |
|
|
||||||
(events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) |
|
|
||||||
(events & DBUS_WATCH_ERROR ? POLLERR : 0) |
|
|
||||||
(events & DBUS_WATCH_HANGUP ? POLLHUP : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
short
|
|
||||||
DBusWatcher::DBusFlagsToUnixEvents(unsigned int flags)
|
|
||||||
{
|
|
||||||
return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) |
|
|
||||||
(flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) |
|
|
||||||
(flags & POLLERR ? DBUS_WATCH_ERROR : 0) |
|
|
||||||
(flags & POLLHUP ? DBUS_WATCH_HANGUP : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBus utility functions, used as function pointers in DBus setup
|
// DBus utility functions, used as function pointers in DBus setup
|
||||||
|
|
||||||
|
void
|
||||||
|
DBusWatcher::FreeFunction(void* aData)
|
||||||
|
{
|
||||||
|
delete static_cast<DBusWatcher*>(aData);
|
||||||
|
}
|
||||||
|
|
||||||
dbus_bool_t
|
dbus_bool_t
|
||||||
DBusWatcher::AddWatchFunction(DBusWatch* aWatch, void* aData)
|
DBusWatcher::AddWatchFunction(DBusWatch* aWatch, void* aData)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aData);
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
DBusWatcher* dbusWatcher = static_cast<DBusWatcher*>(aData);
|
|
||||||
return dbusWatcher->AddWatch(aWatch);
|
RawDBusConnection* connection = static_cast<RawDBusConnection*>(aData);
|
||||||
|
|
||||||
|
DBusWatcher* dbusWatcher = new DBusWatcher(connection, aWatch);
|
||||||
|
dbus_watch_set_data(aWatch, dbusWatcher, DBusWatcher::FreeFunction);
|
||||||
|
|
||||||
|
if (dbus_watch_get_enabled(aWatch)) {
|
||||||
|
dbusWatcher->StartWatching();
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DBusWatcher::RemoveWatchFunction(DBusWatch* aWatch, void* aData)
|
DBusWatcher::RemoveWatchFunction(DBusWatch* aWatch, void* aData)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aData);
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
DBusWatcher* dbusWatcher = static_cast<DBusWatcher*>(aData);
|
|
||||||
dbusWatcher->RemoveWatch(aWatch);
|
DBusWatcher* dbusWatcher =
|
||||||
|
static_cast<DBusWatcher*>(dbus_watch_get_data(aWatch));
|
||||||
|
dbusWatcher->StopWatching();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DBusWatcher::ToggleWatchFunction(DBusWatch* aWatch, void* aData)
|
DBusWatcher::ToggleWatchFunction(DBusWatch* aWatch, void* aData)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aData);
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
DBusWatcher* dbusWatcher = static_cast<DBusWatcher*>(aData);
|
|
||||||
|
DBusWatcher* dbusWatcher =
|
||||||
|
static_cast<DBusWatcher*>(dbus_watch_get_data(aWatch));
|
||||||
|
|
||||||
if (dbus_watch_get_enabled(aWatch)) {
|
if (dbus_watch_get_enabled(aWatch)) {
|
||||||
dbusWatcher->AddWatch(aWatch);
|
dbusWatcher->StartWatching();
|
||||||
} else {
|
} else {
|
||||||
dbusWatcher->RemoveWatch(aWatch);
|
dbusWatcher->StopWatching();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DBusWatcher::DBusWakeupFunction(void* aData)
|
DBusWatcher::OnFileCanReadWithoutBlocking(int aFd)
|
||||||
{
|
|
||||||
MOZ_ASSERT(aData);
|
|
||||||
DBusWatcher* dbusWatcher = static_cast<DBusWatcher*>(aData);
|
|
||||||
dbusWatcher->WakeUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DBusWatcher::SetUp()
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
// If we already have a connection, exit
|
dbus_watch_handle(mWatch, DBUS_WATCH_READABLE);
|
||||||
if (mConnection) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// socketpair opens two sockets for the process to communicate on.
|
DBusDispatchStatus dbusDispatchStatus;
|
||||||
// This is how android's implementation of the dbus event loop
|
do {
|
||||||
// communicates with itself in relation to IPC signals. These
|
dbusDispatchStatus =
|
||||||
// sockets are contained sequentially in the same struct in the
|
dbus_connection_dispatch(mConnection->GetConnection());
|
||||||
// android code, but we break them out into class members here.
|
} while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS);
|
||||||
// Therefore we read into a local array and then copy.
|
|
||||||
|
|
||||||
int sockets[2];
|
|
||||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets) < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mControlFdR.rwget() = sockets[0];
|
|
||||||
mControlFdW.rwget() = sockets[1];
|
|
||||||
|
|
||||||
pollfd* p = mPollData.AppendElement();
|
|
||||||
|
|
||||||
p->fd = mControlFdR.get();
|
|
||||||
p->events = POLLIN;
|
|
||||||
p->revents = 0;
|
|
||||||
|
|
||||||
// Due to the fact that mPollData and mWatchData have to match, we
|
|
||||||
// push a null to the front of mWatchData since it has the control
|
|
||||||
// fd in the first slot of mPollData.
|
|
||||||
|
|
||||||
mWatchData.AppendElement(static_cast<DBusWatch*>(nullptr));
|
|
||||||
|
|
||||||
// If we can't establish a connection to dbus, nothing else will work
|
|
||||||
nsresult rv = EstablishDBusConnection();
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Cannot create DBus Connection for DBus Thread!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbus_bool_t success =
|
|
||||||
dbus_connection_set_watch_functions(mConnection, AddWatchFunction,
|
|
||||||
RemoveWatchFunction,
|
|
||||||
ToggleWatchFunction, this, nullptr);
|
|
||||||
NS_ENSURE_TRUE(success == TRUE, false);
|
|
||||||
|
|
||||||
dbus_connection_set_wakeup_main_function(mConnection, DBusWakeupFunction,
|
|
||||||
this, nullptr);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main task for polling the DBus system
|
void
|
||||||
|
DBusWatcher::OnFileCanWriteWithoutBlocking(int aFd)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
class DBusPollTask : public nsRunnable
|
dbus_watch_handle(mWatch, DBUS_WATCH_WRITABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
class WatchDBusConnectionTask : public Task
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DBusPollTask(DBusWatcher* aDBusWatcher)
|
WatchDBusConnectionTask(RawDBusConnection* aConnection)
|
||||||
: mDBusWatcher(aDBusWatcher)
|
: mConnection(aConnection)
|
||||||
{ }
|
{
|
||||||
|
MOZ_ASSERT(mConnection);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
void Run()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
bool continueThread;
|
dbus_bool_t success =
|
||||||
|
dbus_connection_set_watch_functions(mConnection->GetConnection(),
|
||||||
do {
|
DBusWatcher::AddWatchFunction,
|
||||||
continueThread = mDBusWatcher->Poll();
|
DBusWatcher::RemoveWatchFunction,
|
||||||
} while (continueThread);
|
DBusWatcher::ToggleWatchFunction,
|
||||||
|
mConnection, nullptr);
|
||||||
mDBusWatcher->CleanUp();
|
NS_ENSURE_TRUE_VOID(success == TRUE);
|
||||||
|
|
||||||
nsIThread* thread;
|
|
||||||
nsresult rv = NS_GetCurrentThread(&thread);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsRefPtr<nsIRunnable> runnable =
|
|
||||||
NS_NewRunnableMethod(thread, &nsIThread::Shutdown);
|
|
||||||
rv = NS_DispatchToMainThread(runnable);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<DBusWatcher> mDBusWatcher;
|
RawDBusConnection* mConnection;
|
||||||
};
|
};
|
||||||
|
|
||||||
static StaticRefPtr<DBusWatcher> gDBusWatcher;
|
class DeleteDBusConnectionTask : public Task
|
||||||
static StaticRefPtr<nsIThread> gDBusServiceThread;
|
{
|
||||||
|
public:
|
||||||
|
DeleteDBusConnectionTask(RawDBusConnection* aConnection)
|
||||||
|
: mConnection(aConnection)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mConnection);
|
||||||
|
}
|
||||||
|
|
||||||
// Startup/Shutdown utility functions
|
void Run()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
|
// This command closes the DBus connection and all instances of
|
||||||
|
// DBusWatch will be removed and free'd.
|
||||||
|
delete mConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RawDBusConnection* mConnection;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Startup/Shutdown utility functions
|
||||||
|
|
||||||
|
static RawDBusConnection* gDBusConnection;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StartDBus()
|
StartDBus()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
NS_ENSURE_TRUE(!gDBusWatcher, true);
|
NS_ENSURE_TRUE(!gDBusConnection, true);
|
||||||
|
|
||||||
nsRefPtr<DBusWatcher> dbusWatcher(new DBusWatcher());
|
RawDBusConnection* connection = new RawDBusConnection();
|
||||||
|
nsresult rv = connection->EstablishDBusConnection();
|
||||||
bool eventLoopStarted = dbusWatcher->Initialize();
|
|
||||||
NS_ENSURE_TRUE(eventLoopStarted, false);
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (!gDBusServiceThread) {
|
|
||||||
nsIThread* dbusServiceThread;
|
|
||||||
rv = NS_NewNamedThread("DBus Thread", &dbusServiceThread);
|
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
|
||||||
gDBusServiceThread = dbusServiceThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
LOG("DBus Thread Starting\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsRefPtr<nsIRunnable> pollTask(new DBusPollTask(dbusWatcher));
|
|
||||||
NS_ENSURE_TRUE(pollTask, false);
|
|
||||||
|
|
||||||
rv = gDBusServiceThread->Dispatch(pollTask, NS_DISPATCH_NORMAL);
|
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
gDBusWatcher = dbusWatcher;
|
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||||
|
new WatchDBusConnectionTask(connection));
|
||||||
|
|
||||||
|
gDBusConnection = connection;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -612,36 +282,32 @@ bool
|
||||||
StopDBus()
|
StopDBus()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
NS_ENSURE_TRUE(gDBusServiceThread, true);
|
NS_ENSURE_TRUE(gDBusConnection, true);
|
||||||
|
|
||||||
nsRefPtr<DBusWatcher> dbusWatcher(gDBusWatcher);
|
RawDBusConnection* connection = gDBusConnection;
|
||||||
gDBusWatcher = nullptr;
|
gDBusConnection = nullptr;
|
||||||
|
|
||||||
if (dbusWatcher && !dbusWatcher->Stop()) {
|
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||||
return false;
|
new DeleteDBusConnectionTask(connection));
|
||||||
}
|
|
||||||
|
|
||||||
gDBusServiceThread = nullptr;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
DispatchToDBusThread(nsIRunnable* event)
|
DispatchToDBusThread(Task* task)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsIThread> dbusServiceThread(gDBusServiceThread);
|
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, task);
|
||||||
nsRefPtr<DBusWatcher> dbusWatcher(gDBusWatcher);
|
|
||||||
|
|
||||||
NS_ENSURE_TRUE(dbusServiceThread.get() && dbusWatcher.get(),
|
|
||||||
NS_ERROR_NOT_INITIALIZED);
|
|
||||||
|
|
||||||
nsresult rv = dbusServiceThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
dbusWatcher->WakeUp();
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawDBusConnection*
|
||||||
|
GetDBusConnection()
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(gDBusConnection, nullptr);
|
||||||
|
|
||||||
|
return gDBusConnection;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,13 @@
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
|
||||||
class nsIRunnable;
|
class Task;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
|
class RawDBusConnection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the DBus thread, which handles returning signals to objects
|
* Starts the DBus thread, which handles returning signals to objects
|
||||||
* that call asynchronous functions. This should be called from the
|
* that call asynchronous functions. This should be called from the
|
||||||
|
@ -32,13 +34,21 @@ bool StartDBus();
|
||||||
bool StopDBus();
|
bool StopDBus();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch an event to the DBus thread
|
* Dispatch a task to the DBus I/O thread
|
||||||
*
|
*
|
||||||
* @param event An nsIRunnable to run in the DBus thread
|
* @param task A task to run on the DBus I/O thread
|
||||||
* @return NS_OK on success, or an error code otherwise
|
* @return NS_OK on success, or an error code otherwise
|
||||||
*/
|
*/
|
||||||
nsresult
|
nsresult
|
||||||
DispatchToDBusThread(nsIRunnable* event);
|
DispatchToDBusThread(Task* task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection to the DBus server
|
||||||
|
*
|
||||||
|
* @return The DBus connection on success, or nullptr otherwise
|
||||||
|
*/
|
||||||
|
RawDBusConnection*
|
||||||
|
GetDBusConnection(void);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
#include "base/message_loop.h"
|
||||||
#include "mozilla/Monitor.h"
|
#include "mozilla/Monitor.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "DBusThread.h"
|
#include "DBusThread.h"
|
||||||
|
@ -34,10 +35,14 @@ using namespace mozilla::ipc;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
class DBusConnectionSendRunnableBase : public nsRunnable
|
class DBusConnectionSendTaskBase : public Task
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual ~DBusConnectionSendTaskBase()
|
||||||
|
{ }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DBusConnectionSendRunnableBase(DBusConnection* aConnection,
|
DBusConnectionSendTaskBase(DBusConnection* aConnection,
|
||||||
DBusMessage* aMessage)
|
DBusMessage* aMessage)
|
||||||
: mConnection(aConnection),
|
: mConnection(aConnection),
|
||||||
mMessage(aMessage)
|
mMessage(aMessage)
|
||||||
|
@ -46,9 +51,6 @@ protected:
|
||||||
MOZ_ASSERT(mMessage);
|
MOZ_ASSERT(mMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DBusConnectionSendRunnableBase()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
DBusConnection* mConnection;
|
DBusConnection* mConnection;
|
||||||
DBusMessageRefPtr mMessage;
|
DBusMessageRefPtr mMessage;
|
||||||
};
|
};
|
||||||
|
@ -57,35 +59,33 @@ protected:
|
||||||
// Sends a message and returns the message's serial number to the
|
// Sends a message and returns the message's serial number to the
|
||||||
// disaptching thread. Only run it in DBus thread.
|
// disaptching thread. Only run it in DBus thread.
|
||||||
//
|
//
|
||||||
class DBusConnectionSendRunnable : public DBusConnectionSendRunnableBase
|
class DBusConnectionSendTask : public DBusConnectionSendTaskBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DBusConnectionSendRunnable(DBusConnection* aConnection,
|
DBusConnectionSendTask(DBusConnection* aConnection,
|
||||||
DBusMessage* aMessage)
|
DBusMessage* aMessage)
|
||||||
: DBusConnectionSendRunnableBase(aConnection, aMessage)
|
: DBusConnectionSendTaskBase(aConnection, aMessage)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
virtual ~DBusConnectionSendTask()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void Run() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(MessageLoop::current());
|
||||||
|
|
||||||
dbus_bool_t success = dbus_connection_send(mConnection, mMessage, nullptr);
|
dbus_bool_t success = dbus_connection_send(mConnection,
|
||||||
|
mMessage,
|
||||||
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
|
nullptr);
|
||||||
|
NS_ENSURE_TRUE_VOID(success == TRUE);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
~DBusConnectionSendRunnable()
|
|
||||||
{ }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sends a message and executes a callback function for the reply. Only
|
// Sends a message and executes a callback function for the reply. Only
|
||||||
// run it in DBus thread.
|
// run it in DBus thread.
|
||||||
//
|
//
|
||||||
class DBusConnectionSendWithReplyRunnable : public DBusConnectionSendRunnableBase
|
class DBusConnectionSendWithReplyTask : public DBusConnectionSendTaskBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
class NotifyData
|
class NotifyData
|
||||||
|
@ -130,24 +130,27 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DBusConnectionSendWithReplyRunnable(DBusConnection* aConnection,
|
DBusConnectionSendWithReplyTask(DBusConnection* aConnection,
|
||||||
DBusMessage* aMessage,
|
DBusMessage* aMessage,
|
||||||
int aTimeout,
|
int aTimeout,
|
||||||
DBusReplyCallback aCallback,
|
DBusReplyCallback aCallback,
|
||||||
void* aData)
|
void* aData)
|
||||||
: DBusConnectionSendRunnableBase(aConnection, aMessage),
|
: DBusConnectionSendTaskBase(aConnection, aMessage),
|
||||||
mCallback(aCallback),
|
mCallback(aCallback),
|
||||||
mData(aData),
|
mData(aData),
|
||||||
mTimeout(aTimeout)
|
mTimeout(aTimeout)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
virtual ~DBusConnectionSendWithReplyTask()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void Run() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(MessageLoop::current());
|
||||||
|
|
||||||
// Freed at end of Notify
|
// Freed at end of Notify
|
||||||
nsAutoPtr<NotifyData> data(new NotifyData(mCallback, mData));
|
nsAutoPtr<NotifyData> data(new NotifyData(mCallback, mData));
|
||||||
NS_ENSURE_TRUE(data, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE_VOID(data);
|
||||||
|
|
||||||
DBusPendingCall* call;
|
DBusPendingCall* call;
|
||||||
|
|
||||||
|
@ -155,21 +158,15 @@ public:
|
||||||
mMessage,
|
mMessage,
|
||||||
&call,
|
&call,
|
||||||
mTimeout);
|
mTimeout);
|
||||||
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE_VOID(success == TRUE);
|
||||||
|
|
||||||
success = dbus_pending_call_set_notify(call, Notify, data, nullptr);
|
success = dbus_pending_call_set_notify(call, Notify, data, nullptr);
|
||||||
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE_VOID(success == TRUE);
|
||||||
|
|
||||||
data.forget();
|
data.forget();
|
||||||
dbus_message_unref(mMessage);
|
dbus_message_unref(mMessage);
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
|
||||||
~DBusConnectionSendWithReplyRunnable()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DBusReplyCallback mCallback;
|
DBusReplyCallback mCallback;
|
||||||
void* mData;
|
void* mData;
|
||||||
|
@ -202,7 +199,7 @@ nsresult RawDBusConnection::EstablishDBusConnection()
|
||||||
}
|
}
|
||||||
DBusError err;
|
DBusError err;
|
||||||
dbus_error_init(&err);
|
dbus_error_init(&err);
|
||||||
mConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
|
mConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
|
||||||
if (dbus_error_is_set(&err)) {
|
if (dbus_error_is_set(&err)) {
|
||||||
dbus_error_free(&err);
|
dbus_error_free(&err);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
@ -214,14 +211,15 @@ nsresult RawDBusConnection::EstablishDBusConnection()
|
||||||
void RawDBusConnection::ScopedDBusConnectionPtrTraits::release(DBusConnection* ptr)
|
void RawDBusConnection::ScopedDBusConnectionPtrTraits::release(DBusConnection* ptr)
|
||||||
{
|
{
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
dbus_connection_close(ptr);
|
||||||
dbus_connection_unref(ptr);
|
dbus_connection_unref(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawDBusConnection::Send(DBusMessage* aMessage)
|
bool RawDBusConnection::Send(DBusMessage* aMessage)
|
||||||
{
|
{
|
||||||
nsRefPtr<DBusConnectionSendRunnable> t(
|
DBusConnectionSendTask* t =
|
||||||
new DBusConnectionSendRunnable(mConnection, aMessage));
|
new DBusConnectionSendTask(mConnection, aMessage);
|
||||||
MOZ_ASSERT(t);
|
MOZ_ASSERT(t);
|
||||||
|
|
||||||
nsresult rv = DispatchToDBusThread(t);
|
nsresult rv = DispatchToDBusThread(t);
|
||||||
|
@ -241,9 +239,9 @@ bool RawDBusConnection::SendWithReply(DBusReplyCallback aCallback,
|
||||||
int aTimeout,
|
int aTimeout,
|
||||||
DBusMessage* aMessage)
|
DBusMessage* aMessage)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsIRunnable> t(
|
DBusConnectionSendWithReplyTask* t =
|
||||||
new DBusConnectionSendWithReplyRunnable(mConnection, aMessage,
|
new DBusConnectionSendWithReplyTask(mConnection, aMessage, aTimeout,
|
||||||
aTimeout, aCallback, aData));
|
aCallback, aData);
|
||||||
MOZ_ASSERT(t);
|
MOZ_ASSERT(t);
|
||||||
|
|
||||||
nsresult rv = DispatchToDBusThread(t);
|
nsresult rv = DispatchToDBusThread(t);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "mozilla/Scoped.h"
|
#include "mozilla/Scoped.h"
|
||||||
#include <mozilla/RefPtr.h>
|
|
||||||
#include <mozilla/Mutex.h>
|
#include <mozilla/Mutex.h>
|
||||||
|
|
||||||
struct DBusConnection;
|
struct DBusConnection;
|
||||||
|
@ -26,7 +25,7 @@ namespace ipc {
|
||||||
|
|
||||||
typedef void (*DBusReplyCallback)(DBusMessage*, void*);
|
typedef void (*DBusReplyCallback)(DBusMessage*, void*);
|
||||||
|
|
||||||
class RawDBusConnection : public AtomicRefCounted<RawDBusConnection>
|
class RawDBusConnection
|
||||||
{
|
{
|
||||||
struct ScopedDBusConnectionPtrTraits : ScopedFreePtrTraits<DBusConnection>
|
struct ScopedDBusConnectionPtrTraits : ScopedFreePtrTraits<DBusConnection>
|
||||||
{
|
{
|
||||||
|
|
|
@ -215,4 +215,41 @@ nsFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
PrintDisplayListTo(aBuilder, aList, aFile, aDumpHtml);
|
PrintDisplayListTo(aBuilder, aList, aFile, aDumpHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
PrintDisplayListSetItem(nsDisplayListBuilder* aBuilder,
|
||||||
|
const char* aItemName,
|
||||||
|
const nsDisplayList& aList,
|
||||||
|
FILE* aFile,
|
||||||
|
bool aDumpHtml)
|
||||||
|
{
|
||||||
|
if (aDumpHtml) {
|
||||||
|
fprintf_stderr(aFile, "<li>");
|
||||||
|
}
|
||||||
|
fprintf_stderr(aFile, "%s", aItemName);
|
||||||
|
PrintDisplayListTo(aBuilder, aList, aFile, aDumpHtml);
|
||||||
|
if (aDumpHtml) {
|
||||||
|
fprintf_stderr(aFile, "</li>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsFrame::PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayListSet& aSet,
|
||||||
|
FILE *aFile,
|
||||||
|
bool aDumpHtml)
|
||||||
|
{
|
||||||
|
if (aDumpHtml) {
|
||||||
|
fprintf_stderr(aFile, "<ul>");
|
||||||
|
}
|
||||||
|
PrintDisplayListSetItem(aBuilder, "[BorderBackground]", *(aSet.BorderBackground()), aFile, aDumpHtml);
|
||||||
|
PrintDisplayListSetItem(aBuilder, "[BlockBorderBackgrounds]", *(aSet.BlockBorderBackgrounds()), aFile, aDumpHtml);
|
||||||
|
PrintDisplayListSetItem(aBuilder, "[Floats]", *(aSet.Floats()), aFile, aDumpHtml);
|
||||||
|
PrintDisplayListSetItem(aBuilder, "[PositionedDescendants]", *(aSet.PositionedDescendants()), aFile, aDumpHtml);
|
||||||
|
PrintDisplayListSetItem(aBuilder, "[Outlines]", *(aSet.Outlines()), aFile, aDumpHtml);
|
||||||
|
PrintDisplayListSetItem(aBuilder, "[Content]", *(aSet.Content()), aFile, aDumpHtml);
|
||||||
|
if (aDumpHtml) {
|
||||||
|
fprintf_stderr(aFile, "</ul>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -713,6 +713,10 @@ public:
|
||||||
const nsDisplayList& aList,
|
const nsDisplayList& aList,
|
||||||
FILE* aFile = stdout,
|
FILE* aFile = stdout,
|
||||||
bool aDumpHtml = false);
|
bool aDumpHtml = false);
|
||||||
|
static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayListSet& aList,
|
||||||
|
FILE* aFile = stdout,
|
||||||
|
bool aDumpHtml = false);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[include:dom/mobilemessage/tests/xpcshell.ini]
|
[include:dom/mobilemessage/tests/xpcshell.ini]
|
||||||
[include:dom/network/tests/unit_stats/xpcshell.ini]
|
[include:dom/network/tests/unit_stats/xpcshell.ini]
|
||||||
[include:dom/system/gonk/tests/xpcshell.ini]
|
[include:dom/system/gonk/tests/xpcshell.ini]
|
||||||
|
[include:dom/wappush/tests/xpcshell.ini]
|
||||||
[include:toolkit/devtools/apps/tests/unit/xpcshell.ini]
|
[include:toolkit/devtools/apps/tests/unit/xpcshell.ini]
|
||||||
[include:toolkit/devtools/debugger/tests/unit/xpcshell.ini]
|
[include:toolkit/devtools/debugger/tests/unit/xpcshell.ini]
|
||||||
[include:toolkit/devtools/sourcemap/tests/unit/xpcshell.ini]
|
[include:toolkit/devtools/sourcemap/tests/unit/xpcshell.ini]
|
||||||
|
|
|
@ -64,6 +64,7 @@ HwcComposer2D::HwcComposer2D()
|
||||||
, mColorFill(false)
|
, mColorFill(false)
|
||||||
, mRBSwapSupport(false)
|
, mRBSwapSupport(false)
|
||||||
, mPrevRetireFence(-1)
|
, mPrevRetireFence(-1)
|
||||||
|
, mPrepared(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +452,6 @@ HwcComposer2D::TryHwComposition()
|
||||||
|
|
||||||
if (!(fbsurface && fbsurface->lastHandle)) {
|
if (!(fbsurface && fbsurface->lastHandle)) {
|
||||||
LOGD("H/W Composition failed. FBSurface not initialized.");
|
LOGD("H/W Composition failed. FBSurface not initialized.");
|
||||||
mList->numHwLayers = 0;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +460,6 @@ HwcComposer2D::TryHwComposition()
|
||||||
if (idx >= mMaxLayerCount) {
|
if (idx >= mMaxLayerCount) {
|
||||||
if (!ReallocLayerList() || idx >= mMaxLayerCount) {
|
if (!ReallocLayerList() || idx >= mMaxLayerCount) {
|
||||||
LOGE("TryHwComposition failed! Could not add FB layer");
|
LOGE("TryHwComposition failed! Could not add FB layer");
|
||||||
mList->numHwLayers = 0;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,7 +494,6 @@ HwcComposer2D::TryHwComposition()
|
||||||
|
|
||||||
// No composition on FB layer, so closing releaseFenceFd
|
// No composition on FB layer, so closing releaseFenceFd
|
||||||
close(mList->hwLayers[idx].releaseFenceFd);
|
close(mList->hwLayers[idx].releaseFenceFd);
|
||||||
mList->numHwLayers = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +513,7 @@ HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mList->numHwLayers != 0) {
|
if (mPrepared) {
|
||||||
// No mHwc prepare, if already prepared in current draw cycle
|
// No mHwc prepare, if already prepared in current draw cycle
|
||||||
mList->hwLayers[mList->numHwLayers - 1].handle = fbsurface->lastHandle;
|
mList->hwLayers[mList->numHwLayers - 1].handle = fbsurface->lastHandle;
|
||||||
mList->hwLayers[mList->numHwLayers - 1].acquireFenceFd = fbsurface->lastFenceFD;
|
mList->hwLayers[mList->numHwLayers - 1].acquireFenceFd = fbsurface->lastFenceFD;
|
||||||
|
@ -535,7 +533,6 @@ HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
|
||||||
Commit();
|
Commit();
|
||||||
|
|
||||||
GetGonkDisplay()->SetFBReleaseFd(mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd);
|
GetGonkDisplay()->SetFBReleaseFd(mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd);
|
||||||
mList->numHwLayers = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +563,11 @@ HwcComposer2D::Prepare(buffer_handle_t fbHandle, int fence)
|
||||||
mList->hwLayers[idx].releaseFenceFd = -1;
|
mList->hwLayers[idx].releaseFenceFd = -1;
|
||||||
mList->hwLayers[idx].planeAlpha = 0xFF;
|
mList->hwLayers[idx].planeAlpha = 0xFF;
|
||||||
|
|
||||||
|
if (mPrepared) {
|
||||||
|
LOGE("Multiple hwc prepare calls!");
|
||||||
|
}
|
||||||
mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
||||||
|
mPrepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -609,8 +610,19 @@ HwcComposer2D::Commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPrepared = false;
|
||||||
return !err;
|
return !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HwcComposer2D::Reset()
|
||||||
|
{
|
||||||
|
LOGD("hwcomposer is already prepared, reset with null set");
|
||||||
|
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr };
|
||||||
|
displays[HWC_DISPLAY_PRIMARY] = nullptr;
|
||||||
|
mHwc->set(mHwc, HWC_DISPLAY_PRIMARY, displays);
|
||||||
|
mPrepared = false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
bool
|
bool
|
||||||
HwcComposer2D::TryHwComposition()
|
HwcComposer2D::TryHwComposition()
|
||||||
|
@ -623,6 +635,12 @@ HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
|
||||||
{
|
{
|
||||||
return GetGonkDisplay()->SwapBuffers(dpy, sur);
|
return GetGonkDisplay()->SwapBuffers(dpy, sur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HwcComposer2D::Reset()
|
||||||
|
{
|
||||||
|
mPrepared = false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -640,6 +658,10 @@ HwcComposer2D::TryRender(Layer* aRoot,
|
||||||
mHwcLayerMap.Clear();
|
mHwcLayerMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mPrepared) {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: The clear() below means all rect vectors will be have to be
|
// XXX: The clear() below means all rect vectors will be have to be
|
||||||
// reallocated. We may want to avoid this if possible
|
// reallocated. We may want to avoid this if possible
|
||||||
mVisibleRegions.clear();
|
mVisibleRegions.clear();
|
||||||
|
@ -651,9 +673,6 @@ HwcComposer2D::TryRender(Layer* aRoot,
|
||||||
aGLWorldTransform))
|
aGLWorldTransform))
|
||||||
{
|
{
|
||||||
LOGD("Render aborted. Nothing was drawn to the screen");
|
LOGD("Render aborted. Nothing was drawn to the screen");
|
||||||
if (mList) {
|
|
||||||
mList->numHwLayers = 0;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
bool Render(EGLDisplay dpy, EGLSurface sur);
|
bool Render(EGLDisplay dpy, EGLSurface sur);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Reset();
|
||||||
void Prepare(buffer_handle_t fbHandle, int fence);
|
void Prepare(buffer_handle_t fbHandle, int fence);
|
||||||
bool Commit();
|
bool Commit();
|
||||||
bool TryHwComposition();
|
bool TryHwComposition();
|
||||||
|
@ -84,6 +85,7 @@ private:
|
||||||
nsTArray<int> mPrevReleaseFds;
|
nsTArray<int> mPrevReleaseFds;
|
||||||
int mPrevRetireFence;
|
int mPrevRetireFence;
|
||||||
nsTArray<layers::LayerComposite*> mHwcLayerMap;
|
nsTArray<layers::LayerComposite*> mHwcLayerMap;
|
||||||
|
bool mPrepared;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
Загрузка…
Ссылка в новой задаче