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 : 97f472f6ed1c5d6bed1af01fb7243a82b2629b03
This commit is contained in:
Dan Minor 2018-05-08 15:55:36 -04:00
Родитель 58db281570
Коммит 40fcbf60d9
18 изменённых файлов: 130 добавлений и 2 удалений

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

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

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

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

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

@ -539,6 +539,22 @@ CamerasChild::StartCapture(CaptureEngine aCapEngine,
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
CamerasChild::StopCapture(CaptureEngine aCapEngine, const int capture_id)
{

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

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

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

@ -977,6 +977,43 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
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
CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
const int& capnum)

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

@ -99,6 +99,8 @@ public:
mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
const VideoCaptureCapability&) override;
mozilla::ipc::IPCResult RecvFocusOnSelectedSource(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 RecvAllDone() override;

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

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

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

@ -342,6 +342,18 @@ MediaEngineRemoteVideoSource::Start(const RefPtr<const AllocationHandle>& aHandl
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
MediaEngineRemoteVideoSource::Stop(const RefPtr<const AllocationHandle>& aHandle)
{

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

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

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

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

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

@ -151,6 +151,19 @@ public:
*/
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
* device.
@ -279,6 +292,9 @@ public:
// Not scary by default.
bool GetScary() const override;
// Returns NS_ERROR_NOT_AVAILABLE by default.
nsresult FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle) override;
// Shutdown does nothing by default.
void Shutdown() override;

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

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

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

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

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

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

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

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

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

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

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

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

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

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