OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 package org.chromium.chrome.browser.fullscreen; | 5 package org.chromium.chrome.browser.fullscreen; |
6 | 6 |
7 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; | 7 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; |
8 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; | 8 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; |
9 import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE; | 9 import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE; |
10 | 10 |
11 import android.content.res.Resources; | 11 import android.content.res.Resources; |
12 import android.os.Build; | 12 import android.os.Build; |
13 import android.os.Bundle; | 13 import android.os.Bundle; |
14 import android.os.Handler; | 14 import android.os.Handler; |
15 import android.os.Message; | 15 import android.os.Message; |
16 import android.view.Gravity; | 16 import android.view.Gravity; |
17 import android.view.View; | 17 import android.view.View; |
18 import android.view.View.OnLayoutChangeListener; | 18 import android.view.View.OnLayoutChangeListener; |
19 import android.view.Window; | 19 import android.view.Window; |
20 import android.view.WindowManager; | 20 import android.view.WindowManager; |
21 | 21 |
22 import org.chromium.chrome.R; | 22 import org.chromium.chrome.R; |
23 import org.chromium.chrome.browser.widget.TextBubble; | 23 import org.chromium.chrome.browser.widget.TextBubble; |
24 import org.chromium.content.browser.ContentViewCore; | 24 import org.chromium.content.browser.ContentViewCore; |
25 | 25 |
| 26 import java.lang.ref.WeakReference; |
| 27 |
26 /** | 28 /** |
27 * Handles updating the UI based on requests to the HTML Fullscreen API. | 29 * Handles updating the UI based on requests to the HTML Fullscreen API. |
28 */ | 30 */ |
29 public class FullscreenHtmlApiHandler { | 31 public class FullscreenHtmlApiHandler { |
30 private static final int MSG_ID_HIDE_NOTIFICATION_BUBBLE = 1; | 32 private static final int MSG_ID_HIDE_NOTIFICATION_BUBBLE = 1; |
31 private static final int MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS = 2; | 33 private static final int MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS = 2; |
32 private static final int MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG = 3; | 34 private static final int MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG = 3; |
33 | 35 |
34 private static final int MAX_NOTIFICATION_DIMENSION_DP = 600; | 36 private static final int MAX_NOTIFICATION_DIMENSION_DP = 600; |
35 | 37 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 */ | 99 */ |
98 void onFullscreenExited(ContentViewCore contentViewCore); | 100 void onFullscreenExited(ContentViewCore contentViewCore); |
99 | 101 |
100 /** | 102 /** |
101 * @return Whether the notification bubble should be shown. For fullscre
en video in | 103 * @return Whether the notification bubble should be shown. For fullscre
en video in |
102 * overlay mode, the notification bubble should be disabled. | 104 * overlay mode, the notification bubble should be disabled. |
103 */ | 105 */ |
104 boolean shouldShowNotificationBubble(); | 106 boolean shouldShowNotificationBubble(); |
105 } | 107 } |
106 | 108 |
| 109 // This static inner class holds a WeakReference to the outer object, to avo
id triggering the |
| 110 // lint HandlerLeak warning. |
| 111 private static class FullscreenHandler extends Handler { |
| 112 private final WeakReference<FullscreenHtmlApiHandler> mFullscreenHtmlApi
Handler; |
| 113 |
| 114 public FullscreenHandler(FullscreenHtmlApiHandler fullscreenHtmlApiHandl
er) { |
| 115 mFullscreenHtmlApiHandler = new WeakReference<FullscreenHtmlApiHandl
er>( |
| 116 fullscreenHtmlApiHandler); |
| 117 } |
| 118 |
| 119 @Override |
| 120 public void handleMessage(Message msg) { |
| 121 if (msg == null) return; |
| 122 FullscreenHtmlApiHandler fullscreenHtmlApiHandler = mFullscreenHtmlA
piHandler.get(); |
| 123 if (fullscreenHtmlApiHandler == null) return; |
| 124 switch (msg.what) { |
| 125 case MSG_ID_HIDE_NOTIFICATION_BUBBLE: |
| 126 fullscreenHtmlApiHandler.hideNotificationBubble(); |
| 127 break; |
| 128 case MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS: { |
| 129 assert fullscreenHtmlApiHandler.getPersistentFullscreenMode(
) : |
| 130 "Calling after we exited fullscreen"; |
| 131 final ContentViewCore contentViewCore = |
| 132 fullscreenHtmlApiHandler.mContentViewCoreInFullscree
n; |
| 133 if (contentViewCore == null) return; |
| 134 final View contentView = contentViewCore.getContainerView(); |
| 135 int systemUiVisibility = contentView.getSystemUiVisibility()
; |
| 136 if ((systemUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) |
| 137 == SYSTEM_UI_FLAG_FULLSCREEN) { |
| 138 return; |
| 139 } |
| 140 systemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN; |
| 141 systemUiVisibility |= SYSTEM_UI_FLAG_LOW_PROFILE; |
| 142 contentView.setSystemUiVisibility(systemUiVisibility); |
| 143 |
| 144 // Trigger a update to clear the SYSTEM_UI_FLAG_LAYOUT_FULLS
CREEN flag |
| 145 // once the view has been laid out after this system UI upda
te. Without |
| 146 // clearing this flag, the keyboard appearing will not trigg
er a relayout |
| 147 // of the contents, which prevents updating the overdraw amo
unt to the |
| 148 // renderer. |
| 149 contentView.addOnLayoutChangeListener(new OnLayoutChangeList
ener() { |
| 150 @Override |
| 151 public void onLayoutChange(View v, int left, int top, in
t right, |
| 152 int bottom, int oldLeft, int oldTop, int oldRigh
t, |
| 153 int oldBottom) { |
| 154 sendEmptyMessageDelayed(MSG_ID_CLEAR_LAYOUT_FULLSCRE
EN_FLAG, |
| 155 CLEAR_LAYOUT_FULLSCREEN_DELAY_MS); |
| 156 contentView.removeOnLayoutChangeListener(this); |
| 157 } |
| 158 }); |
| 159 break; |
| 160 } |
| 161 case MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG: { |
| 162 // Change this assert to simply ignoring the message to work
around |
| 163 // http://crbug/365638 |
| 164 // TODO(aberent): Fix bug |
| 165 // assert mIsPersistentMode : "Calling after we exited fulls
creen"; |
| 166 if (!fullscreenHtmlApiHandler.getPersistentFullscreenMode())
return; |
| 167 final ContentViewCore contentViewCore = |
| 168 fullscreenHtmlApiHandler.mContentViewCoreInFullscree
n; |
| 169 if (contentViewCore == null) return; |
| 170 final View view = contentViewCore.getContainerView(); |
| 171 int systemUiVisibility = view.getSystemUiVisibility(); |
| 172 if ((systemUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
== 0) { |
| 173 return; |
| 174 } |
| 175 systemUiVisibility &= ~SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; |
| 176 view.setSystemUiVisibility(systemUiVisibility); |
| 177 break; |
| 178 } |
| 179 default: |
| 180 assert false : "Unexpected message for ID: " + msg.what; |
| 181 break; |
| 182 } |
| 183 } |
| 184 } |
| 185 |
107 /** | 186 /** |
108 * Constructs the handler that will manage the UI transitions from the HTML
fullscreen API. | 187 * Constructs the handler that will manage the UI transitions from the HTML
fullscreen API. |
109 * | 188 * |
110 * @param window The window containing the view going to fullscreen. | 189 * @param window The window containing the view going to fullscreen. |
111 * @param delegate The delegate that allows embedders to handle fullscreen t
ransitions. | 190 * @param delegate The delegate that allows embedders to handle fullscreen t
ransitions. |
112 * @param persistentFullscreenSupported | 191 * @param persistentFullscreenSupported |
113 */ | 192 */ |
114 public FullscreenHtmlApiHandler(Window window, FullscreenHtmlApiDelegate del
egate, | 193 public FullscreenHtmlApiHandler(Window window, FullscreenHtmlApiDelegate del
egate, |
115 boolean persistentFullscreenSupported) { | 194 boolean persistentFullscreenSupported) { |
116 mWindow = window; | 195 mWindow = window; |
117 mDelegate = delegate; | 196 mDelegate = delegate; |
118 mPersistentFullscreenSupported = persistentFullscreenSupported; | 197 mPersistentFullscreenSupported = persistentFullscreenSupported; |
119 | 198 mHandler = new FullscreenHandler(this); |
120 mHandler = new Handler() { | |
121 @Override | |
122 public void handleMessage(Message msg) { | |
123 if (msg == null) return; | |
124 switch (msg.what) { | |
125 case MSG_ID_HIDE_NOTIFICATION_BUBBLE: | |
126 hideNotificationBubble(); | |
127 break; | |
128 case MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS: { | |
129 assert mIsPersistentMode : "Calling after we exited full
screen"; | |
130 final ContentViewCore contentViewCore = mContentViewCore
InFullscreen; | |
131 if (contentViewCore == null) return; | |
132 final View contentView = contentViewCore.getContainerVie
w(); | |
133 int systemUiVisibility = contentView.getSystemUiVisibili
ty(); | |
134 if ((systemUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) | |
135 == SYSTEM_UI_FLAG_FULLSCREEN) { | |
136 return; | |
137 } | |
138 systemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN; | |
139 systemUiVisibility |= SYSTEM_UI_FLAG_LOW_PROFILE; | |
140 contentView.setSystemUiVisibility(systemUiVisibility); | |
141 | |
142 // Trigger a update to clear the SYSTEM_UI_FLAG_LAYOUT_F
ULLSCREEN flag | |
143 // once the view has been laid out after this system UI
update. Without | |
144 // clearing this flag, the keyboard appearing will not t
rigger a relayout | |
145 // of the contents, which prevents updating the overdraw
amount to the | |
146 // renderer. | |
147 contentView.addOnLayoutChangeListener(new OnLayoutChange
Listener() { | |
148 @Override | |
149 public void onLayoutChange(View v, int left, int top
, int right, | |
150 int bottom, int oldLeft, int oldTop, int old
Right, | |
151 int oldBottom) { | |
152 sendEmptyMessageDelayed(MSG_ID_CLEAR_LAYOUT_FULL
SCREEN_FLAG, | |
153 CLEAR_LAYOUT_FULLSCREEN_DELAY_MS); | |
154 contentView.removeOnLayoutChangeListener(this); | |
155 } | |
156 }); | |
157 break; | |
158 } | |
159 case MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG: { | |
160 // Change this assert to simply ignoring the message to
work around | |
161 // http://crbug/365638 | |
162 // TODO(aberent): Fix bug | |
163 // assert mIsPersistentMode : "Calling after we exited f
ullscreen"; | |
164 if (!mIsPersistentMode) return; | |
165 if (mContentViewCoreInFullscreen == null) return; | |
166 final View view = mContentViewCoreInFullscreen.getContai
nerView(); | |
167 int systemUiVisibility = view.getSystemUiVisibility(); | |
168 if ((systemUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCRE
EN) == 0) { | |
169 return; | |
170 } | |
171 systemUiVisibility &= ~SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; | |
172 view.setSystemUiVisibility(systemUiVisibility); | |
173 break; | |
174 } | |
175 default: | |
176 assert false : "Unexpected message for ID: " + msg.what; | |
177 break; | |
178 } | |
179 } | |
180 }; | |
181 | |
182 Resources resources = mWindow.getContext().getResources(); | 199 Resources resources = mWindow.getContext().getResources(); |
183 float density = resources.getDisplayMetrics().density; | 200 float density = resources.getDisplayMetrics().density; |
184 mNotificationMaxDimension = (int) (density * MAX_NOTIFICATION_DIMENSION_
DP); | 201 mNotificationMaxDimension = (int) (density * MAX_NOTIFICATION_DIMENSION_
DP); |
185 } | 202 } |
186 | 203 |
187 /** | 204 /** |
188 * Enters or exits persistent fullscreen mode. In this mode, the top contro
ls will be | 205 * Enters or exits persistent fullscreen mode. In this mode, the top contro
ls will be |
189 * permanently hidden until this mode is exited. | 206 * permanently hidden until this mode is exited. |
190 * | 207 * |
191 * @param enabled Whether to enable persistent fullscreen mode. | 208 * @param enabled Whether to enable persistent fullscreen mode. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 if (!hasWindowFocus) hideNotificationBubble(); | 394 if (!hasWindowFocus) hideNotificationBubble(); |
378 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return; | 395 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return; |
379 | 396 |
380 mHandler.removeMessages(MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS); | 397 mHandler.removeMessages(MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS); |
381 mHandler.removeMessages(MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG); | 398 mHandler.removeMessages(MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG); |
382 if (mContentViewCoreInFullscreen == null || !mIsPersistentMode || !hasWi
ndowFocus) return; | 399 if (mContentViewCoreInFullscreen == null || !mIsPersistentMode || !hasWi
ndowFocus) return; |
383 mHandler.sendEmptyMessageDelayed( | 400 mHandler.sendEmptyMessageDelayed( |
384 MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS, ANDROID_CONTROLS_SHOW_DUR
ATION_MS); | 401 MSG_ID_SET_FULLSCREEN_SYSTEM_UI_FLAGS, ANDROID_CONTROLS_SHOW_DUR
ATION_MS); |
385 } | 402 } |
386 } | 403 } |
OLD | NEW |