TabContext.h (5020B)
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 "mozilla/BasePrincipal.h" 11 #include "nsCOMPtr.h" 12 #include "nsPIDOMWindow.h" 13 #include "nsPIWindowRoot.h" 14 15 namespace mozilla::dom { 16 17 class IPCTabContext; 18 19 /** 20 * TabContext encapsulates information about an iframe. 21 * 22 * BrowserParent and BrowserChild both inherit from TabContext, and you can also 23 * have standalone TabContext objects. 24 * 25 * This class is immutable except by calling one of the protected 26 * SetTabContext*() methods (and those methods can only be called once). See 27 * also MutableTabContext. 28 */ 29 class TabContext { 30 public: 31 TabContext(); 32 33 /* (The implicit copy-constructor and operator= are fine.) */ 34 35 /** 36 * Generates IPCTabContext of type BrowserFrameIPCTabContext from this 37 * TabContext's information. 38 */ 39 IPCTabContext AsIPCTabContext() const; 40 41 uint64_t ChromeOuterWindowID() const; 42 43 uint32_t MaxTouchPoints() const { return mMaxTouchPoints; } 44 45 protected: 46 friend class MaybeInvalidTabContext; 47 48 /** 49 * These protected mutator methods let you modify a TabContext once. Further 50 * attempts to modify a given TabContext will fail (the method will return 51 * false). 52 * 53 * These mutators will also fail if the TabContext was created with anything 54 * other than the no-args constructor. 55 */ 56 57 /** 58 * Set this TabContext to match the given TabContext. 59 */ 60 bool SetTabContext(const TabContext& aContext); 61 62 bool SetTabContext(uint64_t aChromeOuterWindowID, uint32_t aMaxTouchPoints); 63 64 /** 65 * Modify this TabContext to match the given TabContext. This is a special 66 * case triggered by nsFrameLoader::SwapWithOtherRemoteLoader which may have 67 * caused the owner content to change. 68 * 69 * This special case only allows the field `mChromeOuterWindowID` to be 70 * changed. If any other fields have changed, the update is ignored and 71 * returns false. 72 */ 73 bool UpdateTabContextAfterSwap(const TabContext& aContext); 74 75 void SetMaxTouchPoints(uint32_t aMaxTouchPoints) { 76 mMaxTouchPoints = aMaxTouchPoints; 77 } 78 79 private: 80 /** 81 * Has this TabContext been initialized? If so, mutator methods will fail. 82 */ 83 bool mInitialized; 84 85 /** 86 * The outerWindowID of the window hosting the remote frameloader. 87 */ 88 uint64_t mChromeOuterWindowID; 89 90 /** 91 * Maximum number of touch points. 92 */ 93 uint32_t mMaxTouchPoints; 94 }; 95 96 /** 97 * MutableTabContext is the same as MaybeInvalidTabContext, except the mutation 98 * methods are public instead of protected. You can still only call these 99 * mutation methods once on a given object. 100 */ 101 class MutableTabContext : public TabContext { 102 public: 103 bool SetTabContext(const TabContext& aContext) { 104 return TabContext::SetTabContext(aContext); 105 } 106 107 bool SetTabContext(uint64_t aChromeOuterWindowID, uint32_t aMaxTouchPoints) { 108 return TabContext::SetTabContext(aChromeOuterWindowID, aMaxTouchPoints); 109 } 110 }; 111 112 /** 113 * MaybeInvalidTabContext is a simple class that lets you transform an 114 * IPCTabContext into a TabContext. 115 * 116 * The issue is that an IPCTabContext is not necessarily valid. So to convert 117 * an IPCTabContext into a TabContext, you construct a MaybeInvalidTabContext, 118 * check whether it's valid, and, if so, read out your TabContext. 119 * 120 * Example usage: 121 * 122 * void UseTabContext(const TabContext& aTabContext); 123 * 124 * void CreateTab(const IPCTabContext& aContext) { 125 * MaybeInvalidTabContext tc(aContext); 126 * if (!tc.IsValid()) { 127 * NS_ERROR(nsPrintfCString("Got an invalid IPCTabContext: %s", 128 * tc.GetInvalidReason())); 129 * return; 130 * } 131 * UseTabContext(tc.GetTabContext()); 132 * } 133 */ 134 class MaybeInvalidTabContext { 135 public: 136 /** 137 * This constructor copies the information in aContext and sets IsValid() as 138 * appropriate. 139 */ 140 explicit MaybeInvalidTabContext(const IPCTabContext& aContext); 141 142 /** 143 * Was the IPCTabContext we received in our constructor valid? 144 */ 145 bool IsValid(); 146 147 /** 148 * If IsValid(), this function returns null. Otherwise, it returns a 149 * human-readable string indicating why the IPCTabContext passed to our 150 * constructor was not valid. 151 */ 152 const char* GetInvalidReason(); 153 154 /** 155 * If IsValid(), this function returns a reference to a TabContext 156 * corresponding to the IPCTabContext passed to our constructor. If 157 * !IsValid(), this function crashes. 158 */ 159 const TabContext& GetTabContext(); 160 161 private: 162 MaybeInvalidTabContext(const MaybeInvalidTabContext&) = delete; 163 MaybeInvalidTabContext& operator=(const MaybeInvalidTabContext&) = delete; 164 165 const char* mInvalidReason; 166 MutableTabContext mTabContext; 167 }; 168 169 } // namespace mozilla::dom 170 171 #endif