OLD | NEW |
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 package org.chromium.chrome.browser.vr_shell; | 5 package org.chromium.chrome.browser.vr_shell; |
6 | 6 |
7 import android.app.Activity; | 7 import android.app.Activity; |
8 import android.content.Intent; | 8 import android.content.Intent; |
9 import android.content.pm.ActivityInfo; | 9 import android.content.pm.ActivityInfo; |
10 import android.os.StrictMode; | 10 import android.os.StrictMode; |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 /** | 26 /** |
27 * Manages interactions with the VR Shell. | 27 * Manages interactions with the VR Shell. |
28 */ | 28 */ |
29 @JNINamespace("vr_shell") | 29 @JNINamespace("vr_shell") |
30 public class VrShellDelegate { | 30 public class VrShellDelegate { |
31 private static final String TAG = "VrShellDelegate"; | 31 private static final String TAG = "VrShellDelegate"; |
32 | 32 |
33 private ChromeTabbedActivity mActivity; | 33 private ChromeTabbedActivity mActivity; |
34 | 34 |
35 private boolean mVrShellEnabled; | 35 private boolean mVrEnabled; |
36 | 36 |
37 private Class<? extends VrShellInterface> mVrShellClass; | 37 private Class<? extends VrShellInterface> mVrShellClass; |
| 38 private Class<? extends NonPresentingGvrContextInterface> mNonPresentingGvrC
ontextClass; |
38 private VrShellInterface mVrShell; | 39 private VrShellInterface mVrShell; |
| 40 private NonPresentingGvrContextInterface mNonPresentingGvrContext; |
39 private boolean mInVr; | 41 private boolean mInVr; |
40 private int mRestoreSystemUiVisibilityFlag = -1; | 42 private int mRestoreSystemUiVisibilityFlag = -1; |
41 private String mVrExtra; | 43 private String mVrExtra; |
42 private long mNativeVrShellDelegate; | 44 private long mNativeVrShellDelegate; |
43 | 45 |
44 public VrShellDelegate(ChromeTabbedActivity activity) { | 46 public VrShellDelegate(ChromeTabbedActivity activity) { |
45 mActivity = activity; | 47 mActivity = activity; |
46 | 48 |
47 mVrShellClass = maybeFindVrShell(); | 49 mVrEnabled = maybeFindVrClasses(); |
48 if (mVrShellClass != null) { | 50 if (mVrEnabled) { |
49 mVrShellEnabled = true; | |
50 try { | 51 try { |
51 mVrExtra = (String) mVrShellClass.getField("VR_EXTRA").get(null)
; | 52 mVrExtra = (String) mVrShellClass.getField("VR_EXTRA").get(null)
; |
52 } catch (IllegalAccessException | IllegalArgumentException | NoSuchF
ieldException e) { | 53 } catch (IllegalAccessException | IllegalArgumentException | NoSuchF
ieldException e) { |
53 Log.e(TAG, "Unable to read VR_EXTRA field", e); | 54 Log.e(TAG, "Unable to read VR_EXTRA field", e); |
54 mVrShellEnabled = false; | 55 mVrEnabled = false; |
55 } | 56 } |
56 } | 57 } |
57 } | 58 } |
58 | 59 |
59 /** | 60 /** |
60 * Should be called once the native library is loaded so that the native por
tion of this | 61 * Should be called once the native library is loaded so that the native por
tion of this |
61 * class can be initialized. | 62 * class can be initialized. |
62 */ | 63 */ |
63 public void onNativeLibraryReady() { | 64 public void onNativeLibraryReady() { |
64 if (mVrShellEnabled) { | 65 if (mVrEnabled) { |
65 mNativeVrShellDelegate = nativeInit(); | 66 mNativeVrShellDelegate = nativeInit(); |
66 } | 67 } |
67 } | 68 } |
68 | 69 |
69 @SuppressWarnings("unchecked") | 70 @SuppressWarnings("unchecked") |
70 private Class<? extends VrShellInterface> maybeFindVrShell() { | 71 private boolean maybeFindVrClasses() { |
71 try { | 72 try { |
72 return (Class<? extends VrShellInterface>) Class | 73 mVrShellClass = (Class<? extends VrShellInterface>) Class.forName( |
73 .forName("org.chromium.chrome.browser.vr_shell.VrShell"); | 74 "org.chromium.chrome.browser.vr_shell.VrShell"); |
| 75 mNonPresentingGvrContextClass = |
| 76 (Class<? extends NonPresentingGvrContextInterface>) Class.fo
rName( |
| 77 "org.chromium.chrome.browser.vr_shell.NonPresentingG
vrContext"); |
| 78 return true; |
74 } catch (ClassNotFoundException e) { | 79 } catch (ClassNotFoundException e) { |
75 return null; | 80 mVrShellClass = null; |
| 81 mNonPresentingGvrContextClass = null; |
| 82 return false; |
76 } | 83 } |
77 } | 84 } |
78 | 85 |
79 /** | 86 /** |
80 * Enters VR Shell, displaying browser UI and tab contents in VR. | 87 * Enters VR Shell, displaying browser UI and tab contents in VR. |
81 * | 88 * |
82 * This function performs native initialization, and so must only be called
after native | 89 * This function performs native initialization, and so must only be called
after native |
83 * libraries are ready. | 90 * libraries are ready. |
84 * @param inWebVR If true should begin displaying WebVR content rather than
the VrShell UI. | 91 * @param inWebVR If true should begin displaying WebVR content rather than
the VrShell UI. |
85 * @return Whether or not we are in VR when this function returns. | 92 * @return Whether or not we are in VR when this function returns. |
86 */ | 93 */ |
87 @CalledByNative | 94 @CalledByNative |
88 public boolean enterVRIfNecessary(boolean inWebVR) { | 95 public boolean enterVRIfNecessary(boolean inWebVR) { |
89 if (!mVrShellEnabled || mNativeVrShellDelegate == 0) return false; | 96 if (!mVrEnabled || mNativeVrShellDelegate == 0) return false; |
90 Tab tab = mActivity.getActivityTab(); | 97 Tab tab = mActivity.getActivityTab(); |
91 // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow
VR Shell to be | 98 // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow
VR Shell to be |
92 // entered without any current tabs. | 99 // entered without any current tabs. |
93 if (tab == null || tab.getContentViewCore() == null) { | 100 if (tab == null || tab.getContentViewCore() == null) { |
94 return false; | 101 return false; |
95 } | 102 } |
96 if (mInVr) return true; | 103 if (mInVr) return true; |
97 // VrShell must be initialized in Landscape mode due to a bug in the GVR
library. | 104 // VrShell must be initialized in Landscape mode due to a bug in the GVR
library. |
98 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSC
APE); | 105 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSC
APE); |
99 if (!createVrShell()) { | 106 if (!createVrShell()) { |
(...skipping 17 matching lines...) Expand all Loading... |
117 // TODO(bajones): Once VR Shell can be invoked outside of WebVR this | 124 // TODO(bajones): Once VR Shell can be invoked outside of WebVR this |
118 // should no longer exit the shell outright. Need a way to determine | 125 // should no longer exit the shell outright. Need a way to determine |
119 // how VrShell was created. | 126 // how VrShell was created. |
120 shutdownVR(); | 127 shutdownVR(); |
121 return true; | 128 return true; |
122 } | 129 } |
123 | 130 |
124 /** | 131 /** |
125 * Resumes VR Shell. | 132 * Resumes VR Shell. |
126 */ | 133 */ |
127 public void resumeVR() { | 134 public void maybeResumeVR() { |
128 setupVrModeWindowFlags(); | 135 // TODO(bshe): Ideally, we do not need two gvr context exist at the same
time. We can |
129 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); | 136 // probably shutdown non presenting gvr when presenting and create a new
one after exit |
130 try { | 137 // presenting. See crbug.com/655242 |
131 mVrShell.resume(); | 138 if (mNonPresentingGvrContext != null) { |
132 } catch (IllegalArgumentException e) { | 139 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites
(); |
133 Log.e(TAG, "Unable to resume VrShell", e); | 140 try { |
134 } finally { | 141 mNonPresentingGvrContext.resume(); |
135 StrictMode.setThreadPolicy(oldPolicy); | 142 } catch (IllegalArgumentException e) { |
| 143 Log.e(TAG, "Unable to resume mNonPresentingGvrContext", e); |
| 144 } finally { |
| 145 StrictMode.setThreadPolicy(oldPolicy); |
| 146 } |
| 147 } |
| 148 |
| 149 if (mInVr) { |
| 150 setupVrModeWindowFlags(); |
| 151 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites
(); |
| 152 try { |
| 153 mVrShell.resume(); |
| 154 } catch (IllegalArgumentException e) { |
| 155 Log.e(TAG, "Unable to resume VrShell", e); |
| 156 } finally { |
| 157 StrictMode.setThreadPolicy(oldPolicy); |
| 158 } |
136 } | 159 } |
137 } | 160 } |
138 | 161 |
139 /** | 162 /** |
140 * Pauses VR Shell. | 163 * Pauses VR Shell. |
141 */ | 164 */ |
142 public void pauseVR() { | 165 public void maybePauseVR() { |
143 mVrShell.pause(); | 166 if (mNonPresentingGvrContext != null) { |
| 167 mNonPresentingGvrContext.pause(); |
| 168 } |
| 169 if (mInVr) { |
| 170 mVrShell.pause(); |
| 171 } |
144 } | 172 } |
145 | 173 |
146 /** | 174 /** |
147 * Exits the current VR mode (WebVR or VRShell) | 175 * Exits the current VR mode (WebVR or VRShell) |
148 * @return Whether or not we exited VR. | 176 * @return Whether or not we exited VR. |
149 */ | 177 */ |
150 public boolean exitVRIfNecessary() { | 178 public boolean exitVRIfNecessary() { |
151 if (!mInVr) return false; | 179 if (!mInVr) return false; |
152 // If WebVR is presenting instruct it to exit. VR mode should not | 180 // If WebVR is presenting instruct it to exit. VR mode should not |
153 // exit in this scenario, in case we want to return to the VrShell. | 181 // exit in this scenario, in case we want to return to the VrShell. |
154 if (!nativeExitWebVRIfNecessary(mNativeVrShellDelegate)) { | 182 if (!nativeExitWebVRIfNecessary(mNativeVrShellDelegate)) { |
155 // If WebVR was not presenting, shutdown VR mode entirely. | 183 // If WebVR was not presenting, shutdown VR mode entirely. |
156 shutdownVR(); | 184 shutdownVR(); |
157 } | 185 } |
158 | 186 |
159 return true; | 187 return true; |
160 } | 188 } |
161 | 189 |
| 190 @CalledByNative |
| 191 private long createNonPresentingNativeContext() { |
| 192 if (!mVrEnabled) return 0; |
| 193 |
| 194 try { |
| 195 Constructor<?> nonPresentingGvrContextConstructor = |
| 196 mNonPresentingGvrContextClass.getConstructor(Activity.class)
; |
| 197 mNonPresentingGvrContext = |
| 198 (NonPresentingGvrContextInterface) |
| 199 nonPresentingGvrContextConstructor.newInstance(mActi
vity); |
| 200 } catch (InstantiationException | IllegalAccessException | IllegalArgume
ntException |
| 201 | InvocationTargetException | NoSuchMethodException e) { |
| 202 Log.e(TAG, "Unable to instantiate NonPresentingGvrContext", e); |
| 203 return 0; |
| 204 } |
| 205 return mNonPresentingGvrContext.getNativeGvrContext(); |
| 206 } |
| 207 |
| 208 @CalledByNative |
| 209 private void shutdownNonPresentingNativeContext() { |
| 210 mNonPresentingGvrContext.shutdown(); |
| 211 mNonPresentingGvrContext = null; |
| 212 } |
| 213 |
162 /** | 214 /** |
163 * Exits VR Shell, performing all necessary cleanup. | 215 * Exits VR Shell, performing all necessary cleanup. |
164 */ | 216 */ |
165 private void shutdownVR() { | 217 private void shutdownVR() { |
166 if (!mInVr) return; | 218 if (!mInVr) return; |
167 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPEC
IFIED); | 219 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPEC
IFIED); |
168 mVrShell.setVrModeEnabled(false); | 220 mVrShell.setVrModeEnabled(false); |
169 mVrShell.pause(); | 221 mVrShell.pause(); |
170 removeVrViews(); | 222 removeVrViews(); |
171 clearVrModeWindowFlags(); | 223 clearVrModeWindowFlags(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 * Whether or not we are currently in VR. | 301 * Whether or not we are currently in VR. |
250 */ | 302 */ |
251 public boolean isInVR() { | 303 public boolean isInVR() { |
252 return mInVr; | 304 return mInVr; |
253 } | 305 } |
254 | 306 |
255 /** | 307 /** |
256 * @return Whether or not VR Shell is currently enabled. | 308 * @return Whether or not VR Shell is currently enabled. |
257 */ | 309 */ |
258 public boolean isVrShellEnabled() { | 310 public boolean isVrShellEnabled() { |
259 return mVrShellEnabled; | 311 return mVrEnabled; |
260 } | 312 } |
261 | 313 |
262 /** | 314 /** |
263 * @return Pointer to the native VrShellDelegate object. | 315 * @return Pointer to the native VrShellDelegate object. |
264 */ | 316 */ |
265 @CalledByNative | 317 @CalledByNative |
266 private long getNativePointer() { | 318 private long getNativePointer() { |
267 return mNativeVrShellDelegate; | 319 return mNativeVrShellDelegate; |
268 } | 320 } |
269 | 321 |
270 private native long nativeInit(); | 322 private native long nativeInit(); |
271 private native boolean nativeExitWebVRIfNecessary(long nativeVrShellDelegate
); | 323 private native boolean nativeExitWebVRIfNecessary(long nativeVrShellDelegate
); |
272 } | 324 } |
OLD | NEW |