File: note_taking_helper.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (255 lines) | stat: -rw-r--r-- 9,593 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_NOTE_TAKING_NOTE_TAKING_HELPER_H_
#define CHROME_BROWSER_ASH_NOTE_TAKING_NOTE_TAKING_HELPER_H_

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ash/arc/session/arc_session_manager_observer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_manager_observer.h"
#include "chromeos/ash/experiences/arc/intent_helper/arc_intent_helper_bridge.h"
#include "chromeos/ash/experiences/arc/intent_helper/arc_intent_helper_observer.h"
#include "chromeos/ash/experiences/arc/mojom/intent_helper.mojom-forward.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"

class Profile;

namespace apps {
class AppUpdate;
}

namespace content {
class BrowserContext;
}  // namespace content

namespace extensions {
class Extension;
}  // namespace extensions

namespace ash {

class NoteTakingControllerClient;

// Information about an installed note-taking app.
struct NoteTakingAppInfo {
  // Application name to display to user.
  std::string name;

  // Either an extension ID (in the case of a Chrome app) or a package name (in
  // the case of an Android app) or a web app ID (in the case of a web app).
  std::string app_id;

  // True if this is the preferred note-taking app.
  bool preferred;
};

// Singleton class used to launch a note-taking app.
class NoteTakingHelper : public arc::ArcIntentHelperObserver,
                         public arc::ArcSessionManagerObserver,
                         public apps::AppRegistryCache::Observer,
                         public ProfileManagerObserver {
 public:
  // Interface for observing changes to the list of available apps.
  class Observer {
   public:
    virtual ~Observer() = default;

    // Called when the list of available apps that will be returned by
    // GetAvailableApps() changes or when |play_store_enabled_| changes state.
    virtual void OnAvailableNoteTakingAppsUpdated() = 0;

    // Called when the preferred note taking app (or its properties) in
    // |profile| is updated.
    virtual void OnPreferredNoteTakingAppUpdated(Profile* profile) = 0;
  };

  // Describes the result of an attempt to launch a note-taking app. Values must
  // not be renumbered, as this is used by histogram metrics.
  enum class LaunchResult {
    // A Chrome app was launched successfully.
    CHROME_SUCCESS = 0,
    // The requested Chrome app was unavailable.
    CHROME_APP_MISSING = 1,
    // An Android app was launched successfully.
    ANDROID_SUCCESS = 2,
    // An Android app couldn't be launched due to the profile not being allowed
    // to use ARC.
    ANDROID_NOT_SUPPORTED_BY_PROFILE = 3,
    // An Android app couldn't be launched due to ARC not running.
    ANDROID_NOT_RUNNING = 4,
    // Removed: An Android app couldn't be launched due to a failure to convert
    // the supplied path to an ARC URL.
    // ANDROID_FAILED_TO_CONVERT_PATH = 5,
    // No attempt was made due to a preferred app not being specified.
    NO_APP_SPECIFIED = 6,
    // No Android or Chrome apps were available.
    NO_APPS_AVAILABLE = 7,
    // A web app was launched successfully.
    WEB_APP_SUCCESS = 8,
    // The requested web app was unavailable.
    WEB_APP_MISSING = 9,
    // Unable to find an internal display.
    NO_INTERNAL_DISPLAY_FOUND = 10,
    // This value must remain last and should be incremented when a new reason
    // is inserted.
    MAX = 11,
  };

  // Callback used to launch a Chrome app.
  using LaunchChromeAppCallback =
      base::RepeatingCallback<void(content::BrowserContext* context,
                                   const extensions::Extension*)>;

  // Intent action used to launch Android apps.
  static const char kIntentAction[];

  // Extension IDs for the development and released versions of the Google Keep
  // Chrome app.
  static const char kDevKeepExtensionId[];
  static const char kProdKeepExtensionId[];
  // Web app IDs for testing and development versions of note-taking web apps.
  static const char kNoteTakingWebAppIdTest[];
  static const char kNoteTakingWebAppIdDev[];

  // Names of histograms.
  static const char kPreferredLaunchResultHistogramName[];
  static const char kDefaultLaunchResultHistogramName[];

  static void Initialize();
  static void Shutdown();
  static NoteTakingHelper* Get();

  NoteTakingHelper(const NoteTakingHelper&) = delete;
  NoteTakingHelper& operator=(const NoteTakingHelper&) = delete;

  bool play_store_enabled() const { return play_store_enabled_; }
  bool android_apps_received() const { return android_apps_received_; }

  void set_launch_chrome_app_callback_for_test(
      const LaunchChromeAppCallback& callback) {
    launch_chrome_app_callback_ = callback;
  }

  // Adds or removes an observer.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Inform the NoteTakingHelper that the given app was updated. May trigger
  // notifications to observers.
  void NotifyAppUpdated(Profile* profile, const std::string& app_id);

  // Returns a list of available note-taking apps, in the order they should be
  // shown in UI.
  std::vector<NoteTakingAppInfo> GetAvailableApps(Profile* profile);

  // Returns the ID of the preferred note-taking app. Empty if uninstalled or
  // not set.
  std::string GetPreferredAppId(Profile* profile);

  // Sets the preferred note-taking app. |app_id| is a value from a
  // NoteTakingAppInfo object.
  void SetPreferredApp(Profile* profile, const std::string& app_id);

  // Returns true if an app that can be used to take notes is available. UI
  // surfaces that call LaunchAppForNewNote() should be hidden otherwise.
  bool IsAppAvailable(Profile* profile);

  // Launches the note-taking app to create a new note. IsAppAvailable() must
  // be called first.
  void LaunchAppForNewNote(Profile* profile);

  // arc::ArcIntentHelperObserver:
  void OnIntentFiltersUpdated(
      const std::optional<std::string>& package_name) override;

  // arc::ArcSessionManagerObserver:
  void OnArcPlayStoreEnabledChanged(bool enabled) override;

  // ProfileManagerObserver:
  void OnProfileAdded(Profile* profile) override;
  void OnProfileManagerDestroying() override;

  NoteTakingControllerClient* GetNoteTakingControllerClientForTesting() {
    return note_taking_controller_client_.get();
  }

 private:
  NoteTakingHelper();
  ~NoteTakingHelper() override;

  // Queries and returns the app IDs of note-taking Chrome/web apps that are
  // installed, enabled, and allowed for |profile|.
  std::vector<std::string> GetNoteTakingAppIds(Profile* profile) const;

  // Requests a list of Android note-taking apps from ARC.
  void UpdateAndroidApps();

  // Handles ARC's response to an earlier UpdateAndroidApps() call.
  void OnGotAndroidApps(std::vector<arc::mojom::IntentHandlerInfoPtr> handlers);

  // Helper method that launches |app_id| (either an Android package name or a
  // Chrome extension ID) to create a new note. Returns the attempt's result.
  LaunchResult LaunchAppInternal(Profile* profile, const std::string& app_id);

  // apps::AppRegistryCache::Observer
  void OnAppUpdate(const apps::AppUpdate& update) override;
  void OnAppRegistryCacheWillBeDestroyed(
      apps::AppRegistryCache* cache) override;

  // True iff Play Store is enabled (i.e. per the checkbox on the settings
  // page). Note that ARC may not be fully started yet when this is true, but it
  // is expected to start eventually. Similarly, ARC may not be fully shut down
  // yet when this is false, but will be eventually.
  bool play_store_enabled_ = false;

  // This is set to true after |android_apps_| is updated.
  bool android_apps_received_ = false;

  // Callback used to launch Chrome apps. Can be overridden for tests.
  LaunchChromeAppCallback launch_chrome_app_callback_;

  // IDs of allowed (but not necessarily installed) Chrome apps or web apps for
  // note-taking, in the order in which they're chosen if the user hasn't
  // expressed a preference. Explicitly set by command-line and a default
  // hard-coded list.
  std::vector<std::string> force_allowed_app_ids_;

  // Cached information about available Android note-taking apps.
  std::vector<NoteTakingAppInfo> android_apps_;

  // Observes ArcIntentHelper for changes to Android intent filters.
  // TODO(crbug.com/40228788): Remove when App Service publishes Android Apps
  // with note-taking intent.
  base::ScopedMultiSourceObservation<arc::ArcIntentHelperBridge,
                                     arc::ArcIntentHelperObserver>
      arc_intent_helper_observations_{this};

  // Obseves App Registry for all profiles with an App Registry.
  base::ScopedMultiSourceObservation<apps::AppRegistryCache,
                                     apps::AppRegistryCache::Observer>
      app_registry_observations_{this};

  base::ScopedObservation<ProfileManager, ProfileManagerObserver>
      profile_manager_observation_{this};

  base::ObserverList<Observer>::Unchecked observers_;

  std::unique_ptr<NoteTakingControllerClient> note_taking_controller_client_;

  base::WeakPtrFactory<NoteTakingHelper> weak_ptr_factory_{this};
};

}  // namespace ash

#endif  // CHROME_BROWSER_ASH_NOTE_TAKING_NOTE_TAKING_HELPER_H_