1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_TabContext_h 8 #define mozilla_dom_TabContext_h 9 10 #include "mozIApplication.h" 11 #include "nsCOMPtr.h" 12 #include "mozilla/BasePrincipal.h" 13 #include "nsPIDOMWindow.h" 14 #include "nsPIWindowRoot.h" 15 16 namespace mozilla { 17 namespace dom { 18 19 class IPCTabContext; 20 21 /** 22 * TabContext encapsulates information about an iframe that may be a mozbrowser 23 * or mozapp. You can ask whether a TabContext corresponds to a mozbrowser or 24 * mozapp, get the app that contains the browser, and so on. 25 * 26 * TabParent and TabChild both inherit from TabContext, and you can also have 27 * standalone TabContext objects. 28 * 29 * This class is immutable except by calling one of the protected 30 * SetTabContext*() methods (and those methods can only be called once). See 31 * also MutableTabContext. 32 */ 33 class TabContext 34 { 35 public: 36 TabContext(); 37 38 /* (The implicit copy-constructor and operator= are fine.) */ 39 40 /** 41 * Generates IPCTabContext of type BrowserFrameIPCTabContext or 42 * AppFrameIPCTabContext from this TabContext's information. 43 */ 44 IPCTabContext AsIPCTabContext() const; 45 46 /** 47 * Does this TabContext correspond to a mozbrowser? 48 * 49 * <iframe mozbrowser mozapp> and <xul:browser> are not considered to be 50 * mozbrowser elements. 51 * 52 * If IsMozBrowserElement() is true, HasOwnApp() and HasAppOwnerApp() are 53 * guaranteed to be false. 54 * 55 * If IsMozBrowserElement() is false, HasBrowserOwnerApp() is guaranteed to be 56 * false. 57 */ 58 bool IsMozBrowserElement() const; 59 60 /** 61 * Does this TabContext correspond to an isolated mozbrowser? 62 * 63 * <iframe mozbrowser mozapp> and <xul:browser> are not considered to be 64 * mozbrowser elements. <iframe mozbrowser noisolation> does not count as 65 * isolated since isolation is disabled. Isolation can only be disabled by 66 * chrome pages. 67 */ 68 bool IsIsolatedMozBrowserElement() const; 69 70 /** 71 * Does this TabContext correspond to a mozbrowser or mozapp? This is 72 * equivalent to IsMozBrowserElement() || HasOwnApp(). Returns false for 73 * <xul:browser>, which is neither a mozbrowser nor a mozapp. 74 */ 75 bool IsMozBrowserOrApp() const; 76 77 /** 78 * OwnAppId() returns the id of the app which directly corresponds to this 79 * context's frame. GetOwnApp() returns the corresponding app object, and 80 * HasOwnApp() returns true iff GetOwnApp() would return a non-null value. 81 * 82 * If HasOwnApp() is true, IsMozBrowserElement() is guaranteed to be 83 * false. 84 */ 85 uint32_t OwnAppId() const; 86 already_AddRefed<mozIApplication> GetOwnApp() const; 87 bool HasOwnApp() const; 88 89 /** 90 * BrowserOwnerAppId() gets the ID of the app which contains this browser 91 * frame. If this is not a mozbrowser frame (if !IsMozBrowserElement()), then 92 * BrowserOwnerAppId() is guaranteed to return NO_APP_ID. 93 * 94 * Even if we are a browser frame, BrowserOwnerAppId() may still return 95 * NO_APP_ID, if this browser frame is not contained inside an app. 96 */ 97 uint32_t BrowserOwnerAppId() const; 98 already_AddRefed<mozIApplication> GetBrowserOwnerApp() const; 99 bool HasBrowserOwnerApp() const; 100 101 /** 102 * AppOwnerAppId() gets the ID of the app which contains this app frame. If 103 * this is not an app frame (i.e., if !HasOwnApp()), then AppOwnerAppId() is 104 * guaranteed to return NO_APP_ID. 105 * 106 * Even if we are an app frame, AppOwnerAppId() may still return NO_APP_ID, if 107 * this app frame is not contained inside an app. 108 */ 109 uint32_t AppOwnerAppId() const; 110 already_AddRefed<mozIApplication> GetAppOwnerApp() const; 111 bool HasAppOwnerApp() const; 112 113 /** 114 * OwnOrContainingAppId() gets the ID of this frame, if HasOwnApp(). If this 115 * frame does not have its own app, it gets the ID of the app which contains 116 * this frame (i.e., the result of {Browser,App}OwnerAppId(), as applicable). 117 */ 118 uint32_t OwnOrContainingAppId() const; 119 already_AddRefed<mozIApplication> GetOwnOrContainingApp() const; 120 bool HasOwnOrContainingApp() const; 121 122 /** 123 * OriginAttributesRef() returns the DocShellOriginAttributes of this frame to 124 * the caller. This is used to store any attribute associated with the frame's 125 * docshell, such as the AppId. 126 */ 127 const DocShellOriginAttributes& OriginAttributesRef() const; 128 129 /** 130 * Returns the presentation URL associated with the tab if this tab is 131 * created for presented content 132 */ 133 const nsAString& PresentationURL() const; 134 135 UIStateChangeType ShowAccelerators() const; 136 UIStateChangeType ShowFocusRings() const; 137 138 protected: 139 friend class MaybeInvalidTabContext; 140 141 /** 142 * These protected mutator methods let you modify a TabContext once. Further 143 * attempts to modify a given TabContext will fail (the method will return 144 * false). 145 * 146 * These mutators will also fail if the TabContext was created with anything 147 * other than the no-args constructor. 148 */ 149 150 /** 151 * Set this TabContext to match the given TabContext. 152 */ 153 bool SetTabContext(const TabContext& aContext); 154 155 /** 156 * Set the tab context's origin attributes to a private browsing value. 157 */ 158 void SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing); 159 160 /** 161 * Set the TabContext for this frame. This can either be: 162 * - an app frame (with the given own app) inside the given owner app. Either 163 * apps can be null. 164 * - a browser frame inside the given owner app (which may be null). 165 * - a non-browser, non-app frame. Both own app and owner app should be null. 166 */ 167 bool SetTabContext(bool aIsMozBrowserElement, 168 bool aIsPrerendered, 169 mozIApplication* aOwnApp, 170 mozIApplication* aAppFrameOwnerApp, 171 UIStateChangeType aShowAccelerators, 172 UIStateChangeType aShowFocusRings, 173 const DocShellOriginAttributes& aOriginAttributes, 174 const nsAString& aPresentationURL); 175 176 /** 177 * Modify this TabContext to match the given TabContext. This is a special 178 * case triggered by nsFrameLoader::SwapWithOtherRemoteLoader which may have 179 * caused the owner content to change. 180 * 181 * This special case only allows the field `mIsMozBrowserElement` to be 182 * changed. If any other fields have changed, the update is ignored and 183 * returns false. 184 */ 185 bool UpdateTabContextAfterSwap(const TabContext& aContext); 186 187 /** 188 * Whether this TabContext is in prerender mode. 189 */ 190 bool mIsPrerendered; 191 192 private: 193 /** 194 * Has this TabContext been initialized? If so, mutator methods will fail. 195 */ 196 bool mInitialized; 197 198 /** 199 * Whether this TabContext corresponds to a mozbrowser. 200 * 201 * <iframe mozbrowser mozapp> and <xul:browser> are not considered to be 202 * mozbrowser elements. 203 */ 204 bool mIsMozBrowserElement; 205 206 /** 207 * This TabContext's own app. If this is non-null, then this 208 * TabContext corresponds to an app, and mIsMozBrowserElement must be false. 209 */ 210 nsCOMPtr<mozIApplication> mOwnApp; 211 212 /** 213 * This TabContext's containing app. If mIsMozBrowserElement, this 214 * corresponds to the app which contains the browser frame; otherwise, this 215 * corresponds to the app which contains the app frame. 216 */ 217 nsCOMPtr<mozIApplication> mContainingApp; 218 219 /* 220 * Cache of mContainingApp->GetLocalId(). 221 */ 222 uint32_t mContainingAppId; 223 224 /** 225 * DocShellOriginAttributes of the top level tab docShell 226 */ 227 DocShellOriginAttributes mOriginAttributes; 228 229 /** 230 * The requested presentation URL. 231 */ 232 nsString mPresentationURL; 233 234 /** 235 * Keyboard indicator state (focus rings, accelerators). 236 */ 237 UIStateChangeType mShowAccelerators; 238 UIStateChangeType mShowFocusRings; 239 }; 240 241 /** 242 * MutableTabContext is the same as MaybeInvalidTabContext, except the mutation 243 * methods are public instead of protected. You can still only call these 244 * mutation methods once on a given object. 245 */ 246 class MutableTabContext : public TabContext 247 { 248 public: SetTabContext(const TabContext & aContext)249 bool SetTabContext(const TabContext& aContext) 250 { 251 return TabContext::SetTabContext(aContext); 252 } 253 254 bool 255 SetTabContext(bool aIsMozBrowserElement, 256 bool aIsPrerendered, 257 mozIApplication* aOwnApp, 258 mozIApplication* aAppFrameOwnerApp, 259 UIStateChangeType aShowAccelerators, 260 UIStateChangeType aShowFocusRings, 261 const DocShellOriginAttributes& aOriginAttributes, 262 const nsAString& aPresentationURL = EmptyString()) 263 { 264 return TabContext::SetTabContext(aIsMozBrowserElement, 265 aIsPrerendered, 266 aOwnApp, 267 aAppFrameOwnerApp, 268 aShowAccelerators, 269 aShowFocusRings, 270 aOriginAttributes, 271 aPresentationURL); 272 } 273 }; 274 275 /** 276 * MaybeInvalidTabContext is a simple class that lets you transform an 277 * IPCTabContext into a TabContext. 278 * 279 * The issue is that an IPCTabContext is not necessarily valid; for example, it 280 * might specify an app-id which doesn't exist. So to convert an IPCTabContext 281 * into a TabContext, you construct a MaybeInvalidTabContext, check whether it's 282 * valid, and, if so, read out your TabContext. 283 * 284 * Example usage: 285 * 286 * void UseTabContext(const TabContext& aTabContext); 287 * 288 * void CreateTab(const IPCTabContext& aContext) { 289 * MaybeInvalidTabContext tc(aContext); 290 * if (!tc.IsValid()) { 291 * NS_ERROR(nsPrintfCString("Got an invalid IPCTabContext: %s", 292 * tc.GetInvalidReason())); 293 * return; 294 * } 295 * UseTabContext(tc.GetTabContext()); 296 * } 297 */ 298 class MaybeInvalidTabContext 299 { 300 public: 301 /** 302 * This constructor copies the information in aContext and sets IsValid() as 303 * appropriate. 304 */ 305 explicit MaybeInvalidTabContext(const IPCTabContext& aContext); 306 307 /** 308 * Was the IPCTabContext we received in our constructor valid? 309 */ 310 bool IsValid(); 311 312 /** 313 * If IsValid(), this function returns null. Otherwise, it returns a 314 * human-readable string indicating why the IPCTabContext passed to our 315 * constructor was not valid. 316 */ 317 const char* GetInvalidReason(); 318 319 /** 320 * If IsValid(), this function returns a reference to a TabContext 321 * corresponding to the IPCTabContext passed to our constructor. If 322 * !IsValid(), this function crashes. 323 */ 324 const TabContext& GetTabContext(); 325 326 private: 327 MaybeInvalidTabContext(const MaybeInvalidTabContext&) = delete; 328 MaybeInvalidTabContext& operator=(const MaybeInvalidTabContext&) = delete; 329 330 const char* mInvalidReason; 331 MutableTabContext mTabContext; 332 }; 333 334 } // namespace dom 335 } // namespace mozilla 336 337 #endif 338