| 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 |