1 // Copyright 2017 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_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_CONTROLLER_WIN_H_
6 #define CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_CONTROLLER_WIN_H_
7 
8 #include <set>
9 #include <vector>
10 
11 #include "base/callback.h"
12 #include "base/files/file_path.h"
13 #include "base/macros.h"
14 #include "base/observer_list.h"
15 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results_win.h"
16 #include "chrome/browser/safe_browsing/chrome_cleaner/sw_reporter_invocation_win.h"
17 #include "components/prefs/pref_registry_simple.h"
18 
19 class Profile;
20 
21 namespace extensions {
22 class ExtensionService;
23 }
24 
25 namespace safe_browsing {
26 
27 // These values are used to send UMA information and are replicated in the
28 // histograms.xml file, so the order MUST NOT CHANGE.
29 enum CleanupStartedHistogramValue {
30   CLEANUP_STARTED_FROM_PROMPT_DIALOG = 0,
31   CLEANUP_STARTED_FROM_PROMPT_IN_SETTINGS = 1,
32 
33   CLEANUP_STARTED_MAX,
34 };
35 
36 // Records a SoftwareReporter.CleanupStarted histogram.
37 void RecordCleanupStartedHistogram(CleanupStartedHistogramValue value);
38 
39 // Interface for the Chrome Cleaner controller class that keeps track of the
40 // execution of the Chrome Cleaner and the various states through which the
41 // execution will transition. Observers can register themselves to be notified
42 // of state changes. Intended to be used by the Chrome Cleaner webui page and
43 // the Chrome Cleaner prompt dialog.
44 //
45 // This class lives on, and all its members should be called only on, the UI
46 // thread.
47 class ChromeCleanerController {
48  public:
49   enum class State {
50     // The default state where there is no Chrome Cleaner process or IPC to keep
51     // track of and a reboot of the machine is not required to complete previous
52     // cleaning attempts. This is also the state the controller will end up in
53     // if any errors occur during execution of the Chrome Cleaner process.
54     kIdle,
55     // The Software Reporter tool is currently running and there is no pending
56     // action corresponding to a cleaner execution.
57     kReporterRunning,
58     // All steps up to and including scanning the machine occur in this
59     // state. The steps include downloading the Chrome Cleaner binary, setting
60     // up an IPC between Chrome and the Cleaner process, and the actual
61     // scanning done by the Cleaner.
62     kScanning,
63     // Scanning has been completed and harmful or unwanted software was
64     // found. In this state, the controller is waiting to get a response from
65     // the user on whether or not they want the cleaner to remove the harmful
66     // software that was found.
67     kInfected,
68     // The Cleaner process is cleaning the machine.
69     kCleaning,
70     // The cleaning has finished, but a reboot of the machine is required to
71     // complete cleanup. This state will persist across restarts of Chrome until
72     // a reboot is detected.
73     kRebootRequired,
74   };
75 
76   enum class IdleReason {
77     kInitial,
78     kReporterFoundNothing,
79     kReporterFailed,
80     kScanningFoundNothing,
81     kScanningFailed,
82     kConnectionLost,
83     kUserDeclinedCleanup,
84     kCleaningFailed,
85     kCleaningSucceeded,
86     kCleanerDownloadFailed,
87   };
88 
89   enum class UserResponse {
90     // User accepted the cleanup operation and logs upload is enabled.
91     kAcceptedWithLogs,
92     // User accepted the cleanup operation and logs upload is not enabled.
93     kAcceptedWithoutLogs,
94     // User explicitly denied the cleanup operation, for example by clicking the
95     // Cleaner dialog's cancel button.
96     kDenied,
97     // The cleanup operation was denied when the user dismissed the Cleaner
98     // dialog, for example by pressing the ESC key.
99     kDismissed,
100   };
101 
102   class Observer : public base::CheckedObserver {
103    public:
OnIdle(IdleReason idle_reason)104     virtual void OnIdle(IdleReason idle_reason) {}
OnReporterRunning()105     virtual void OnReporterRunning() {}
OnScanning()106     virtual void OnScanning() {}
OnInfected(bool is_powered_by_partner,const ChromeCleanerScannerResults & scanner_results)107     virtual void OnInfected(
108         bool is_powered_by_partner,
109         const ChromeCleanerScannerResults& scanner_results) {}
OnCleaning(bool is_powered_by_partner,const ChromeCleanerScannerResults & scanner_results)110     virtual void OnCleaning(
111         bool is_powered_by_partner,
112         const ChromeCleanerScannerResults& scanner_results) {}
OnRebootRequired()113     virtual void OnRebootRequired() {}
OnRebootFailed()114     virtual void OnRebootFailed() {}
115   };
116 
117   // Returns the global controller object.
118   static ChromeCleanerController* GetInstance();
119 
120   virtual State state() const = 0;
121   virtual IdleReason idle_reason() const = 0;
122 
123   // Called by Chrome Cleaner's UI when the user changes Cleaner logs upload
124   // permissions. Observers are notified if |logs_enabled| is different from the
125   // current permission state.
126   virtual void SetLogsEnabled(Profile* profile, bool logs_enabled) = 0;
127   virtual bool logs_enabled(Profile* profile) const = 0;
128 
129   // Called by the Chrome Cleaner's UI when the user dismisses the card while
130   // in the kIdle state. Does nothing if the current state is not |kIdle|.
131   virtual void ResetIdleState() = 0;
132 
133   // |AddObserver()| immediately notifies |observer| of the controller's state
134   // by calling the corresponding |On*()| function.
135   virtual void AddObserver(Observer* observer) = 0;
136   virtual void RemoveObserver(Observer* observer) = 0;
137   virtual bool HasObserver(Observer* observer) = 0;
138 
139   // Invoked by the reporter runner, notifies the controller that a reporter
140   // sequence started. If there is no pending cleaner action (currently on the
141   // kIdle state), then it will transition to the kReporterRunning state.
142   virtual void OnReporterSequenceStarted() = 0;
143 
144   // Invoked by the reporter runner, notifies the controller that a reporter
145   // sequence completed (or has not been scheduled). If there is no pending
146   // cleaner action (currently on kIdle or kReporterRunning state), then it will
147   // transition to either kScanning, if the reporter found removable UwS, or
148   // kIdle otherwise.
149   virtual void OnReporterSequenceDone(SwReporterInvocationResult result) = 0;
150 
151   // Attempts to start the reporter runner to scan the system for unwanted
152   // software. Once the reporter runner has started (which may involve
153   // downloading the SwReporter component), |OnReporterSequenceStarted| and
154   // |OnReporterSequenceDone| will be called with the result.
155   //
156   // This can have adverse effects on the component updater subsystem and
157   // should only be called from direct user action.
158   virtual void RequestUserInitiatedScan(Profile* profile) = 0;
159 
160   // Calls |MaybeStartSwReporter| with the |invocation_type| of the next
161   // scheduled run, which will be |SwReporterInvocationType::kPeriodicRun|
162   // unless the user has manually requested a reporter run, in which case the
163   // |SwReporterInvocationType::kUserInitiatedWithLogsAllowed| or
164   // |SwReporterInvocationType::kUserInitiatedWithLogsDisallowed| types will be
165   // passed.
166   virtual void OnSwReporterReady(
167       SwReporterInvocationSequence&& invocations) = 0;
168 
169   // Downloads the Chrome Cleaner binary, executes it and waits for the Cleaner
170   // to communicate with Chrome about harmful software found on the
171   // system. During this time, the controller will be in the kScanning state. If
172   // any of the steps fail or if the Cleaner does not find harmful software on
173   // the system, the controller will transition to the kIdle state, passing to
174   // observers the reason for the transition. Otherwise, the scanner will
175   // transition to the kInfected state.
176   //
177   // |reporter_invocation| is the invocation that was used to run the reporter
178   // which found possible harmful software on the system.
179   //
180   // A call to Scan() will be a no-op if the controller is not in the kIdle
181   // state. This gracefully handles cases where multiple user responses are
182   // received, for example if a user manages to click on a "Scan" button
183   // multiple times.
184   virtual void Scan(const SwReporterInvocation& reporter_invocation) = 0;
185 
186   // Sends the user's response, as to whether or not they want the Chrome
187   // Cleaner to remove harmful software that was found, to the Chrome Cleaner
188   // process. If the user accepted the prompt, then tags |profile| for
189   // post-cleanup settings reset.
190   //
191   // A call to ReplyWithUserResponse() will be a no-op if the controller is not
192   // in the kInfected state. This gracefully handles cases where multiple user
193   // responses are received, for example if a user manages to click on a
194   // "Cleanup" button multiple times.
195   virtual void ReplyWithUserResponse(
196       Profile* profile,
197       extensions::ExtensionService* extension_service,
198       UserResponse user_response) = 0;
199 
200   // If the controller is in the kRebootRequired state, initiates a reboot of
201   // the computer. Call this after obtaining permission from the user to
202   // reboot.
203   //
204   // If initiating the reboot fails, observers will be notified via a call to
205   // OnRebootFailed().
206   //
207   // Note that there are no guarantees that the reboot will in fact happen even
208   // if the system calls to initiate a reboot return success.
209   virtual void Reboot() = 0;
210 
211   // Returns true if the cleaner is allowed to run by enterprise policy.
212   virtual bool IsAllowedByPolicy() = 0;
213 
214   // Returns true if cleaner reporting is managed by enterprise policy.
215   virtual bool IsReportingManagedByPolicy(Profile* profile) = 0;
216 
217  protected:
218   ChromeCleanerController();
219   virtual ~ChromeCleanerController();
220 
221  private:
222   DISALLOW_COPY_AND_ASSIGN(ChromeCleanerController);
223 };
224 
225 // Registers the reporter scan completion time preference.
226 void RegisterChromeCleanerScanCompletionTimePref(PrefRegistrySimple* registry);
227 
228 //  These are used for debug output in tests.
229 std::ostream& operator<<(std::ostream& out,
230                          ChromeCleanerController::State state);
231 
232 std::ostream& operator<<(std::ostream& out,
233                          ChromeCleanerController::UserResponse response);
234 
235 }  // namespace safe_browsing
236 
237 #endif  // CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_CONTROLLER_WIN_H_
238