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

Side by Side Diff: chrome/browser/android/banners/app_banner_data_fetcher_android.cc

Issue 1148163003: Allow only responsive websites to install as a web app on mobile. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Restoring a lost nullptr check Created 5 years, 6 months 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/banners/app_banner_data_fetcher_android.h" 5 #include "chrome/browser/android/banners/app_banner_data_fetcher_android.h"
6 6
7 #include <vector>
8
9 #include "base/strings/string_util.h"
7 #include "chrome/browser/android/banners/app_banner_infobar_delegate_android.h" 10 #include "chrome/browser/android/banners/app_banner_infobar_delegate_android.h"
11 #include "chrome/browser/banners/app_banner_debug_log.h"
8 #include "chrome/browser/infobars/infobar_service.h" 12 #include "chrome/browser/infobars/infobar_service.h"
9 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h" 13 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h"
14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/render_messages.h"
10 #include "third_party/skia/include/core/SkBitmap.h" 16 #include "third_party/skia/include/core/SkBitmap.h"
11 17
18 namespace {
19
20 const char kMetaViewportTagName[] = "viewport";
21 const char kMetaViewportWidthDevice[] = "width=device-width";
22 const char kMetaViewportInitialScaleInt[] = "initial-scale=1";
23 const char kMetaViewportInitialScaleFloat[] = "initial-scale=1.0";
24
25 } // anonymous namespace
26
12 namespace banners { 27 namespace banners {
13 28
14 AppBannerDataFetcherAndroid::AppBannerDataFetcherAndroid( 29 AppBannerDataFetcherAndroid::AppBannerDataFetcherAndroid(
15 content::WebContents* web_contents, 30 content::WebContents* web_contents,
16 base::WeakPtr<Delegate> weak_delegate, 31 base::WeakPtr<Delegate> weak_delegate,
17 int ideal_icon_size) 32 int ideal_icon_size)
18 : AppBannerDataFetcher(web_contents, weak_delegate, ideal_icon_size) { 33 : AppBannerDataFetcher(web_contents, weak_delegate, ideal_icon_size) {
19 } 34 }
20 35
21 AppBannerDataFetcherAndroid::~AppBannerDataFetcherAndroid() { 36 AppBannerDataFetcherAndroid::~AppBannerDataFetcherAndroid() {
22 } 37 }
23 38
24 std::string AppBannerDataFetcherAndroid::GetBannerType() { 39 std::string AppBannerDataFetcherAndroid::GetBannerType() {
25 return native_app_data_.is_null() 40 return native_app_data_.is_null()
26 ? AppBannerDataFetcher::GetBannerType() : "android"; 41 ? AppBannerDataFetcher::GetBannerType() : "android";
27 } 42 }
28 43
29 bool AppBannerDataFetcherAndroid::ContinueFetching( 44 bool AppBannerDataFetcherAndroid::ContinueFetching(
30 const base::string16& app_title, 45 const base::string16& app_title,
31 const std::string& app_package, 46 const std::string& app_package,
32 base::android::ScopedJavaLocalRef<jobject> app_data, 47 base::android::ScopedJavaLocalRef<jobject> app_data,
33 const GURL& image_url) { 48 const GURL& image_url) {
34 set_app_title(app_title); 49 set_app_title(app_title);
35 native_app_package_ = app_package; 50 native_app_package_ = app_package;
36 native_app_data_.Reset(app_data); 51 native_app_data_.Reset(app_data);
37 return FetchIcon(image_url); 52 return FetchIcon(image_url);
38 } 53 }
39 54
55 bool AppBannerDataFetcherAndroid::OnMessageReceived(
56 const IPC::Message& message) {
57 bool handled = true;
58 IPC_BEGIN_MESSAGE_MAP(AppBannerDataFetcherAndroid, message)
59 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidRetrieveMetaTagContent,
60 OnDidRetrieveMetaTagContent)
61 IPC_MESSAGE_UNHANDLED(handled = false)
62 IPC_END_MESSAGE_MAP()
63 return handled;
64 }
65
66 void AppBannerDataFetcherAndroid::HandleWebApp(
67 content::WebContents* web_contents) {
68 Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(), validated_url_,
69 kMetaViewportTagName));
70 }
71
40 std::string AppBannerDataFetcherAndroid::GetAppIdentifier() { 72 std::string AppBannerDataFetcherAndroid::GetAppIdentifier() {
41 return native_app_data_.is_null() 73 return native_app_data_.is_null()
42 ? AppBannerDataFetcher::GetAppIdentifier() : native_app_package_; 74 ? AppBannerDataFetcher::GetAppIdentifier() : native_app_package_;
43 } 75 }
44 76
45 void AppBannerDataFetcherAndroid::ShowBanner(const SkBitmap* icon, 77 void AppBannerDataFetcherAndroid::ShowBanner(const SkBitmap* icon,
46 const base::string16& title) { 78 const base::string16& title) {
47 content::WebContents* web_contents = GetWebContents(); 79 content::WebContents* web_contents = GetWebContents();
48 DCHECK(web_contents); 80 DCHECK(web_contents);
49 81
50 infobars::InfoBar* infobar = nullptr; 82 infobars::InfoBar* infobar = nullptr;
51 if (native_app_data_.is_null()) { 83 if (native_app_data_.is_null()) {
52 scoped_ptr<AppBannerInfoBarDelegateAndroid> delegate( 84 scoped_ptr<AppBannerInfoBarDelegateAndroid> delegate(
53 new AppBannerInfoBarDelegateAndroid( 85 new AppBannerInfoBarDelegateAndroid(
54 event_request_id(), title, new SkBitmap(*icon), web_app_data())); 86 event_request_id(), title, new SkBitmap(*icon), web_app_data()));
55 87
56 infobar = 88 infobar =
57 new AppBannerInfoBarAndroid(delegate.Pass(), web_app_data().start_url); 89 new AppBannerInfoBarAndroid(delegate.Pass(), web_app_data().start_url);
58 if (infobar) 90 if (infobar)
59 RecordDidShowBanner("AppBanner.WebApp.Shown"); 91 RecordDidShowBanner("AppBanner.WebApp.Shown");
60 } else { 92 } else {
61 scoped_ptr<AppBannerInfoBarDelegateAndroid> delegate( 93 scoped_ptr<AppBannerInfoBarDelegateAndroid> delegate(
62 new AppBannerInfoBarDelegateAndroid( 94 new AppBannerInfoBarDelegateAndroid(
63 event_request_id(), title, new SkBitmap(*icon), native_app_data_, 95 event_request_id(), title, new SkBitmap(*icon), native_app_data_,
64 native_app_package_)); 96 native_app_package_));
65 infobar = new AppBannerInfoBarAndroid(delegate.Pass(), native_app_data_); 97 infobar = new AppBannerInfoBarAndroid(delegate.Pass(), native_app_data_);
66 if (infobar) 98 if (infobar)
67 RecordDidShowBanner("AppBanner.NativeApp.Shown"); 99 RecordDidShowBanner("AppBanner.NativeApp.Shown");
68 } 100 }
69 InfoBarService::FromWebContents(web_contents) 101 if (infobar) {
70 ->AddInfoBar(make_scoped_ptr(infobar)); 102 InfoBarService::FromWebContents(web_contents)
103 ->AddInfoBar(make_scoped_ptr(infobar));
104 }
105 }
106
107 // Ideally, we should be able to get this information more directly. For now, we
108 // parse the retrieved meta viewport tag (if any), and look for the necessary
109 // strings to determine if the page will scale with the viewport.
110 void AppBannerDataFetcherAndroid::OnDidRetrieveMetaTagContent(
111 bool success,
112 const std::string& tag_name,
113 const std::string& tag_content,
114 const GURL& expected_url) {
115 bool is_responsive = false;
116 if (success && tag_name == kMetaViewportTagName &&
117 validated_url_ == expected_url &&
118 tag_content.size() <= chrome::kMaxMetaTagAttributeLength) {
119 std::string local_tag_content;
120 std::vector<std::string> content_tokens;
121
122 // Perform the following steps:
123 // 1. strip spaces from the viewport content.
124 // 2. convert the content to lower case.
125 // 3. split the viewport content by commas.
126 // 4. search for the required strings.
127 base::RemoveChars(tag_content, " ", &local_tag_content);
128 base::StringToLowerASCII(&local_tag_content);
129 Tokenize(local_tag_content, ",", &content_tokens);
130
131 for (const auto& property : content_tokens) {
132 if (property == kMetaViewportWidthDevice ||
133 property == kMetaViewportInitialScaleInt ||
134 property == kMetaViewportInitialScaleFloat) {
135 is_responsive = true;
136 break;
137 }
138 }
139 }
140
141 content::WebContents* web_contents = GetWebContents();
142 if (!is_responsive) {
143 OutputDeveloperNotShownMessage(web_contents, kMetaViewportTagError);
144 Cancel();
145 return;
146 }
147
148 if (!CheckFetcherIsStillAlive(web_contents)) {
149 OutputDeveloperNotShownMessage(web_contents,
150 kUserNavigatedBeforeBannerShown);
151 Cancel();
152 return;
153 }
154
155 AppBannerDataFetcher::HandleWebApp(web_contents);
71 } 156 }
72 157
73 } // namespace banners 158 } // namespace banners
OLDNEW
« no previous file with comments | « chrome/browser/android/banners/app_banner_data_fetcher_android.h ('k') | chrome/browser/banners/app_banner_data_fetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698