dom/ipc/TabContext.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set sw=2 ts=8 et tw=80 : */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "mozilla/dom/TabContext.h"
michael@0 8 #include "mozilla/dom/PTabContext.h"
michael@0 9 #include "mozilla/dom/TabParent.h"
michael@0 10 #include "mozilla/dom/TabChild.h"
michael@0 11 #include "nsIAppsService.h"
michael@0 12 #include "nsIScriptSecurityManager.h"
michael@0 13 #include "nsServiceManagerUtils.h"
michael@0 14
michael@0 15 #define NO_APP_ID (nsIScriptSecurityManager::NO_APP_ID)
michael@0 16
michael@0 17 using namespace mozilla::dom::ipc;
michael@0 18 using namespace mozilla::layout;
michael@0 19
michael@0 20 namespace mozilla {
michael@0 21 namespace dom {
michael@0 22
michael@0 23 TabContext::TabContext()
michael@0 24 : mInitialized(false)
michael@0 25 , mOwnAppId(NO_APP_ID)
michael@0 26 , mContainingAppId(NO_APP_ID)
michael@0 27 , mScrollingBehavior(DEFAULT_SCROLLING)
michael@0 28 , mIsBrowser(false)
michael@0 29 {
michael@0 30 }
michael@0 31
michael@0 32 bool
michael@0 33 TabContext::IsBrowserElement() const
michael@0 34 {
michael@0 35 return mIsBrowser;
michael@0 36 }
michael@0 37
michael@0 38 bool
michael@0 39 TabContext::IsBrowserOrApp() const
michael@0 40 {
michael@0 41 return HasOwnApp() || IsBrowserElement();
michael@0 42 }
michael@0 43
michael@0 44 uint32_t
michael@0 45 TabContext::OwnAppId() const
michael@0 46 {
michael@0 47 return mOwnAppId;
michael@0 48 }
michael@0 49
michael@0 50 already_AddRefed<mozIApplication>
michael@0 51 TabContext::GetOwnApp() const
michael@0 52 {
michael@0 53 nsCOMPtr<mozIApplication> ownApp = mOwnApp;
michael@0 54 return ownApp.forget();
michael@0 55 }
michael@0 56
michael@0 57 bool
michael@0 58 TabContext::HasOwnApp() const
michael@0 59 {
michael@0 60 nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
michael@0 61 return !!ownApp;
michael@0 62 }
michael@0 63
michael@0 64 uint32_t
michael@0 65 TabContext::BrowserOwnerAppId() const
michael@0 66 {
michael@0 67 if (IsBrowserElement()) {
michael@0 68 return mContainingAppId;
michael@0 69 }
michael@0 70 return NO_APP_ID;
michael@0 71 }
michael@0 72
michael@0 73 already_AddRefed<mozIApplication>
michael@0 74 TabContext::GetBrowserOwnerApp() const
michael@0 75 {
michael@0 76 nsCOMPtr<mozIApplication> ownerApp;
michael@0 77 if (IsBrowserElement()) {
michael@0 78 ownerApp = mContainingApp;
michael@0 79 }
michael@0 80 return ownerApp.forget();
michael@0 81 }
michael@0 82
michael@0 83 bool
michael@0 84 TabContext::HasBrowserOwnerApp() const
michael@0 85 {
michael@0 86 nsCOMPtr<mozIApplication> ownerApp = GetBrowserOwnerApp();
michael@0 87 return !!ownerApp;
michael@0 88 }
michael@0 89
michael@0 90 uint32_t
michael@0 91 TabContext::AppOwnerAppId() const
michael@0 92 {
michael@0 93 if (HasOwnApp()) {
michael@0 94 return mContainingAppId;
michael@0 95 }
michael@0 96 return NO_APP_ID;
michael@0 97 }
michael@0 98
michael@0 99 already_AddRefed<mozIApplication>
michael@0 100 TabContext::GetAppOwnerApp() const
michael@0 101 {
michael@0 102 nsCOMPtr<mozIApplication> ownerApp;
michael@0 103 if (HasOwnApp()) {
michael@0 104 ownerApp = mContainingApp;
michael@0 105 }
michael@0 106 return ownerApp.forget();
michael@0 107 }
michael@0 108
michael@0 109 bool
michael@0 110 TabContext::HasAppOwnerApp() const
michael@0 111 {
michael@0 112 nsCOMPtr<mozIApplication> ownerApp = GetAppOwnerApp();
michael@0 113 return !!ownerApp;
michael@0 114 }
michael@0 115
michael@0 116 uint32_t
michael@0 117 TabContext::OwnOrContainingAppId() const
michael@0 118 {
michael@0 119 if (HasOwnApp()) {
michael@0 120 return mOwnAppId;
michael@0 121 }
michael@0 122
michael@0 123 return mContainingAppId;
michael@0 124 }
michael@0 125
michael@0 126 already_AddRefed<mozIApplication>
michael@0 127 TabContext::GetOwnOrContainingApp() const
michael@0 128 {
michael@0 129 nsCOMPtr<mozIApplication> ownOrContainingApp;
michael@0 130 if (HasOwnApp()) {
michael@0 131 ownOrContainingApp = mOwnApp;
michael@0 132 } else {
michael@0 133 ownOrContainingApp = mContainingApp;
michael@0 134 }
michael@0 135
michael@0 136 return ownOrContainingApp.forget();
michael@0 137 }
michael@0 138
michael@0 139 bool
michael@0 140 TabContext::HasOwnOrContainingApp() const
michael@0 141 {
michael@0 142 nsCOMPtr<mozIApplication> ownOrContainingApp = GetOwnOrContainingApp();
michael@0 143 return !!ownOrContainingApp;
michael@0 144 }
michael@0 145
michael@0 146 bool
michael@0 147 TabContext::SetTabContext(const TabContext& aContext)
michael@0 148 {
michael@0 149 NS_ENSURE_FALSE(mInitialized, false);
michael@0 150
michael@0 151 *this = aContext;
michael@0 152 mInitialized = true;
michael@0 153
michael@0 154 return true;
michael@0 155 }
michael@0 156
michael@0 157 bool
michael@0 158 TabContext::SetTabContextForAppFrame(mozIApplication* aOwnApp,
michael@0 159 mozIApplication* aAppFrameOwnerApp,
michael@0 160 ScrollingBehavior aRequestedBehavior)
michael@0 161 {
michael@0 162 NS_ENSURE_FALSE(mInitialized, false);
michael@0 163
michael@0 164 // Get ids for both apps and only write to our member variables after we've
michael@0 165 // verified that this worked.
michael@0 166 uint32_t ownAppId = NO_APP_ID;
michael@0 167 if (aOwnApp) {
michael@0 168 nsresult rv = aOwnApp->GetLocalId(&ownAppId);
michael@0 169 NS_ENSURE_SUCCESS(rv, false);
michael@0 170 NS_ENSURE_TRUE(ownAppId != NO_APP_ID, false);
michael@0 171 }
michael@0 172
michael@0 173 uint32_t containingAppId = NO_APP_ID;
michael@0 174 if (aAppFrameOwnerApp) {
michael@0 175 nsresult rv = aAppFrameOwnerApp->GetLocalId(&containingAppId);
michael@0 176 NS_ENSURE_SUCCESS(rv, false);
michael@0 177 NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
michael@0 178 }
michael@0 179
michael@0 180 mInitialized = true;
michael@0 181 mIsBrowser = false;
michael@0 182 mOwnAppId = ownAppId;
michael@0 183 mContainingAppId = containingAppId;
michael@0 184 mScrollingBehavior = aRequestedBehavior;
michael@0 185 mOwnApp = aOwnApp;
michael@0 186 mContainingApp = aAppFrameOwnerApp;
michael@0 187 return true;
michael@0 188 }
michael@0 189
michael@0 190 bool
michael@0 191 TabContext::SetTabContextForBrowserFrame(mozIApplication* aBrowserFrameOwnerApp,
michael@0 192 ScrollingBehavior aRequestedBehavior)
michael@0 193 {
michael@0 194 NS_ENSURE_FALSE(mInitialized, false);
michael@0 195
michael@0 196 uint32_t containingAppId = NO_APP_ID;
michael@0 197 if (aBrowserFrameOwnerApp) {
michael@0 198 nsresult rv = aBrowserFrameOwnerApp->GetLocalId(&containingAppId);
michael@0 199 NS_ENSURE_SUCCESS(rv, false);
michael@0 200 NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
michael@0 201 }
michael@0 202
michael@0 203 mInitialized = true;
michael@0 204 mIsBrowser = true;
michael@0 205 mOwnAppId = NO_APP_ID;
michael@0 206 mContainingAppId = containingAppId;
michael@0 207 mScrollingBehavior = aRequestedBehavior;
michael@0 208 mContainingApp = aBrowserFrameOwnerApp;
michael@0 209 return true;
michael@0 210 }
michael@0 211
michael@0 212 bool
michael@0 213 TabContext::SetTabContextForNormalFrame(ScrollingBehavior aRequestedBehavior)
michael@0 214 {
michael@0 215 NS_ENSURE_FALSE(mInitialized, false);
michael@0 216
michael@0 217 mInitialized = true;
michael@0 218 mScrollingBehavior = aRequestedBehavior;
michael@0 219 return true;
michael@0 220 }
michael@0 221
michael@0 222 IPCTabContext
michael@0 223 TabContext::AsIPCTabContext() const
michael@0 224 {
michael@0 225 if (mIsBrowser) {
michael@0 226 return IPCTabContext(BrowserFrameIPCTabContext(mContainingAppId),
michael@0 227 mScrollingBehavior);
michael@0 228 }
michael@0 229
michael@0 230 return IPCTabContext(AppFrameIPCTabContext(mOwnAppId, mContainingAppId),
michael@0 231 mScrollingBehavior);
michael@0 232 }
michael@0 233
michael@0 234 static already_AddRefed<mozIApplication>
michael@0 235 GetAppForId(uint32_t aAppId)
michael@0 236 {
michael@0 237 nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
michael@0 238 NS_ENSURE_TRUE(appsService, nullptr);
michael@0 239
michael@0 240 nsCOMPtr<mozIApplication> app;
michael@0 241 appsService->GetAppByLocalId(aAppId, getter_AddRefs(app));
michael@0 242
michael@0 243 return app.forget();
michael@0 244 }
michael@0 245
michael@0 246 MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
michael@0 247 : mInvalidReason(nullptr)
michael@0 248 {
michael@0 249 bool isBrowser = false;
michael@0 250 uint32_t ownAppId = NO_APP_ID;
michael@0 251 uint32_t containingAppId = NO_APP_ID;
michael@0 252
michael@0 253 const IPCTabAppBrowserContext& appBrowser = aParams.appBrowserContext();
michael@0 254 switch(appBrowser.type()) {
michael@0 255 case IPCTabAppBrowserContext::TPopupIPCTabContext: {
michael@0 256 const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();
michael@0 257
michael@0 258 TabContext *context;
michael@0 259 if (ipcContext.openerParent()) {
michael@0 260 context = static_cast<TabParent*>(ipcContext.openerParent());
michael@0 261 if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
michael@0 262 // If the TabParent corresponds to a browser element, then it can only
michael@0 263 // open other browser elements, for security reasons. We should have
michael@0 264 // checked this before calling the TabContext constructor, so this is
michael@0 265 // a fatal error.
michael@0 266 mInvalidReason = "Child is-browser process tried to "
michael@0 267 "open a non-browser tab.";
michael@0 268 return;
michael@0 269 }
michael@0 270 } else if (ipcContext.openerChild()) {
michael@0 271 context = static_cast<TabChild*>(ipcContext.openerChild());
michael@0 272 } else {
michael@0 273 // This should be unreachable because PopupIPCTabContext::opener is not a
michael@0 274 // nullable field.
michael@0 275 mInvalidReason = "PopupIPCTabContext::opener was null (?!).";
michael@0 276 return;
michael@0 277 }
michael@0 278
michael@0 279 // Browser elements can't nest other browser elements. So if
michael@0 280 // our opener is browser element, we must be a new DOM window
michael@0 281 // opened by it. In that case we inherit our containing app ID
michael@0 282 // (if any).
michael@0 283 //
michael@0 284 // Otherwise, we're a new app window and we inherit from our
michael@0 285 // opener app.
michael@0 286 if (ipcContext.isBrowserElement()) {
michael@0 287 isBrowser = true;
michael@0 288 ownAppId = NO_APP_ID;
michael@0 289 containingAppId = context->OwnOrContainingAppId();
michael@0 290 } else {
michael@0 291 isBrowser = false;
michael@0 292 ownAppId = context->mOwnAppId;
michael@0 293 containingAppId = context->mContainingAppId;
michael@0 294 }
michael@0 295 break;
michael@0 296 }
michael@0 297 case IPCTabAppBrowserContext::TAppFrameIPCTabContext: {
michael@0 298 const AppFrameIPCTabContext &ipcContext =
michael@0 299 appBrowser.get_AppFrameIPCTabContext();
michael@0 300
michael@0 301 isBrowser = false;
michael@0 302 ownAppId = ipcContext.ownAppId();
michael@0 303 containingAppId = ipcContext.appFrameOwnerAppId();
michael@0 304 break;
michael@0 305 }
michael@0 306 case IPCTabAppBrowserContext::TBrowserFrameIPCTabContext: {
michael@0 307 const BrowserFrameIPCTabContext &ipcContext =
michael@0 308 appBrowser.get_BrowserFrameIPCTabContext();
michael@0 309
michael@0 310 isBrowser = true;
michael@0 311 ownAppId = NO_APP_ID;
michael@0 312 containingAppId = ipcContext.browserFrameOwnerAppId();
michael@0 313 break;
michael@0 314 }
michael@0 315 case IPCTabAppBrowserContext::TVanillaFrameIPCTabContext: {
michael@0 316 isBrowser = false;
michael@0 317 ownAppId = NO_APP_ID;
michael@0 318 containingAppId = NO_APP_ID;
michael@0 319 break;
michael@0 320 }
michael@0 321 default: {
michael@0 322 MOZ_CRASH();
michael@0 323 }
michael@0 324 }
michael@0 325
michael@0 326 nsCOMPtr<mozIApplication> ownApp = GetAppForId(ownAppId);
michael@0 327 if ((ownApp == nullptr) != (ownAppId == NO_APP_ID)) {
michael@0 328 mInvalidReason = "Got an ownAppId that didn't correspond to an app.";
michael@0 329 return;
michael@0 330 }
michael@0 331
michael@0 332 nsCOMPtr<mozIApplication> containingApp = GetAppForId(containingAppId);
michael@0 333 if ((containingApp == nullptr) != (containingAppId == NO_APP_ID)) {
michael@0 334 mInvalidReason = "Got a containingAppId that didn't correspond to an app.";
michael@0 335 return;
michael@0 336 }
michael@0 337
michael@0 338 bool rv;
michael@0 339 if (isBrowser) {
michael@0 340 rv = mTabContext.SetTabContextForBrowserFrame(containingApp,
michael@0 341 aParams.scrollingBehavior());
michael@0 342 } else {
michael@0 343 rv = mTabContext.SetTabContextForAppFrame(ownApp,
michael@0 344 containingApp,
michael@0 345 aParams.scrollingBehavior());
michael@0 346 }
michael@0 347
michael@0 348 if (!rv) {
michael@0 349 mInvalidReason = "Couldn't initialize TabContext.";
michael@0 350 }
michael@0 351 }
michael@0 352
michael@0 353 bool
michael@0 354 MaybeInvalidTabContext::IsValid()
michael@0 355 {
michael@0 356 return mInvalidReason == nullptr;
michael@0 357 }
michael@0 358
michael@0 359 const char*
michael@0 360 MaybeInvalidTabContext::GetInvalidReason()
michael@0 361 {
michael@0 362 return mInvalidReason;
michael@0 363 }
michael@0 364
michael@0 365 const TabContext&
michael@0 366 MaybeInvalidTabContext::GetTabContext()
michael@0 367 {
michael@0 368 if (!IsValid()) {
michael@0 369 MOZ_CRASH("Can't GetTabContext() if !IsValid().");
michael@0 370 }
michael@0 371
michael@0 372 return mTabContext;
michael@0 373 }
michael@0 374
michael@0 375 } // namespace dom
michael@0 376 } // namespace mozilla

mercurial