Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: chrome/browser/android/webapk/manifest_upgrade_detector_fetcher.cc

Issue 2460253002: Update WebAPKs even if the WebAPK start URL has no Web Manifest part 2/3 (Closed)
Patch Set: Merge branch 'master' into update_fail_refactor0 Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/android/webapk/manifest_upgrade_detector_fetcher.h"
6
7 #include <jni.h>
8 #include <vector>
9
10 #include "base/android/jni_array.h"
11 #include "base/android/jni_string.h"
12 #include "chrome/browser/android/shortcut_helper.h"
13 #include "chrome/browser/android/webapk/webapk_icon_hasher.h"
14 #include "chrome/browser/android/webapk/webapk_web_manifest_checker.h"
15 #include "chrome/browser/installable/installable_manager.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/common/manifest.h"
19 #include "jni/ManifestUpgradeDetectorFetcher_jni.h"
20 #include "third_party/smhasher/src/MurmurHash2.h"
21 #include "ui/gfx/android/java_bitmap.h"
22 #include "ui/gfx/codec/png_codec.h"
23 #include "url/gurl.h"
24
25 using base::android::JavaParamRef;
26 using base::android::ScopedJavaLocalRef;
27
28 namespace {
29
30 // Returns whether the given |url| is within the scope of the |scope| url.
31 bool IsInScope(const GURL& url, const GURL& scope) {
32 return base::StartsWith(url.spec(), scope.spec(),
33 base::CompareCase::SENSITIVE);
34 }
35
36 } // anonymous namespace
37
38 jlong Initialize(JNIEnv* env,
39 const JavaParamRef<jobject>& obj,
40 const JavaParamRef<jstring>& java_scope_url,
41 const JavaParamRef<jstring>& java_web_manifest_url) {
42 GURL scope(base::android::ConvertJavaStringToUTF8(env, java_scope_url));
43 GURL web_manifest_url(base::android::ConvertJavaStringToUTF8(
44 env, java_web_manifest_url));
45 ManifestUpgradeDetectorFetcher* fetcher =
46 new ManifestUpgradeDetectorFetcher(env, obj, scope, web_manifest_url);
47 return reinterpret_cast<intptr_t>(fetcher);
48 }
49
50 ManifestUpgradeDetectorFetcher::ManifestUpgradeDetectorFetcher(
51 JNIEnv* env,
52 jobject obj,
53 const GURL& scope,
54 const GURL& web_manifest_url)
55 : content::WebContentsObserver(nullptr),
56 scope_(scope),
57 web_manifest_url_(web_manifest_url),
58 info_(GURL()),
59 weak_ptr_factory_(this) {
60 java_ref_.Reset(env, obj);
61 }
62
63 ManifestUpgradeDetectorFetcher::~ManifestUpgradeDetectorFetcher() {
64 }
65
66 // static
67 bool ManifestUpgradeDetectorFetcher::Register(JNIEnv* env) {
68 return RegisterNativesImpl(env);
69 }
70
71 void ManifestUpgradeDetectorFetcher::ReplaceWebContents(
72 JNIEnv* env,
73 const JavaParamRef<jobject>& obj,
74 const JavaParamRef<jobject>& java_web_contents) {
75 content::WebContents* web_contents =
76 content::WebContents::FromJavaWebContents(java_web_contents);
77 content::WebContentsObserver::Observe(web_contents);
78 }
79
80 void ManifestUpgradeDetectorFetcher::Destroy(JNIEnv* env,
81 const JavaParamRef<jobject>& obj) {
82 delete this;
83 }
84
85 void ManifestUpgradeDetectorFetcher::Start(
86 JNIEnv* env,
87 const JavaParamRef<jobject>& obj,
88 const JavaParamRef<jobject>& java_web_contents) {
89 ReplaceWebContents(env, obj, java_web_contents);
90 if (!web_contents()->IsLoading())
91 FetchInstallableData();
92 }
93
94 void ManifestUpgradeDetectorFetcher::DidStopLoading() {
95 FetchInstallableData();
96 }
97
98 void ManifestUpgradeDetectorFetcher::FetchInstallableData() {
99 GURL url = web_contents()->GetLastCommittedURL();
100
101 // DidStopLoading() can be called multiple times for a single URL. Only fetch
102 // installable data the first time.
103 if (url == last_fetched_url_)
104 return;
105 last_fetched_url_ = url;
106
107 if (!IsInScope(url, scope_))
108 return;
109
110 InstallableParams params;
111 params.ideal_icon_size_in_dp =
112 ShortcutHelper::GetIdealHomescreenIconSizeInDp();
113 params.minimum_icon_size_in_dp =
114 ShortcutHelper::GetMinimumHomescreenIconSizeInDp();
115 params.check_installable = true;
116 params.fetch_valid_icon = true;
117 InstallableManager::CreateForWebContents(web_contents());
118 InstallableManager* installable_manager =
119 InstallableManager::FromWebContents(web_contents());
120 installable_manager->GetData(
121 params,
122 base::Bind(&ManifestUpgradeDetectorFetcher::OnDidGetInstallableData,
123 weak_ptr_factory_.GetWeakPtr()));
124 }
125
126 void ManifestUpgradeDetectorFetcher::OnDidGetInstallableData(
127 const InstallableData& data) {
128 // If the manifest is empty, it means the current WebContents doesn't
129 // associate with a Web Manifest. In such case, we ignore the empty manifest
130 // and continue observing the WebContents's loading until we find a page that
131 // links to the Web Manifest that we are looking for.
132 // If the manifest URL is different from the current one, we will continue
133 // observing too. It is based on our assumption that it is invalid for
134 // web developers to change the Web Manifest location. When it does
135 // change, we will treat the new Web Manifest as the one of another WebAPK.
136 if (data.manifest.IsEmpty() || web_manifest_url_ != data.manifest_url)
137 return;
138
139 // TODO(pkotwicz): Tell Java side that the Web Manifest was fetched but the
140 // Web Manifest is not WebAPK-compatible. (http://crbug.com/639536)
141 if (data.error_code != NO_ERROR_DETECTED ||
142 !AreWebManifestUrlsWebApkCompatible(data.manifest)) {
143 return;
144 }
145
146 info_.UpdateFromManifest(data.manifest);
147 info_.manifest_url = data.manifest_url;
148 info_.best_icon_url = data.icon_url;
149 best_icon_ = *data.icon;
150
151 icon_hasher_.reset(new WebApkIconHasher());
152 Profile* profile =
153 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
154 icon_hasher_->DownloadAndComputeMurmur2Hash(
155 profile->GetRequestContext(),
156 data.icon_url,
157 base::Bind(&ManifestUpgradeDetectorFetcher::OnGotIconMurmur2Hash,
158 weak_ptr_factory_.GetWeakPtr()));
159 }
160
161 void ManifestUpgradeDetectorFetcher::OnGotIconMurmur2Hash(
162 const std::string& best_icon_murmur2_hash) {
163 icon_hasher_.reset();
164
165 if (best_icon_murmur2_hash.empty()) {
166 // TODO(pkotwicz): Tell Java side that the Web Manifest was fetched but the
167 // Web Manifest is not WebAPK-compatible. (http://crbug.com/639536)
168 return;
169 }
170
171 OnDataAvailable(info_, best_icon_murmur2_hash, best_icon_);
172 }
173
174 void ManifestUpgradeDetectorFetcher::OnDataAvailable(
175 const ShortcutInfo& info,
176 const std::string& best_icon_murmur2_hash,
177 const SkBitmap& best_icon_bitmap) {
178 JNIEnv* env = base::android::AttachCurrentThread();
179
180 ScopedJavaLocalRef<jstring> java_url =
181 base::android::ConvertUTF8ToJavaString(env, info.url.spec());
182 ScopedJavaLocalRef<jstring> java_scope =
183 base::android::ConvertUTF8ToJavaString(env, info.scope.spec());
184 ScopedJavaLocalRef<jstring> java_name =
185 base::android::ConvertUTF16ToJavaString(env, info.name);
186 ScopedJavaLocalRef<jstring> java_short_name =
187 base::android::ConvertUTF16ToJavaString(env, info.short_name);
188 ScopedJavaLocalRef<jstring> java_best_icon_url =
189 base::android::ConvertUTF8ToJavaString(env, info.best_icon_url.spec());
190 ScopedJavaLocalRef<jstring> java_best_icon_murmur2_hash =
191 base::android::ConvertUTF8ToJavaString(env, best_icon_murmur2_hash);
192 ScopedJavaLocalRef<jobject> java_best_bitmap =
193 gfx::ConvertToJavaBitmap(&best_icon_bitmap);
194
195 ScopedJavaLocalRef<jobjectArray> java_icon_urls =
196 base::android::ToJavaArrayOfStrings(env, info.icon_urls);
197
198 Java_ManifestUpgradeDetectorFetcher_onDataAvailable(
199 env, java_ref_, java_url, java_scope, java_name, java_short_name,
200 java_best_icon_url, java_best_icon_murmur2_hash, java_best_bitmap,
201 java_icon_urls, info.display, info.orientation, info.theme_color,
202 info.background_color);
203 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698