Bug 1298360 - Separate session id and window id mapping into two parts. r=smaug

--HG--
extra : rebase_source : c365514be64095e2936d4ccb8a6560b96ad3d70e
This commit is contained in:
Kershaw Chang 2016-08-29 19:40:00 -04:00
Родитель f69944c26d
Коммит bd60aefa57
8 изменённых файлов: 198 добавлений и 85 удалений

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

@ -122,6 +122,7 @@ PresentationReconnectCallback::NotifySuccess()
}
rv = service->UpdateWindowIdBySessionId(mSessionId,
nsIPresentationService::ROLE_CONTROLLER,
mRequest->GetOwner()->WindowID());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;

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

@ -502,7 +502,9 @@ PresentationService::HandleReconnectRequest(nsIPresentationSessionRequest* aRequ
}
uint64_t windowId;
rv = GetWindowIdBySessionIdInternal(sessionId, &windowId);
rv = GetWindowIdBySessionIdInternal(sessionId,
nsIPresentationService::ROLE_RECEIVER,
&windowId);
if (NS_WARN_IF(NS_FAILED(rv))) {
ctrlChannel->Disconnect(rv);
return rv;
@ -672,7 +674,9 @@ PresentationService::CreateControllingSessionInfo(const nsAString& aUrl,
new PresentationControllingInfo(aUrl, aSessionId);
mSessionInfoAtController.Put(aSessionId, info);
AddRespondingSessionId(aWindowId, aSessionId);
AddRespondingSessionId(aWindowId,
aSessionId,
nsIPresentationService::ROLE_CONTROLLER);
return info.forget();
}
@ -908,12 +912,14 @@ PresentationService::RegisterRespondingListener(
return (listener == aListener) ? NS_OK : NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsTArray<nsString>* sessionIdArray;
if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) {
return NS_ERROR_INVALID_ARG;
nsTArray<nsString> sessionIdArray;
nsresult rv = mReceiverSessionIdManager.GetSessionIds(aWindowId,
sessionIdArray);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (const auto& id : *sessionIdArray) {
for (const auto& id : sessionIdArray) {
aListener->NotifySessionConnect(aWindowId, id);
}
@ -932,13 +938,6 @@ PresentationService::UnregisterRespondingListener(uint64_t aWindowId)
return NS_OK;
}
NS_IMETHODIMP
PresentationService::GetExistentSessionIdAtLaunch(uint64_t aWindowId,
nsAString& aSessionId)
{
return GetExistentSessionIdAtLaunchInternal(aWindowId, aSessionId);
}
NS_IMETHODIMP
PresentationService::NotifyReceiverReady(const nsAString& aSessionId,
uint64_t aWindowId,
@ -953,10 +952,13 @@ PresentationService::NotifyReceiverReady(const nsAString& aSessionId,
return NS_ERROR_NOT_AVAILABLE;
}
AddRespondingSessionId(aWindowId, aSessionId);
AddRespondingSessionId(aWindowId,
aSessionId,
nsIPresentationService::ROLE_RECEIVER);
if (!aIsLoading) {
return static_cast<PresentationPresentingInfo*>(info.get())->NotifyResponderFailure();
return static_cast<PresentationPresentingInfo*>(
info.get())->NotifyResponderFailure();
}
nsCOMPtr<nsIPresentationRespondingListener> listener;
@ -1006,7 +1008,7 @@ PresentationService::UntrackSessionInfo(const nsAString& aSessionId,
} else {
// Terminate receiver page.
uint64_t windowId;
nsresult rv = GetWindowIdBySessionIdInternal(aSessionId, &windowId);
nsresult rv = GetWindowIdBySessionIdInternal(aSessionId, aRole, &windowId);
if (NS_SUCCEEDED(rv)) {
NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void {
PRES_DEBUG("Attempt to close window[%d]\n", windowId);
@ -1021,23 +1023,25 @@ PresentationService::UntrackSessionInfo(const nsAString& aSessionId,
}
// Remove the in-process responding info if there's still any.
RemoveRespondingSessionId(aSessionId);
RemoveRespondingSessionId(aSessionId, aRole);
return NS_OK;
}
NS_IMETHODIMP
PresentationService::GetWindowIdBySessionId(const nsAString& aSessionId,
uint8_t aRole,
uint64_t* aWindowId)
{
return GetWindowIdBySessionIdInternal(aSessionId, aWindowId);
return GetWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId);
}
NS_IMETHODIMP
PresentationService::UpdateWindowIdBySessionId(const nsAString& aSessionId,
uint8_t aRole,
const uint64_t aWindowId)
{
return UpdateWindowIdBySessionIdInternal(aSessionId, aWindowId);
return UpdateWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId);
}
bool

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

@ -14,27 +14,9 @@ namespace dom {
NS_IMPL_ISUPPORTS0(PresentationServiceBase)
nsresult
PresentationServiceBase::GetExistentSessionIdAtLaunchInternal(
uint64_t aWindowId,
nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
nsTArray<nsString>* sessionIdArray;
if (mRespondingSessionIds.Get(aWindowId, &sessionIdArray) &&
!sessionIdArray->IsEmpty()) {
aSessionId.Assign((*sessionIdArray)[0]);
}
else {
aSessionId.Truncate();
}
return NS_OK;
}
nsresult
PresentationServiceBase::GetWindowIdBySessionIdInternal(
const nsAString& aSessionId,
uint64_t* aWindowId)
PresentationServiceBase::SessionIdManager::GetWindowId(
const nsAString& aSessionId,
uint64_t* aWindowId)
{
MOZ_ASSERT(NS_IsMainThread());
@ -44,9 +26,26 @@ PresentationServiceBase::GetWindowIdBySessionIdInternal(
return NS_ERROR_NOT_AVAILABLE;
}
nsresult
PresentationServiceBase::SessionIdManager::GetSessionIds(
uint64_t aWindowId,
nsTArray<nsString>& aSessionIds)
{
MOZ_ASSERT(NS_IsMainThread());
nsTArray<nsString>* sessionIdArray;
if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) {
return NS_ERROR_INVALID_ARG;
}
aSessionIds.Assign(*sessionIdArray);
return NS_OK;
}
void
PresentationServiceBase::AddRespondingSessionId(uint64_t aWindowId,
const nsAString& aSessionId)
PresentationServiceBase::SessionIdManager::AddSessionId(
uint64_t aWindowId,
const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
@ -65,7 +64,8 @@ PresentationServiceBase::AddRespondingSessionId(uint64_t aWindowId,
}
void
PresentationServiceBase::RemoveRespondingSessionId(const nsAString& aSessionId)
PresentationServiceBase::SessionIdManager::RemoveSessionId(
const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
@ -83,16 +83,81 @@ PresentationServiceBase::RemoveRespondingSessionId(const nsAString& aSessionId)
}
nsresult
PresentationServiceBase::UpdateWindowIdBySessionIdInternal(
const nsAString& aSessionId,
const uint64_t aWindowId)
PresentationServiceBase::SessionIdManager::UpdateWindowId(
const nsAString& aSessionId,
const uint64_t aWindowId)
{
MOZ_ASSERT(NS_IsMainThread());
RemoveRespondingSessionId(aSessionId);
AddRespondingSessionId(aWindowId, aSessionId);
RemoveSessionId(aSessionId);
AddSessionId(aWindowId, aSessionId);
return NS_OK;
}
nsresult
PresentationServiceBase::GetWindowIdBySessionIdInternal(
const nsAString& aSessionId,
uint8_t aRole,
uint64_t* aWindowId)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
if (NS_WARN_IF(!aWindowId)) {
return NS_ERROR_INVALID_POINTER;
}
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
return mControllerSessionIdManager.GetWindowId(aSessionId, aWindowId);
}
return mReceiverSessionIdManager.GetWindowId(aSessionId, aWindowId);
}
void
PresentationServiceBase::AddRespondingSessionId(uint64_t aWindowId,
const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
mControllerSessionIdManager.AddSessionId(aWindowId, aSessionId);
} else {
mReceiverSessionIdManager.AddSessionId(aWindowId, aSessionId);
}
}
void
PresentationServiceBase::RemoveRespondingSessionId(const nsAString& aSessionId,
uint8_t aRole)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
mControllerSessionIdManager.RemoveSessionId(aSessionId);
} else {
mReceiverSessionIdManager.RemoveSessionId(aSessionId);
}
}
nsresult
PresentationServiceBase::UpdateWindowIdBySessionIdInternal(
const nsAString& aSessionId,
uint8_t aRole,
const uint64_t aWindowId)
{
MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
aRole == nsIPresentationService::ROLE_RECEIVER);
if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
return mControllerSessionIdManager.UpdateWindowId(aSessionId, aWindowId);
}
return mReceiverSessionIdManager.UpdateWindowId(aSessionId, aWindowId);
}
} // namespace dom
} // namespace mozilla

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

@ -25,32 +25,73 @@ public:
PresentationServiceBase() = default;
protected:
class SessionIdManager final
{
public:
explicit SessionIdManager()
{
MOZ_COUNT_CTOR(SessionIdManager);
}
~SessionIdManager()
{
MOZ_COUNT_DTOR(SessionIdManager);
}
nsresult GetWindowId(const nsAString& aSessionId, uint64_t* aWindowId);
nsresult GetSessionIds(uint64_t aWindowId, nsTArray<nsString>& aSessionIds);
void AddSessionId(uint64_t aWindowId, const nsAString& aSessionId);
void RemoveSessionId(const nsAString& aSessionId);
nsresult UpdateWindowId(const nsAString& aSessionId, const uint64_t aWindowId);
void Clear()
{
mRespondingSessionIds.Clear();
mRespondingWindowIds.Clear();
}
private:
nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mRespondingSessionIds;
nsDataHashtable<nsStringHashKey, uint64_t> mRespondingWindowIds;
};
virtual ~PresentationServiceBase() = default;
void Shutdown()
{
mRespondingListeners.Clear();
mRespondingSessionIds.Clear();
mRespondingWindowIds.Clear();
mControllerSessionIdManager.Clear();
mReceiverSessionIdManager.Clear();
}
nsresult GetExistentSessionIdAtLaunchInternal(uint64_t aWindowId, nsAString& aSessionId);
nsresult GetWindowIdBySessionIdInternal(const nsAString& aSessionId, uint64_t* aWindowId);
void AddRespondingSessionId(uint64_t aWindowId, const nsAString& aSessionId);
void RemoveRespondingSessionId(const nsAString& aSessionId);
nsresult GetWindowIdBySessionIdInternal(const nsAString& aSessionId,
uint8_t aRole,
uint64_t* aWindowId);
void AddRespondingSessionId(uint64_t aWindowId,
const nsAString& aSessionId,
uint8_t aRole);
void RemoveRespondingSessionId(const nsAString& aSessionId,
uint8_t aRole);
nsresult UpdateWindowIdBySessionIdInternal(const nsAString& aSessionId,
uint8_t aRole,
const uint64_t aWindowId);
// Store the responding listener based on the window ID of the (in-process or
// OOP) receiver page.
nsRefPtrHashtable<nsUint64HashKey, nsIPresentationRespondingListener> mRespondingListeners;
nsRefPtrHashtable<nsUint64HashKey, nsIPresentationRespondingListener>
mRespondingListeners;
// Store the mapping between the window ID of the in-process and OOP page and the ID
// of the responding session. It's used for an receiver page to retrieve
// the correspondent session ID. Besides, also keep the mapping
// of the responding session. It's used for both controller and receiver page
// to retrieve the correspondent session ID. Besides, also keep the mapping
// between the responding session ID and the window ID to help look up the
// window ID.
nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mRespondingSessionIds;
nsDataHashtable<nsStringHashKey, uint64_t> mRespondingWindowIds;
SessionIdManager mControllerSessionIdManager;
SessionIdManager mReceiverSessionIdManager;
};
} // namespace dom

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

@ -373,7 +373,9 @@ PresentationSessionInfo::GetWindow()
return nullptr;
}
uint64_t windowId = 0;
if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId(mSessionId, &windowId)))) {
if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId(mSessionId,
mRole,
&windowId)))) {
return nullptr;
}

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

@ -161,16 +161,6 @@ interface nsIPresentationService : nsISupports
*/
void unregisterRespondingListener(in unsigned long long windowId);
/*
* Check if the presentation instance has an existent session ID at launch.
* An empty string is always returned at sender side. Whereas at receiver side
* the associated session ID is returned if the window ID and URI are matched;
* otherwise an empty string is returned.
*
* @param windowId: The inner window ID used to look up the session ID.
*/
DOMString getExistentSessionIdAtLaunch(in unsigned long long windowId);
/*
* Notify the receiver page is ready for presentation use.
*
@ -204,17 +194,23 @@ interface nsIPresentationService : nsISupports
/*
* The windowId for building RTCDataChannel session transport
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
*/
unsigned long long getWindowIdBySessionId(in DOMString sessionId);
unsigned long long getWindowIdBySessionId(in DOMString sessionId,
in uint8_t role);
/*
* Update the mapping of the session ID and window ID.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
* @param windowId: The inner window ID associated with the presentation
* session.
*/
void updateWindowIdBySessionId(in DOMString sessionId,
in uint8_t role,
in unsigned long long windowId);
/*

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

@ -39,7 +39,10 @@ nsresult PresentationBuilderChild::Init()
return NS_ERROR_NOT_AVAILABLE;
}
if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId(mSessionId, &windowId)))) {
if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId(
mSessionId,
mRole,
&windowId)))) {
return NS_ERROR_NOT_AVAILABLE;
}

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

@ -60,7 +60,9 @@ PresentationIPCService::StartSession(const nsAString& aUrl,
nsIPresentationServiceCallback* aCallback)
{
if (aWindowId != 0) {
AddRespondingSessionId(aWindowId, aSessionId);
AddRespondingSessionId(aWindowId,
aSessionId,
nsIPresentationService::ROLE_CONTROLLER);
}
return SendRequest(aCallback, StartSessionRequest(nsString(aUrl),
@ -281,16 +283,18 @@ PresentationIPCService::NotifySessionTransport(const nsString& aSessionId,
NS_IMETHODIMP
PresentationIPCService::GetWindowIdBySessionId(const nsAString& aSessionId,
uint8_t aRole,
uint64_t* aWindowId)
{
return GetWindowIdBySessionIdInternal(aSessionId, aWindowId);
return GetWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId);
}
NS_IMETHODIMP
PresentationIPCService::UpdateWindowIdBySessionId(const nsAString& aSessionId,
uint8_t aRole,
const uint64_t aWindowId)
{
return UpdateWindowIdBySessionIdInternal(aSessionId, aWindowId);
return UpdateWindowIdBySessionIdInternal(aSessionId, aRole, aWindowId);
}
nsresult
@ -356,13 +360,6 @@ PresentationIPCService::NotifyAvailableChange(bool aAvailable)
return NS_OK;
}
NS_IMETHODIMP
PresentationIPCService::GetExistentSessionIdAtLaunch(uint64_t aWindowId,
nsAString& aSessionId)
{
return GetExistentSessionIdAtLaunchInternal(aWindowId, aSessionId);;
}
NS_IMETHODIMP
PresentationIPCService::NotifyReceiverReady(const nsAString& aSessionId,
uint64_t aWindowId,
@ -376,7 +373,9 @@ PresentationIPCService::NotifyReceiverReady(const nsAString& aSessionId,
}
// Track the responding info for an OOP receiver page.
AddRespondingSessionId(aWindowId, aSessionId);
AddRespondingSessionId(aWindowId,
aSessionId,
nsIPresentationService::ROLE_RECEIVER);
NS_WARN_IF(!sPresentationChild->SendNotifyReceiverReady(nsString(aSessionId),
aWindowId,
@ -398,7 +397,9 @@ PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId,
if (nsIPresentationService::ROLE_RECEIVER == aRole) {
// Terminate receiver page.
uint64_t windowId;
if (NS_SUCCEEDED(GetWindowIdBySessionIdInternal(aSessionId, &windowId))) {
if (NS_SUCCEEDED(GetWindowIdBySessionIdInternal(aSessionId,
aRole,
&windowId))) {
NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void {
PRES_DEBUG("Attempt to close window[%d]\n", windowId);
@ -410,7 +411,7 @@ PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId,
}
// Remove the OOP responding info (if it has never been used).
RemoveRespondingSessionId(aSessionId);
RemoveRespondingSessionId(aSessionId, aRole);
if (mSessionInfos.Contains(aSessionId)) {
mSessionInfos.Remove(aSessionId);
}