File: manifest_silent_update_command.h

package info (click to toggle)
chromium 140.0.7339.80-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,201,348 kB
  • sloc: cpp: 35,092,378; ansic: 7,161,671; javascript: 4,199,703; python: 1,441,798; asm: 949,904; xml: 747,409; pascal: 187,748; perl: 88,691; sh: 88,248; objc: 79,953; sql: 52,714; cs: 44,599; fortran: 24,137; makefile: 22,119; tcl: 15,277; php: 13,980; yacc: 9,000; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (165 lines) | stat: -rw-r--r-- 6,439 bytes parent folder | download | duplicates (3)
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
// Copyright 2025 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_WEB_APPLICATIONS_COMMANDS_MANIFEST_SILENT_UPDATE_COMMAND_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_COMMANDS_MANIFEST_SILENT_UPDATE_COMMAND_H_

#include "base/functional/callback_forward.h"
#include "chrome/browser/web_applications/commands/web_app_command.h"
#include "chrome/browser/web_applications/jobs/manifest_to_web_app_install_info_job.h"
#include "chrome/browser/web_applications/locks/app_lock.h"
#include "chrome/browser/web_applications/locks/noop_lock.h"
#include "chrome/browser/web_applications/manifest_update_utils.h"
#include "chrome/browser/web_applications/proto/web_app.pb.h"
#include "chrome/browser/web_applications/web_app_icon_manager.h"
#include "chrome/browser/web_applications/web_contents/web_app_data_retriever.h"

class GURL;

namespace content {
class WebContents;
}  // namespace content

namespace web_app {

// Not actually used in production logic. This is just for debugging output.
enum class ManifestSilentUpdateCommandStage {
  kFetchingNewManifestData,
  kLoadingExistingManifestData,
  kAcquiringAppLock,
  kComparingManifestData,
  kFinalizingSilentManifestChanges,
  kCompleteCommand,
};

// This enum is recorded by UMA, the numeric values must not change.
enum class ManifestSilentUpdateCheckResult {
  kAppNotInstalled = 0,
  kAppUpdateFailedDuringInstall = 1,
  kSystemShutdown = 2,
  kAppSilentlyUpdated = 3,
  kAppUpToDate = 4,
  kIconReadFromDiskFailed = 5,
  kWebContentsDestroyed = 6,
  kAppOnlyHasSecurityUpdate = 7,
  kAppHasNonSecurityAndSecurityChanges = 8,
  kMaxValue = kAppHasNonSecurityAndSecurityChanges,
};

struct WebAppInstallInfo;

// Documentation: docs/webapps/manifest_update_process.md
//
// Checks whether the installed web app associated with a given WebContents has
// out of date manifest data and what to update it to.
//
// High level procedure for this command:
// - Download new manifest data from site.
// - Load existing manifest data from disk including external resources.
// - Diff the non-security sensitive manifest data. This includes all fields of
//   the manifest excluding icons and app name.
// - Update non-security sensitive fields silently.
// - Choose two golden icons (one each from the new and existing manifest).
// - Compare their icon's URL which determines a silent update of the icon (<10%
//   image diff) or store it as a PendingUpdateInfo (>10% image diff).
// - Finalize silent update of icon (if needed) and destroy command.
class ManifestSilentUpdateCommand
    : public WebAppCommand<NoopLock, ManifestSilentUpdateCheckResult>,
      public content::WebContentsObserver {
 public:
  using CompletedCallback =
      base::OnceCallback<void(ManifestSilentUpdateCheckResult check_result)>;

  ManifestSilentUpdateCommand(
      const GURL& url,
      base::WeakPtr<content::WebContents> web_contents,
      CompletedCallback callback,
      std::unique_ptr<WebAppDataRetriever> data_retriever,
      std::unique_ptr<WebAppIconDownloader> icon_downloader);

  ~ManifestSilentUpdateCommand() override;

 protected:
  // WebAppCommand:
  void StartWithLock(std::unique_ptr<NoopLock> lock) override;

 private:
  // Stage: Upgrade NoopLock to AppLock
  // (ManifestSilentUpdateCommandStage::kAcquiringAppLock).
  void OnManifestFetchedAcquireAppLock(
      blink::mojom::ManifestPtr opt_manifest,
      bool valid_manifest_for_web_app,
      webapps::InstallableStatusCode installable_status);

  // Stage: Starting to fetch new manifest data
  // (ManifestSilentUpdateCommandStage::kFetchingNewManifestData).
  void StartManifestToInstallInfoJob(blink::mojom::ManifestPtr opt_manifest);

  // The `install_info` will have icons populated if they were found in the
  // manifest.
  void OnWebAppInfoCreatedFromManifest(
      std::unique_ptr<WebAppInstallInfo> install_info);
  void StashValidatedScopeExtensionsAndLoadExistingManifest(
      ScopeExtensions validated_scope_extensions);

  // Stage: Loading existing manifest data from disk.
  // (ManifestSilentUpdateCommandStage::kLoadingExistingManifestData)
  void StashExistingAppIcons(WebAppIconManager::WebAppBitmaps icon_bitmaps);

  // Stage: Comparing manifest data and exiting update if no changes detected.
  // (ManifestSilentUpdateCommandStage::kComparingManifestData)
  void StashExistingShortcutsMenuIconsFinalizeUpdateIfNeeded(
      ShortcutsMenuIconBitmaps shortcuts_menu_icon_bitmaps);

  // Stage: Finalize silent changes to web app.
  // (ManifestSilentUpdateCommandStage::kFinalizingSilentManifestChanges)
  void NonSecuritySensitiveFieldsApplied(
      bool silent_update_applied,
      std::optional<proto::PendingUpdateInfo> pending_update_info,
      const webapps::AppId& app_id,
      webapps::InstallResultCode code);

  // Stage: Update check complete.
  // (ManifestSilentUpdateCommandStage::kCompleteCommand)
  void CompleteCommandAndSelfDestruct(
      ManifestSilentUpdateCheckResult check_result);

  bool IsWebContentsDestroyed();
  void AbortCommandOnWebContentsDestruction();

  base::WeakPtr<ManifestSilentUpdateCommand> GetWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

  // Manifest update check request parameters.
  const GURL url_;
  webapps::AppId app_id_;

  // Resources and helpers used to fetch manifest data.
  std::unique_ptr<NoopLock> lock_;
  std::unique_ptr<AppLock> app_lock_;
  base::WeakPtr<content::WebContents> web_contents_;
  std::unique_ptr<WebAppDataRetriever> data_retriever_;
  std::unique_ptr<WebAppIconDownloader> icon_downloader_;
  std::unique_ptr<ManifestToWebAppInstallInfoJob> manifest_to_install_info_job_;
  std::optional<apps::IconInfo> new_manifest_trusted_icon_;
  std::optional<apps::IconInfo> existing_manifest_trusted_icon_;
  bool has_icon_url_changed_;

  // Temporary variables stored here while the update check progresses
  // asynchronously.
  std::unique_ptr<WebAppInstallInfo> new_install_info_;
  IconBitmaps existing_app_icon_bitmaps_;
  ShortcutsMenuIconBitmaps existing_shortcuts_menu_icon_bitmaps_;

  // Debug info.
  ManifestSilentUpdateCommandStage stage_ =
      ManifestSilentUpdateCommandStage::kFetchingNewManifestData;

  base::WeakPtrFactory<ManifestSilentUpdateCommand> weak_factory_{this};
};

}  // namespace web_app

#endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMMANDS_MANIFEST_SILENT_UPDATE_COMMAND_H_