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

Side by Side Diff: chrome/browser/permissions/permission_dialog_delegate.cc

Issue 2899973002: Hide modal permission prompts on Android upon tab navigation/destruction (Closed)
Patch Set: clean up Created 3 years, 7 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 2016 The Chromium Authors. All rights reserved. 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 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/permissions/permission_dialog_delegate.h" 5 #include "chrome/browser/permissions/permission_dialog_delegate.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_array.h" 10 #include "base/android/jni_array.h"
11 #include "base/android/jni_string.h" 11 #include "base/android/jni_string.h"
12 #include "base/feature_list.h" 12 #include "base/feature_list.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "chrome/browser/android/resource_mapper.h" 14 #include "chrome/browser/android/resource_mapper.h"
15 #include "chrome/browser/android/tab_android.h" 15 #include "chrome/browser/android/tab_android.h"
16 #include "chrome/browser/geolocation/geolocation_infobar_delegate_android.h" 16 #include "chrome/browser/geolocation/geolocation_infobar_delegate_android.h"
17 #include "chrome/browser/media/midi_permission_infobar_delegate_android.h" 17 #include "chrome/browser/media/midi_permission_infobar_delegate_android.h"
18 #include "chrome/browser/media/protected_media_identifier_infobar_delegate_andro id.h" 18 #include "chrome/browser/media/protected_media_identifier_infobar_delegate_andro id.h"
19 #include "chrome/browser/media/webrtc/media_stream_infobar_delegate_android.h" 19 #include "chrome/browser/media/webrtc/media_stream_infobar_delegate_android.h"
20 #include "chrome/browser/notifications/notification_permission_infobar_delegate. h" 20 #include "chrome/browser/notifications/notification_permission_infobar_delegate. h"
21 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/common/chrome_features.h" 22 #include "chrome/common/chrome_features.h"
23 #include "components/variations/variations_associated_data.h" 23 #include "components/variations/variations_associated_data.h"
24 #include "content/public/browser/navigation_handle.h"
24 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
25 #include "jni/PermissionDialogController_jni.h" 26 #include "jni/PermissionDialogController_jni.h"
26 #include "jni/PermissionDialogDelegate_jni.h" 27 #include "jni/PermissionDialogDelegate_jni.h"
27 #include "ui/android/window_android.h" 28 #include "ui/android/window_android.h"
28 #include "ui/base/window_open_disposition.h" 29 #include "ui/base/window_open_disposition.h"
29 30
30 using base::android::ConvertUTF16ToJavaString; 31 using base::android::ConvertUTF16ToJavaString;
31 32
32 namespace { 33 namespace {
33 34
(...skipping 14 matching lines...) Expand all
48 49
49 // If we don't have a tab, just act as though the prompt was dismissed. 50 // If we don't have a tab, just act as though the prompt was dismissed.
50 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); 51 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
51 if (!tab) { 52 if (!tab) {
52 callback.Run(false, PermissionAction::DISMISSED); 53 callback.Run(false, PermissionAction::DISMISSED);
53 return; 54 return;
54 } 55 }
55 56
56 // Dispatch the dialog to Java, which manages the lifetime of this object. 57 // Dispatch the dialog to Java, which manages the lifetime of this object.
57 new PermissionDialogDelegate( 58 new PermissionDialogDelegate(
58 tab, PermissionInfoBarDelegate::CreateDelegate( 59 tab, web_contents,
59 type, requesting_frame, user_gesture, profile, callback)); 60 PermissionInfoBarDelegate::CreateDelegate(
61 type, requesting_frame, user_gesture, profile, callback));
60 } 62 }
61 63
62 // static 64 // static
63 void PermissionDialogDelegate::CreateMediaStreamDialog( 65 void PermissionDialogDelegate::CreateMediaStreamDialog(
64 content::WebContents* web_contents, 66 content::WebContents* web_contents,
65 bool user_gesture, 67 bool user_gesture,
66 std::unique_ptr<MediaStreamDevicesController::Request> request) { 68 std::unique_ptr<MediaStreamDevicesController::Request> request) {
67 DCHECK(web_contents); 69 DCHECK(web_contents);
68 70
69 // If we don't have a tab, just act as though the prompt was dismissed. 71 // If we don't have a tab, just act as though the prompt was dismissed.
70 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); 72 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
71 if (!tab) { 73 if (!tab) {
72 request->Cancelled(); 74 request->Cancelled();
73 return; 75 return;
74 } 76 }
75 77
76 // Called this way because the infobar delegate has a private destructor. 78 // Called this way because the infobar delegate has a private destructor.
77 std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate; 79 std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate;
78 infobar_delegate.reset(new MediaStreamInfoBarDelegateAndroid( 80 infobar_delegate.reset(new MediaStreamInfoBarDelegateAndroid(
79 Profile::FromBrowserContext(web_contents->GetBrowserContext()), 81 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
80 user_gesture, std::move(request))); 82 user_gesture, std::move(request)));
81 83
82 // Dispatch the dialog to Java, which manages the lifetime of this object. 84 // Dispatch the dialog to Java, which manages the lifetime of this object.
83 new PermissionDialogDelegate(tab, std::move(infobar_delegate)); 85 new PermissionDialogDelegate(tab, web_contents, std::move(infobar_delegate));
84 } 86 }
85 87
86 // static 88 // static
87 bool PermissionDialogDelegate::ShouldShowDialog(bool has_user_gesture) { 89 bool PermissionDialogDelegate::ShouldShowDialog(bool has_user_gesture) {
88 if (!base::FeatureList::IsEnabled(features::kModalPermissionPrompts)) 90 if (!base::FeatureList::IsEnabled(features::kModalPermissionPrompts))
89 return false; 91 return false;
90 92
91 // Only use modals when the prompt is triggered by a user gesture, unless the 93 // Only use modals when the prompt is triggered by a user gesture, unless the
92 // kModalParamsUserGestureKey is set to false. 94 // kModalParamsUserGestureKey is set to false.
93 std::string require_gesture = variations::GetVariationParamValueByFeature( 95 std::string require_gesture = variations::GetVariationParamValueByFeature(
94 features::kModalPermissionPrompts, kModalParamsUserGestureKey); 96 features::kModalPermissionPrompts, kModalParamsUserGestureKey);
95 if (require_gesture == "false") 97 if (require_gesture == "false")
96 return true; 98 return true;
97 return has_user_gesture; 99 return has_user_gesture;
98 } 100 }
99 101
100 // static 102 // static
101 bool PermissionDialogDelegate::RegisterPermissionDialogDelegate(JNIEnv* env) { 103 bool PermissionDialogDelegate::RegisterPermissionDialogDelegate(JNIEnv* env) {
102 return RegisterNativesImpl(env); 104 return RegisterNativesImpl(env);
103 } 105 }
104 106
105 ScopedJavaLocalRef<jobject> PermissionDialogDelegate::CreateJavaDelegate( 107 void PermissionDialogDelegate::CreateJavaDelegate(JNIEnv* env) {
106 JNIEnv* env) {
107 std::vector<int> content_settings_types{ 108 std::vector<int> content_settings_types{
108 infobar_delegate_->content_settings_types()}; 109 infobar_delegate_->content_settings_types()};
109 110
110 return Java_PermissionDialogDelegate_create( 111 j_delegate_.Reset(Java_PermissionDialogDelegate_create(
111 env, reinterpret_cast<uintptr_t>(this), 112 env, reinterpret_cast<uintptr_t>(this), tab_->GetJavaObject(),
112 tab_->GetJavaObject(),
113 base::android::ToJavaIntArray(env, content_settings_types).obj(), 113 base::android::ToJavaIntArray(env, content_settings_types).obj(),
114 ResourceMapper::MapFromChromiumId(infobar_delegate_->GetIconId()), 114 ResourceMapper::MapFromChromiumId(infobar_delegate_->GetIconId()),
115 ConvertUTF16ToJavaString(env, infobar_delegate_->GetMessageText()), 115 ConvertUTF16ToJavaString(env, infobar_delegate_->GetMessageText()),
116 ConvertUTF16ToJavaString(env, infobar_delegate_->GetLinkText()), 116 ConvertUTF16ToJavaString(env, infobar_delegate_->GetLinkText()),
117 ConvertUTF16ToJavaString(env, infobar_delegate_->GetButtonLabel( 117 ConvertUTF16ToJavaString(env, infobar_delegate_->GetButtonLabel(
118 PermissionInfoBarDelegate::BUTTON_OK)), 118 PermissionInfoBarDelegate::BUTTON_OK)),
119 ConvertUTF16ToJavaString(env, 119 ConvertUTF16ToJavaString(env,
120 infobar_delegate_->GetButtonLabel( 120 infobar_delegate_->GetButtonLabel(
121 PermissionInfoBarDelegate::BUTTON_CANCEL)), 121 PermissionInfoBarDelegate::BUTTON_CANCEL)),
122 infobar_delegate_->ShouldShowPersistenceToggle()); 122 infobar_delegate_->ShouldShowPersistenceToggle()));
123 } 123 }
124 124
125 void PermissionDialogDelegate::Accept(JNIEnv* env, 125 void PermissionDialogDelegate::Accept(JNIEnv* env,
126 const JavaParamRef<jobject>& obj, 126 const JavaParamRef<jobject>& obj,
127 jboolean persist) { 127 jboolean persist) {
128 if (infobar_delegate_->ShouldShowPersistenceToggle()) 128 if (infobar_delegate_->ShouldShowPersistenceToggle())
129 infobar_delegate_->set_persist(persist); 129 infobar_delegate_->set_persist(persist);
130 infobar_delegate_->Accept(); 130 infobar_delegate_->Accept();
131 } 131 }
132 132
(...skipping 18 matching lines...) Expand all
151 if (tab_->web_contents()) { 151 if (tab_->web_contents()) {
152 tab_->web_contents()->OpenURL(content::OpenURLParams( 152 tab_->web_contents()->OpenURL(content::OpenURLParams(
153 infobar_delegate_->GetLinkURL(), content::Referrer(), 153 infobar_delegate_->GetLinkURL(), content::Referrer(),
154 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, 154 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
155 false)); 155 false));
156 } 156 }
157 } 157 }
158 158
159 void PermissionDialogDelegate::Destroy(JNIEnv* env, 159 void PermissionDialogDelegate::Destroy(JNIEnv* env,
160 const JavaParamRef<jobject>& obj) { 160 const JavaParamRef<jobject>& obj) {
161 j_delegate_ = nullptr;
161 delete this; 162 delete this;
162 } 163 }
163 164
164 PermissionDialogDelegate::PermissionDialogDelegate( 165 PermissionDialogDelegate::PermissionDialogDelegate(
165 TabAndroid* tab, 166 TabAndroid* tab,
167 content::WebContents* web_contents,
dominickn 2017/05/24 03:33:38 No need to pass this: use tab->web_contents()
Timothy Loh 2017/05/24 04:59:33 Done.
166 std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate) 168 std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate)
167 : tab_(tab), infobar_delegate_(std::move(infobar_delegate)) { 169 : WebContentsObserver(web_contents),
dominickn 2017/05/24 03:33:38 Nit: content::WebContentsObserver for completeness
Timothy Loh 2017/05/24 04:59:33 Done.
170 tab_(tab),
171 infobar_delegate_(std::move(infobar_delegate)) {
168 DCHECK(tab_); 172 DCHECK(tab_);
169 DCHECK(infobar_delegate_); 173 DCHECK(infobar_delegate_);
170 174
171 // Create our Java counterpart, which manages our lifetime. 175 // Create our Java counterpart, which manages our lifetime.
172 JNIEnv* env = base::android::AttachCurrentThread(); 176 JNIEnv* env = base::android::AttachCurrentThread();
173 base::android::ScopedJavaLocalRef<jobject> j_delegate = 177 CreateJavaDelegate(env);
174 CreateJavaDelegate(env);
175 178
176 // Send the Java delegate to the Java PermissionDialogController for display. 179 // Send the Java delegate to the Java PermissionDialogController for display.
177 // The controller takes over lifetime management; when the Java delegate is no 180 // The controller takes over lifetime management; when the Java delegate is no
178 // longer needed it will in turn free the native delegate. 181 // longer needed it will in turn free the native delegate.
179 Java_PermissionDialogController_createDialog(env, j_delegate.obj()); 182 Java_PermissionDialogController_createDialog(env, j_delegate_.obj());
180 } 183 }
181 184
182 PermissionDialogDelegate::~PermissionDialogDelegate() {} 185 PermissionDialogDelegate::~PermissionDialogDelegate() {}
186
187 void PermissionDialogDelegate::DestroyJavaDelegate() {
dominickn 2017/05/24 03:33:38 Call this DismissDialog()
Timothy Loh 2017/05/24 04:59:33 Done.
188 JNIEnv* env = base::android::AttachCurrentThread();
189 Java_PermissionDialogDelegate_destroyFromNative(env, j_delegate_.obj());
190 }
191
192 void PermissionDialogDelegate::DidFinishNavigation(
193 content::NavigationHandle* navigation_handle) {
194 if (!navigation_handle->IsInMainFrame() ||
dominickn 2017/05/24 03:33:38 This means that if we have a third party iframe th
Timothy Loh 2017/05/24 04:59:33 Yeah, I might add some tests in a separate patch.
195 !navigation_handle->HasCommitted() ||
196 navigation_handle->IsSameDocument()) {
197 return;
198 }
199
200 DestroyJavaDelegate();
201 delete this;
202 }
203
204 void PermissionDialogDelegate::WebContentsDestroyed() {
205 DestroyJavaDelegate();
206 delete this;
207 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698