Bug 1450658 - Should bring window to front when screen-sharing a window; r=pehrsons

This adds a FocusOnSelectedSource method to PCameras and uses it to focus the
selected window while window sharing. We can't just focus the window as soon as
it is shared because we have a live preview in the getUserMedia permissions
prompt which would cause the prompt to lose focus. Instead, this only focuses the
window when the sharing is not done from a chrome context.


MozReview-Commit-ID: 5jre75E3JLi

--HG--
extra : rebase_source : 5f5154fc9fc7590cc02eb25146e5bc20b2243fa3
This commit is contained in:
Dan Minor 2018-05-08 15:55:36 -04:00
Родитель 5572e9708a
Коммит 50a3ab6cd4
18 изменённых файлов: 130 добавлений и 2 удалений

Просмотреть файл

@ -1005,6 +1005,13 @@ MediaDevice::Reconfigure(const dom::MediaTrackConstraints &aConstraints,
aOutBadConstraint); aOutBadConstraint);
} }
nsresult
MediaDevice::FocusOnSelectedSource()
{
MOZ_ASSERT(MediaManager::IsInMediaThread());
return mSource->FocusOnSelectedSource(mAllocationHandle);
}
nsresult nsresult
MediaDevice::Stop() MediaDevice::Stop()
{ {
@ -1119,7 +1126,8 @@ public:
const MediaStreamConstraints& aConstraints, const MediaStreamConstraints& aConstraints,
MediaDevice* aAudioDevice, MediaDevice* aAudioDevice,
MediaDevice* aVideoDevice, MediaDevice* aVideoDevice,
PeerIdentity* aPeerIdentity) PeerIdentity* aPeerIdentity,
bool aIsChrome)
: Runnable("GetUserMediaStreamRunnable") : Runnable("GetUserMediaStreamRunnable")
, mOnSuccess(aOnSuccess) , mOnSuccess(aOnSuccess)
, mOnFailure(aOnFailure) , mOnFailure(aOnFailure)
@ -1709,6 +1717,13 @@ public:
if (mAudioDevice) { if (mAudioDevice) {
mAudioDevice->Deallocate(); mAudioDevice->Deallocate();
} }
} else {
if (!mIsChrome) {
rv = mVideoDevice->FocusOnSelectedSource();
if (NS_FAILED(rv)) {
LOG(("FocusOnSelectedSource failed"));
}
}
} }
} }
if (errorMsg) { if (errorMsg) {
@ -1741,7 +1756,7 @@ public:
mWindowListener, mSourceListener, mWindowListener, mSourceListener,
mPrincipalInfo, mConstraints, mPrincipalInfo, mConstraints,
mAudioDevice, mVideoDevice, mAudioDevice, mVideoDevice,
peerIdentity))); peerIdentity, mIsChrome)));
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -89,6 +89,7 @@ public:
nsresult Reconfigure(const dom::MediaTrackConstraints& aConstraints, nsresult Reconfigure(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs, const MediaEnginePrefs& aPrefs,
const char** aOutBadConstraint); const char** aOutBadConstraint);
nsresult FocusOnSelectedSource();
nsresult Stop(); nsresult Stop();
nsresult Deallocate(); nsresult Deallocate();

Просмотреть файл

@ -539,6 +539,22 @@ CamerasChild::StartCapture(CaptureEngine aCapEngine,
return dispatcher.ReturnValue(); return dispatcher.ReturnValue();
} }
int
CamerasChild::FocusOnSelectedSource(CaptureEngine aCapEngine,
const int aCaptureId)
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
mozilla::NewRunnableMethod<CaptureEngine, int>(
"camera::PCamerasChild::SendFocusOnSelectedSource",
this,
&CamerasChild::SendFocusOnSelectedSource,
aCapEngine,
aCaptureId);
LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
return dispatcher.ReturnValue();
}
int int
CamerasChild::StopCapture(CaptureEngine aCapEngine, const int capture_id) CamerasChild::StopCapture(CaptureEngine aCapEngine, const int capture_id)
{ {

Просмотреть файл

@ -192,6 +192,7 @@ public:
int StartCapture(CaptureEngine aCapEngine, int StartCapture(CaptureEngine aCapEngine,
const int capture_id, webrtc::VideoCaptureCapability& capability, const int capture_id, webrtc::VideoCaptureCapability& capability,
FrameRelay* func); FrameRelay* func);
int FocusOnSelectedSource(CaptureEngine aCapEngine, const int capture_id);
int StopCapture(CaptureEngine aCapEngine, const int capture_id); int StopCapture(CaptureEngine aCapEngine, const int capture_id);
int AllocateCaptureDevice(CaptureEngine aCapEngine, int AllocateCaptureDevice(CaptureEngine aCapEngine,
const char* unique_idUTF8, const char* unique_idUTF8,

Просмотреть файл

@ -977,6 +977,43 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult
CamerasParent::RecvFocusOnSelectedSource(const CaptureEngine& aCapEngine,
const int& aCapNum)
{
LOG((__PRETTY_FUNCTION__));
RefPtr<Runnable> webrtc_runnable =
media::NewRunnableFrom([self = RefPtr<CamerasParent>(this),
aCapEngine, aCapNum]() -> nsresult {
if (auto engine = self->EnsureInitialized(aCapEngine)) {
engine->WithEntry(aCapNum, [self](VideoEngine::CaptureEntry& cap){
if (cap.VideoCapture()) {
bool result = cap.VideoCapture()->FocusOnSelectedSource();
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, result]() -> nsresult {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (result) {
Unused << self->SendReplySuccess();
return NS_OK;
}
Unused << self->SendReplyFailure();
return NS_ERROR_FAILURE;
});
self->mPBackgroundEventTarget->Dispatch(ipc_runnable,
NS_DISPATCH_NORMAL);
}
});
}
return NS_ERROR_FAILURE;
});
DispatchToVideoCaptureThread(webrtc_runnable);
return IPC_OK();
}
void void
CamerasParent::StopCapture(const CaptureEngine& aCapEngine, CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
const int& capnum) const int& capnum)

Просмотреть файл

@ -99,6 +99,8 @@ public:
mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override; mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&, mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
const VideoCaptureCapability&) override; const VideoCaptureCapability&) override;
mozilla::ipc::IPCResult RecvFocusOnSelectedSource(const CaptureEngine&,
const int&) override;
mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override; mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override; mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
mozilla::ipc::IPCResult RecvAllDone() override; mozilla::ipc::IPCResult RecvAllDone() override;

Просмотреть файл

@ -80,6 +80,7 @@ parent:
PrincipalInfo principal); PrincipalInfo principal);
async ReleaseCaptureDevice(CaptureEngine engine, int numdev); async ReleaseCaptureDevice(CaptureEngine engine, int numdev);
async StartCapture(CaptureEngine engine, int numdev, VideoCaptureCapability capability); async StartCapture(CaptureEngine engine, int numdev, VideoCaptureCapability capability);
async FocusOnSelectedSource(CaptureEngine engine, int numdev);
async StopCapture(CaptureEngine engine, int numdev); async StopCapture(CaptureEngine engine, int numdev);
// transfers frame back // transfers frame back
async ReleaseFrame(Shmem s); async ReleaseFrame(Shmem s);

Просмотреть файл

@ -342,6 +342,18 @@ MediaEngineRemoteVideoSource::Start(const RefPtr<const AllocationHandle>& aHandl
return NS_OK; return NS_OK;
} }
nsresult
MediaEngineRemoteVideoSource::FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle)
{
LOG((__PRETTY_FUNCTION__));
AssertIsOnOwningThread();
int result;
result = camera::GetChildAndCall(&camera::CamerasChild::FocusOnSelectedSource,
mCapEngine, mCaptureIndex);
return result == 0 ? NS_OK : NS_ERROR_FAILURE;
}
nsresult nsresult
MediaEngineRemoteVideoSource::Stop(const RefPtr<const AllocationHandle>& aHandle) MediaEngineRemoteVideoSource::Stop(const RefPtr<const AllocationHandle>& aHandle)
{ {

Просмотреть файл

@ -144,6 +144,7 @@ public:
const MediaEnginePrefs& aPrefs, const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId, const nsString& aDeviceId,
const char** aOutBadConstraint) override; const char** aOutBadConstraint) override;
nsresult FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle) override;
nsresult Stop(const RefPtr<const AllocationHandle>& aHandle) override; nsresult Stop(const RefPtr<const AllocationHandle>& aHandle) override;
void Pull(const RefPtr<const AllocationHandle>& aHandle, void Pull(const RefPtr<const AllocationHandle>& aHandle,
const RefPtr<SourceMediaStream>& aStream, const RefPtr<SourceMediaStream>& aStream,

Просмотреть файл

@ -55,6 +55,12 @@ MediaEngineSource::GetScary() const
return false; return false;
} }
nsresult
MediaEngineSource::FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle)
{
return NS_ERROR_NOT_AVAILABLE;
}
void void
MediaEngineSource::Shutdown() MediaEngineSource::Shutdown()
{ {

Просмотреть файл

@ -151,6 +151,19 @@ public:
*/ */
virtual nsresult Start(const RefPtr<const AllocationHandle>& aHandle) = 0; virtual nsresult Start(const RefPtr<const AllocationHandle>& aHandle) = 0;
/**
* This brings focus to the selected source, e.g. to bring a captured window
* to the front.
*
* We return one of the following:
* NS_OK - Success.
* NS_ERROR_NOT_AVAILABLE - For backends where focusing does not make sense.
* NS_ERROR_NOT_IMPLEMENTED - For backends where focusing makes sense, but
* is not yet implemented.
* NS_ERROR_FAILURE - Failures reported from underlying code.
*/
virtual nsresult FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle) = 0;
/** /**
* Applies new constraints to the capability selection for the underlying * Applies new constraints to the capability selection for the underlying
* device. * device.
@ -279,6 +292,9 @@ public:
// Not scary by default. // Not scary by default.
bool GetScary() const override; bool GetScary() const override;
// Returns NS_ERROR_NOT_AVAILABLE by default.
nsresult FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle) override;
// Shutdown does nothing by default. // Shutdown does nothing by default.
void Shutdown() override; void Shutdown() override;

Просмотреть файл

@ -396,6 +396,12 @@ MediaEngineTabVideoSource::Draw() {
mImageSize = size; mImageSize = size;
} }
nsresult
MediaEngineTabVideoSource::FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult nsresult
MediaEngineTabVideoSource::Stop(const RefPtr<const AllocationHandle>& aHandle) MediaEngineTabVideoSource::Stop(const RefPtr<const AllocationHandle>& aHandle)
{ {

Просмотреть файл

@ -46,6 +46,7 @@ public:
const MediaEnginePrefs& aPrefs, const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId, const nsString& aDeviceId,
const char** aOutBadConstraint) override; const char** aOutBadConstraint) override;
nsresult FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle) override;
nsresult Stop(const RefPtr<const AllocationHandle>& aHandle) override; nsresult Stop(const RefPtr<const AllocationHandle>& aHandle) override;
void Pull(const RefPtr<const AllocationHandle>& aHandle, void Pull(const RefPtr<const AllocationHandle>& aHandle,

Просмотреть файл

@ -184,4 +184,8 @@ void DesktopAndCursorComposer::OnMouseCursorPosition(
cursor_position_ = position; cursor_position_ = position;
} }
bool DesktopAndCursorComposer::FocusOnSelectedSource() {
return desktop_capturer_->FocusOnSelectedSource();
}
} // namespace webrtc } // namespace webrtc

Просмотреть файл

@ -40,6 +40,7 @@ class DesktopAndCursorComposer : public DesktopCapturer,
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override; std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
void CaptureFrame() override; void CaptureFrame() override;
void SetExcludedWindow(WindowId window) override; void SetExcludedWindow(WindowId window) override;
bool FocusOnSelectedSource() override;
private: private:
// DesktopCapturer::Callback interface. // DesktopCapturer::Callback interface.

Просмотреть файл

@ -168,6 +168,8 @@ class VideoCaptureModule: public rtc::RefCountInterface {
virtual int32_t StopCaptureIfAllClientsClose() = 0; virtual int32_t StopCaptureIfAllClientsClose() = 0;
virtual bool FocusOnSelectedSource() { return false; };
virtual int32_t StopCapture() = 0; virtual int32_t StopCapture() = 0;
// Returns the name of the device used by this module. // Returns the name of the device used by this module.

Просмотреть файл

@ -672,6 +672,11 @@ int32_t DesktopCaptureImpl::StartCapture(const VideoCaptureCapability& capabilit
return 0; return 0;
} }
bool DesktopCaptureImpl::FocusOnSelectedSource()
{
return desktop_capturer_cursor_composer_->FocusOnSelectedSource();
}
int32_t DesktopCaptureImpl::StopCapture() { int32_t DesktopCaptureImpl::StopCapture() {
if (started_) { if (started_) {
capturer_thread_->Stop(); // thread is guaranteed stopped before this returns capturer_thread_->Stop(); // thread is guaranteed stopped before this returns

Просмотреть файл

@ -192,6 +192,7 @@ public:
// Platform dependent // Platform dependent
virtual int32_t StartCapture(const VideoCaptureCapability& capability) override; virtual int32_t StartCapture(const VideoCaptureCapability& capability) override;
virtual bool FocusOnSelectedSource() override;
virtual int32_t StopCapture() override; virtual int32_t StopCapture() override;
virtual bool CaptureStarted() override; virtual bool CaptureStarted() override;
virtual int32_t CaptureSettings(VideoCaptureCapability& settings) override; virtual int32_t CaptureSettings(VideoCaptureCapability& settings) override;