Chromium Code Reviews| 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 resumeVR() { |
|
mthiesse
2016/10/11 18:10:44
nit: Rename to maybeResumeVR() and maybePauseVR()
bshe
2016/10/12 19:02:17
Done.
| |
| 128 setupVrModeWindowFlags(); | 135 if (mNonPresentingGvrContext != null) { |
|
mthiesse
2016/10/11 18:10:44
Is there a reason to have both a non-presenting GV
bshe
2016/10/12 19:02:17
I can't think of any reason. And we might want to
| |
| 129 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); | 136 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites (); |
| 130 try { | 137 try { |
| 131 mVrShell.resume(); | 138 mNonPresentingGvrContext.resume(); |
| 132 } catch (IllegalArgumentException e) { | 139 } catch (IllegalArgumentException e) { |
| 133 Log.e(TAG, "Unable to resume VrShell", e); | 140 Log.e(TAG, "Unable to resume mNonPresentingGvrContext", e); |
| 134 } finally { | 141 } finally { |
| 135 StrictMode.setThreadPolicy(oldPolicy); | 142 StrictMode.setThreadPolicy(oldPolicy); |
| 143 } | |
| 144 } | |
| 145 | |
| 146 if (mInVr) { | |
| 147 setupVrModeWindowFlags(); | |
| 148 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites (); | |
| 149 try { | |
| 150 mVrShell.resume(); | |
| 151 } catch (IllegalArgumentException e) { | |
| 152 Log.e(TAG, "Unable to resume VrShell", e); | |
| 153 } finally { | |
| 154 StrictMode.setThreadPolicy(oldPolicy); | |
| 155 } | |
| 136 } | 156 } |
| 137 } | 157 } |
| 138 | 158 |
| 139 /** | 159 /** |
| 140 * Pauses VR Shell. | 160 * Pauses VR Shell. |
| 141 */ | 161 */ |
| 142 public void pauseVR() { | 162 public void pauseVR() { |
| 143 mVrShell.pause(); | 163 if (mNonPresentingGvrContext != null) { |
| 164 mNonPresentingGvrContext.pause(); | |
| 165 } | |
| 166 if (mInVr) { | |
| 167 mVrShell.pause(); | |
| 168 } | |
| 144 } | 169 } |
| 145 | 170 |
| 146 /** | 171 /** |
| 147 * Exits the current VR mode (WebVR or VRShell) | 172 * Exits the current VR mode (WebVR or VRShell) |
| 148 * @return Whether or not we exited VR. | 173 * @return Whether or not we exited VR. |
| 149 */ | 174 */ |
| 150 public boolean exitVRIfNecessary() { | 175 public boolean exitVRIfNecessary() { |
| 151 if (!mInVr) return false; | 176 if (!mInVr) return false; |
| 152 // If WebVR is presenting instruct it to exit. VR mode should not | 177 // 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. | 178 // exit in this scenario, in case we want to return to the VrShell. |
| 154 if (!nativeExitWebVRIfNecessary(mNativeVrShellDelegate)) { | 179 if (!nativeExitWebVRIfNecessary(mNativeVrShellDelegate)) { |
| 155 // If WebVR was not presenting, shutdown VR mode entirely. | 180 // If WebVR was not presenting, shutdown VR mode entirely. |
| 156 shutdownVR(); | 181 shutdownVR(); |
| 157 } | 182 } |
| 158 | 183 |
| 159 return true; | 184 return true; |
| 160 } | 185 } |
| 161 | 186 |
| 187 @CalledByNative | |
| 188 private long createNonPresentingNativeContext() { | |
| 189 if (!mVrEnabled) return 0; | |
| 190 | |
| 191 try { | |
| 192 Constructor<?> nonPresentingGvrContextConstructor = | |
| 193 mNonPresentingGvrContextClass.getConstructor(Activity.class) ; | |
| 194 mNonPresentingGvrContext = | |
| 195 (NonPresentingGvrContextInterface) | |
| 196 nonPresentingGvrContextConstructor.newInstance(mActi vity); | |
| 197 } catch (InstantiationException | IllegalAccessException | IllegalArgume ntException | |
| 198 | InvocationTargetException | NoSuchMethodException e) { | |
| 199 Log.e(TAG, "Unable to instantiate NonPresentingGvrContext", e); | |
| 200 return 0; | |
| 201 } | |
| 202 return mNonPresentingGvrContext.getNativeGvrContext(); | |
| 203 } | |
| 204 | |
| 205 @CalledByNative | |
| 206 private void shutdownNonPresentingNativeContext() { | |
| 207 mNonPresentingGvrContext.shutdown(); | |
| 208 mNonPresentingGvrContext = null; | |
| 209 } | |
| 210 | |
| 162 /** | 211 /** |
| 163 * Exits VR Shell, performing all necessary cleanup. | 212 * Exits VR Shell, performing all necessary cleanup. |
| 164 */ | 213 */ |
| 165 private void shutdownVR() { | 214 private void shutdownVR() { |
| 166 if (!mInVr) return; | 215 if (!mInVr) return; |
| 167 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPEC IFIED); | 216 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPEC IFIED); |
| 168 mVrShell.setVrModeEnabled(false); | 217 mVrShell.setVrModeEnabled(false); |
| 169 mVrShell.pause(); | 218 mVrShell.pause(); |
| 170 removeVrViews(); | 219 removeVrViews(); |
| 171 clearVrModeWindowFlags(); | 220 clearVrModeWindowFlags(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 * Whether or not we are currently in VR. | 298 * Whether or not we are currently in VR. |
| 250 */ | 299 */ |
| 251 public boolean isInVR() { | 300 public boolean isInVR() { |
| 252 return mInVr; | 301 return mInVr; |
| 253 } | 302 } |
| 254 | 303 |
| 255 /** | 304 /** |
| 256 * @return Whether or not VR Shell is currently enabled. | 305 * @return Whether or not VR Shell is currently enabled. |
| 257 */ | 306 */ |
| 258 public boolean isVrShellEnabled() { | 307 public boolean isVrShellEnabled() { |
| 259 return mVrShellEnabled; | 308 return mVrEnabled; |
| 260 } | 309 } |
| 261 | 310 |
| 262 /** | 311 /** |
| 263 * @return Pointer to the native VrShellDelegate object. | 312 * @return Pointer to the native VrShellDelegate object. |
| 264 */ | 313 */ |
| 265 @CalledByNative | 314 @CalledByNative |
| 266 private long getNativePointer() { | 315 private long getNativePointer() { |
| 267 return mNativeVrShellDelegate; | 316 return mNativeVrShellDelegate; |
| 268 } | 317 } |
| 269 | 318 |
| 270 private native long nativeInit(); | 319 private native long nativeInit(); |
| 271 private native boolean nativeExitWebVRIfNecessary(long nativeVrShellDelegate ); | 320 private native boolean nativeExitWebVRIfNecessary(long nativeVrShellDelegate ); |
| 272 } | 321 } |
| OLD | NEW |