1 // Copyright 2020 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 #include "chrome/browser/nearby_sharing/nearby_process_manager.h" 6 7 #include <memory> 8 #include <utility> 9 10 #include "base/barrier_closure.h" 11 #include "base/bind.h" 12 #include "base/callback.h" 13 #include "base/callback_helpers.h" 14 #include "base/files/file_path.h" 15 #include "build/build_config.h" 16 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/chromeos/nearby/nearby_process_manager_factory.h" 18 #include "chrome/browser/chromeos/nearby/nearby_process_manager_impl.h" 19 #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" 20 #include "chrome/browser/nearby_sharing/logging/logging.h" 21 #include "chrome/browser/nearby_sharing/webrtc_signaling_messenger.h" 22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile_attributes_entry.h" 24 #include "chrome/browser/profiles/profile_attributes_storage.h" 25 #include "chrome/browser/profiles/profile_manager.h" 26 #include "chrome/browser/sharing/webrtc/ice_config_fetcher.h" 27 #include "chrome/browser/sharing/webrtc/sharing_mojo_service.h" 28 #include "chrome/browser/signin/identity_manager_factory.h" 29 #include "chromeos/services/nearby/public/mojom/nearby_connections.mojom.h" 30 #include "components/prefs/pref_service.h" 31 #include "components/signin/public/identity_manager/identity_manager.h" 32 #include "content/public/browser/network_context_client_base.h" 33 #include "content/public/browser/network_service_instance.h" 34 #include "content/public/browser/service_process_host.h" 35 #include "content/public/browser/storage_partition.h" 36 #include "device/bluetooth/adapter.h" 37 #include "device/bluetooth/bluetooth_adapter_factory.h" 38 #include "mojo/public/cpp/bindings/self_owned_receiver.h" 39 #include "services/network/public/mojom/network_context.mojom.h" 40 #include "services/network/public/mojom/network_service.mojom.h" 41 #include "services/network/public/mojom/p2p.mojom.h" 42 #include "services/network/public/mojom/p2p_trusted.mojom.h" 43 44 namespace { 45 GetStoredNearbyProfile()46ProfileAttributesEntry* GetStoredNearbyProfile() { 47 PrefService* local_state = g_browser_process->local_state(); 48 if (!local_state) 49 return nullptr; 50 51 base::FilePath advertising_profile_path = 52 local_state->GetFilePath(::prefs::kNearbySharingActiveProfilePrefName); 53 if (advertising_profile_path.empty()) 54 return nullptr; 55 56 ProfileManager* profile_manager = g_browser_process->profile_manager(); 57 if (!profile_manager) 58 return nullptr; 59 60 ProfileAttributesStorage& storage = 61 profile_manager->GetProfileAttributesStorage(); 62 63 ProfileAttributesEntry* entry; 64 if (!storage.GetProfileAttributesWithPath(advertising_profile_path, &entry)) { 65 // Stored profile path is invalid so remove it. 66 local_state->ClearPref(::prefs::kNearbySharingActiveProfilePrefName); 67 return nullptr; 68 } 69 return entry; 70 } 71 SetStoredNearbyProfile(Profile * profile)72void SetStoredNearbyProfile(Profile* profile) { 73 PrefService* local_state = g_browser_process->local_state(); 74 if (!local_state) 75 return; 76 77 if (profile) { 78 local_state->SetFilePath(::prefs::kNearbySharingActiveProfilePrefName, 79 profile->GetPath()); 80 } else { 81 local_state->ClearPref(::prefs::kNearbySharingActiveProfilePrefName); 82 } 83 } 84 IsStoredNearbyProfile(Profile * profile)85bool IsStoredNearbyProfile(Profile* profile) { 86 ProfileAttributesEntry* entry = GetStoredNearbyProfile(); 87 if (!entry) 88 return profile == nullptr; 89 return profile && entry->GetPath() == profile->GetPath(); 90 } 91 92 } // namespace 93 94 // static GetInstance()95NearbyProcessManager& NearbyProcessManager::GetInstance() { 96 static base::NoDestructor<NearbyProcessManager> instance; 97 return *instance; 98 } 99 AddObserver(Observer * observer)100void NearbyProcessManager::AddObserver(Observer* observer) { 101 observers_.AddObserver(observer); 102 } 103 RemoveObserver(Observer * observer)104void NearbyProcessManager::RemoveObserver(Observer* observer) { 105 observers_.RemoveObserver(observer); 106 } 107 GetActiveProfile() const108ProfileAttributesEntry* NearbyProcessManager::GetActiveProfile() const { 109 return GetStoredNearbyProfile(); 110 } 111 IsActiveProfile(Profile * profile) const112bool NearbyProcessManager::IsActiveProfile(Profile* profile) const { 113 // If the active profile is not loaded yet, try looking in prefs. 114 if (!active_profile_) 115 return IsStoredNearbyProfile(profile); 116 117 return active_profile_ == profile; 118 } 119 IsAnyProfileActive() const120bool NearbyProcessManager::IsAnyProfileActive() const { 121 return !IsActiveProfile(/*profile=*/nullptr); 122 } 123 SetActiveProfile(Profile * profile)124void NearbyProcessManager::SetActiveProfile(Profile* profile) { 125 if (IsActiveProfile(profile)) 126 return; 127 128 active_profile_ = profile; 129 SetStoredNearbyProfile(active_profile_); 130 StopProcess(active_profile_); 131 132 for (auto& observer : observers_) 133 observer.OnNearbyProfileChanged(profile); 134 } 135 ClearActiveProfile()136void NearbyProcessManager::ClearActiveProfile() { 137 SetActiveProfile(/*profile=*/nullptr); 138 } 139 140 location::nearby::connections::mojom::NearbyConnections* GetOrStartNearbyConnections(Profile * profile)141NearbyProcessManager::GetOrStartNearbyConnections(Profile* profile) { 142 if (!IsActiveProfile(profile)) 143 return nullptr; 144 145 EnsureProcessIsRunning(); 146 return reference_->GetNearbyConnections().get(); 147 } 148 149 sharing::mojom::NearbySharingDecoder* GetOrStartNearbySharingDecoder(Profile * profile)150NearbyProcessManager::GetOrStartNearbySharingDecoder(Profile* profile) { 151 if (!IsActiveProfile(profile)) 152 return nullptr; 153 154 EnsureProcessIsRunning(); 155 return reference_->GetNearbySharingDecoder().get(); 156 } 157 StopProcess(Profile * profile)158void NearbyProcessManager::StopProcess(Profile* profile) { 159 if (!IsActiveProfile(profile)) 160 return; 161 162 EnsureNearbyProcessReferenceReleased(); 163 } 164 OnProfileAdded(Profile * profile)165void NearbyProcessManager::OnProfileAdded(Profile* profile) { 166 // Cache active |profile| once it loads so we don't have to check prefs. 167 if (IsActiveProfile(profile)) 168 active_profile_ = profile; 169 } 170 OnProfileMarkedForPermanentDeletion(Profile * profile)171void NearbyProcessManager::OnProfileMarkedForPermanentDeletion( 172 Profile* profile) { 173 if (IsActiveProfile(profile)) 174 SetActiveProfile(nullptr); 175 } 176 NearbyProcessManager()177NearbyProcessManager::NearbyProcessManager() { 178 // profile_manager() might be null in tests or during shutdown. 179 if (auto* manager = g_browser_process->profile_manager()) 180 manager->AddObserver(this); 181 } 182 ~NearbyProcessManager()183NearbyProcessManager::~NearbyProcessManager() { 184 if (auto* manager = g_browser_process->profile_manager()) 185 manager->RemoveObserver(this); 186 } 187 EnsureProcessIsRunning()188void NearbyProcessManager::EnsureProcessIsRunning() { 189 DCHECK(IsAnyProfileActive()); 190 191 // A reference already exists; the process is active. 192 if (reference_) 193 return; 194 195 chromeos::nearby::NearbyProcessManager* process_manager = 196 chromeos::nearby::NearbyProcessManagerFactory::GetForProfile( 197 active_profile_); 198 DCHECK(process_manager); 199 200 NS_LOG(INFO) << "Initializing Nearby Share process reference."; 201 202 // Note: base::Unretained(this) is used because this is a singleton. 203 reference_ = process_manager->GetNearbyProcessReference(base::BindOnce( 204 &NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this))); 205 DCHECK(reference_); 206 207 for (auto& observer : observers_) 208 observer.OnNearbyProcessStarted(); 209 } 210 OnNearbyProcessStopped()211void NearbyProcessManager::OnNearbyProcessStopped() { 212 NS_LOG(INFO) << "Nearby process has stopped."; 213 EnsureNearbyProcessReferenceReleased(); 214 } 215 EnsureNearbyProcessReferenceReleased()216void NearbyProcessManager::EnsureNearbyProcessReferenceReleased() { 217 if (!reference_) 218 return; 219 220 NS_LOG(INFO) << "Releasing Nearby Share process reference."; 221 reference_.reset(); 222 223 for (auto& observer : observers_) 224 observer.OnNearbyProcessStopped(); 225 } 226