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 #ifndef CHROME_BROWSER_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_
6 #define CHROME_BROWSER_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/callback.h"
12 #include "base/optional.h"
13 #include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager.h"
14 #include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
15 #include "mojo/public/cpp/bindings/pending_receiver.h"
16 #include "mojo/public/cpp/bindings/receiver.h"
17 #include "mojo/public/cpp/bindings/receiver_set.h"
18 #include "mojo/public/cpp/bindings/remote_set.h"
19 
20 class NearbyShareClientFactory;
21 class NearbyShareContactDownloader;
22 class NearbyShareLocalDeviceDataManager;
23 class NearbyShareScheduler;
24 class PrefService;
25 
26 // Implementation of NearbyShareContactManager that persists the set of allowed
27 // contact IDs--for selected-contacts visiblity mode--in prefs. All other
28 // contact data is downloaded from People API, via the NearbyShare server, as
29 // needed.
30 //
31 // The Nearby Share server must be explicitly informed of all contacts this
32 // device is aware of--needed for all-contacts visibility mode--as well as what
33 // contacts are allowed for selected-contacts visibility mode. These uploaded
34 // contact lists are used by the server to distribute the device's public
35 // certificates accordingly. This implementation persists a hash of the last
36 // uploaded contact data, and after every contacts download, a subsequent upload
37 // request is made if we detect that the contact list or allowlist has changed
38 // since the last successful upload. We also schedule periodic contact uploads
39 // just in case the server removed the record.
40 //
41 // In addition to supporting on-demand contact downloads, this implementation
42 // periodically checks in with the Nearby Share server to see if the user's
43 // contact list has changed since the last upload.
44 class NearbyShareContactManagerImpl : public NearbyShareContactManager {
45  public:
46   class Factory {
47    public:
48     static std::unique_ptr<NearbyShareContactManager> Create(
49         PrefService* pref_service,
50         NearbyShareClientFactory* http_client_factory,
51         NearbyShareLocalDeviceDataManager* local_device_data_manager,
52         const std::string& profile_user_name);
53     static void SetFactoryForTesting(Factory* test_factory);
54 
55    protected:
56     virtual ~Factory();
57     virtual std::unique_ptr<NearbyShareContactManager> CreateInstance(
58         PrefService* pref_service,
59         NearbyShareClientFactory* http_client_factory,
60         NearbyShareLocalDeviceDataManager* local_device_data_manager,
61         const std::string& profile_user_name) = 0;
62 
63    private:
64     static Factory* test_factory_;
65   };
66 
67   ~NearbyShareContactManagerImpl() override;
68 
69  private:
70   NearbyShareContactManagerImpl(
71       PrefService* pref_service,
72       NearbyShareClientFactory* http_client_factory,
73       NearbyShareLocalDeviceDataManager* local_device_data_manager,
74       const std::string& profile_user_name);
75 
76   // NearbyShareContactsManager:
77   void DownloadContacts() override;
78   void SetAllowedContacts(
79       const std::set<std::string>& allowed_contact_ids) override;
80   void OnStart() override;
81   void OnStop() override;
82   void Bind(mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver)
83       override;
84 
85   // nearby_share::mojom::ContactsManager:
86   void AddDownloadContactsObserver(
87       ::mojo::PendingRemote<nearby_share::mojom::DownloadContactsObserver>
88           observer) override;
89 
90   std::set<std::string> GetAllowedContacts() const;
91   void OnPeriodicContactsUploadRequested();
92   void OnContactsDownloadRequested();
93   void OnContactsDownloadSuccess(
94       std::vector<nearbyshare::proto::ContactRecord> contacts,
95       uint32_t num_unreachable_contacts_filtered_out);
96   void OnContactsDownloadFailure();
97   void OnContactsUploadFinished(bool did_contacts_change_since_last_upload,
98                                 const std::string& contact_upload_hash,
99                                 bool success);
100   bool SetAllowlist(const std::set<std::string>& new_allowlist);
101   void NotifyMojoObserverContactsDownloaded(
102       const std::set<std::string>& allowed_contact_ids,
103       const std::vector<nearbyshare::proto::ContactRecord>& contacts,
104       uint32_t num_unreachable_contacts_filtered_out);
105 
106   PrefService* pref_service_ = nullptr;
107   NearbyShareClientFactory* http_client_factory_ = nullptr;
108   NearbyShareLocalDeviceDataManager* local_device_data_manager_ = nullptr;
109   std::string profile_user_name_;
110   std::unique_ptr<NearbyShareScheduler> periodic_contact_upload_scheduler_;
111   std::unique_ptr<NearbyShareScheduler> contact_download_and_upload_scheduler_;
112   std::unique_ptr<NearbyShareContactDownloader> contact_downloader_;
113   mojo::RemoteSet<nearby_share::mojom::DownloadContactsObserver> observers_set_;
114   mojo::ReceiverSet<nearby_share::mojom::ContactManager> receiver_set_;
115   base::WeakPtrFactory<NearbyShareContactManagerImpl> weak_ptr_factory_{this};
116 };
117 
118 #endif  // CHROME_BROWSER_NEARBY_SHARING_CONTACTS_NEARBY_SHARE_CONTACT_MANAGER_IMPL_H_
119