1 // Copyright 2013 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 CHROME_BROWSER_EXTENSIONS_API_MESSAGING_INCOGNITO_CONNECTABILITY_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_INCOGNITO_CONNECTABILITY_H_ 7 8 #include <set> 9 10 #include "base/memory/weak_ptr.h" 11 #include "extensions/browser/browser_context_keyed_api_factory.h" 12 #include "url/gurl.h" 13 14 class InfoBarService; 15 16 namespace content { 17 class BrowserContext; 18 class WebContents; 19 } 20 21 namespace infobars { 22 class InfoBar; 23 } 24 25 namespace extensions { 26 class Extension; 27 28 // Tracks the web connectability of domains to extensions in incognito mode. 29 // 30 // The most important functionality is prompting the user to allow or disallow 31 // connections from incognito tabs to extensions or apps. Users are not prompted 32 // for extensions which can be enabled in incognito mode. However for apps, it's 33 // essential we have this functionality because there is no way for them to be 34 // enabled in incognito. 35 class IncognitoConnectability : public BrowserContextKeyedAPI { 36 public: 37 // While in scope, immediately either accepts or denies the alerts that show 38 // up, and counts the number of times it was invoked. 39 class ScopedAlertTracker { 40 public: 41 enum Mode { 42 INTERACTIVE, 43 ALWAYS_ALLOW, 44 ALWAYS_DENY, 45 }; 46 47 explicit ScopedAlertTracker(Mode mode); 48 49 ~ScopedAlertTracker(); 50 51 // Returns the number of times the alert has been shown since 52 // GetAndResetAlertCount was last called. 53 int GetAndResetAlertCount(); 54 55 private: 56 int last_checked_invocation_count_; 57 }; 58 59 // Returns the IncognitoConnectability object for |context|. |context| must 60 // be off-the-record. 61 static IncognitoConnectability* Get(content::BrowserContext* context); 62 63 // Passes true to the provided callback if |url| is allowed to connect from 64 // this profile, false otherwise. If unknown, the user will be prompted before 65 // an answer is returned. 66 void Query(const Extension* extension, 67 content::WebContents* web_contents, 68 const GURL& url, 69 const base::Callback<void(bool)>& callback); 70 71 private: 72 struct TabContext { 73 TabContext(); 74 TabContext(const TabContext& other); 75 ~TabContext(); 76 77 // The infobar being shown in a given tab. The InfoBarService maintains 78 // ownership of this object. This struct must always be destroyed before the 79 // infobar it tracks. 80 infobars::InfoBar* infobar; 81 // Connectability queries outstanding on this infobar. 82 std::vector<base::Callback<void(bool)>> callbacks; 83 }; 84 85 friend class BrowserContextKeyedAPIFactory<IncognitoConnectability>; 86 87 explicit IncognitoConnectability(content::BrowserContext* context); 88 ~IncognitoConnectability() override; 89 90 typedef std::map<std::string, std::set<GURL> > ExtensionToOriginsMap; 91 typedef std::pair<std::string, GURL> ExtensionOriginPair; 92 typedef std::map<InfoBarService*, TabContext> PendingOrigin; 93 typedef std::map<ExtensionOriginPair, PendingOrigin> PendingOriginMap; 94 95 // Called with the user's selection from the infobar. 96 // |response == INTERACTIVE| indicates that the user closed the infobar 97 // without selecting allow or deny. 98 void OnInteractiveResponse(const std::string& extension_id, 99 const GURL& origin, 100 InfoBarService* infobar_service, 101 ScopedAlertTracker::Mode response); 102 103 // Returns true if the (|extension|, |origin|) pair appears in the map. 104 bool IsInMap(const Extension* extension, 105 const GURL& origin, 106 const ExtensionToOriginsMap& map); 107 108 // BrowserContextKeyedAPI implementation. 109 static BrowserContextKeyedAPIFactory<IncognitoConnectability>* 110 GetFactoryInstance(); service_name()111 static const char* service_name() { 112 return "Messaging.IncognitoConnectability"; 113 } 114 static const bool kServiceHasOwnInstanceInIncognito = true; 115 static const bool kServiceIsCreatedWithBrowserContext = false; 116 117 // The origins that have been prompted for and either allowed or disallowed. 118 // These are deliberately stored in-memory so that they're reset when the 119 // profile is destroyed (i.e. when the last incognito window is closed). 120 ExtensionToOriginsMap allowed_origins_; 121 ExtensionToOriginsMap disallowed_origins_; 122 123 // This maps extension/origin pairs to the tabs with an infobar prompting for 124 // incognito connectability on them. This also stores a reference to the 125 // infobar and the set of callbacks (passed to Query) that will be called when 126 // the query is resolved. 127 PendingOriginMap pending_origins_; 128 129 base::WeakPtrFactory<IncognitoConnectability> weak_factory_{this}; 130 }; 131 132 } // namespace extensions 133 134 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_INCOGNITO_CONNECTABILITY_H_ 135