1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef IOS_CHROME_BROWSER_MAIN_BROWSER_USER_DATA_H_ 6 #define IOS_CHROME_BROWSER_MAIN_BROWSER_USER_DATA_H_ 7 8 #include "base/memory/ptr_util.h" 9 #include "base/supports_user_data.h" 10 #import "ios/chrome/browser/main/browser.h" 11 12 // This macro declares a static variable inside the class that inherits from 13 // BrwoserUserData. The address of this static variable is used as the key to 14 // store/retrieve an instance of the class on/from a Browser. 15 #define BROWSER_USER_DATA_KEY_DECL() static constexpr int kUserDataKey = 0 16 17 // This macro instantiates the static variable declared by the previous macro. 18 // It must live in a .mm/.cc file to ensure that there is only one instantiation 19 // of the static variable. 20 #define BROWSER_USER_DATA_KEY_IMPL(Type) const int Type::kUserDataKey; 21 22 // A base class for classes attached to, and scoped to, the lifetime of a 23 // Browser. For example: 24 // 25 // --- in foo_browser_agent.h --- 26 // class FooBrowserAgent : public BrowserUserData<FooBrowserAgent> { 27 // public: 28 // ~FooBrowserAgent() override; 29 // // ... more public stuff here ... 30 // private: 31 // explicit FooBrowserAgent(Browser* browser); 32 // friend class BrowserUserData<FooBrowserAgent>; 33 // BROWSER_USER_DATA_KEY_DECL(); 34 // // ... more private stuff here ... 35 // }; 36 // 37 // --- in foo_browser_agent.cc --- 38 // BROWSER_USER_DATA_KEY_IMPL(FooBrowserAgent) 39 template <typename T> 40 class BrowserUserData : public base::SupportsUserData::Data { 41 public: 42 // Creates an object of type T, and attaches it to the specified Browser. 43 // If an instance is already attached, does nothing. CreateForBrowser(Browser * browser)44 static void CreateForBrowser(Browser* browser) { 45 if (!FromBrowser(browser)) 46 browser->SetUserData(UserDataKey(), base::WrapUnique(new T(browser))); 47 } 48 49 // Retrieves the instance of type T that was attached to the specified 50 // Browser (via CreateForBrowser above) and returns it. If no instance 51 // of the type was attached, returns nullptr. FromBrowser(Browser * browser)52 static T* FromBrowser(Browser* browser) { 53 return static_cast<T*>(browser->GetUserData(UserDataKey())); 54 } FromBrowser(const Browser * browser)55 static const T* FromBrowser(const Browser* browser) { 56 return static_cast<const T*>(browser->GetUserData(UserDataKey())); 57 } 58 59 // Removes the instance attached to the specified Browser. RemoveFromBrowser(Browser * browser)60 static void RemoveFromBrowser(Browser* browser) { 61 browser->RemoveUserData(UserDataKey()); 62 } 63 UserDataKey()64 static const void* UserDataKey() { return &T::kUserDataKey; } 65 }; 66 67 #endif // IOS_CHROME_BROWSER_MAIN_BROWSER_USER_DATA_H_ 68