Add more Daydream VR support
This commit is contained in:
parent
5db7edad0b
commit
49660a6b31
|
@ -22,6 +22,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.google.vr:sdk-base:1.160.0'
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||
implementation 'com.android.support:support-v4:27.1.1'
|
||||
|
|
|
@ -11,17 +11,40 @@
|
|||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".PathfinderActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:configChanges="density|navigation|orientation|keyboardHidden|screenSize|uiMode"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/FullscreenTheme">
|
||||
android:theme="@style/VrActivityTheme"
|
||||
android:resizeableActivity="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
<!-- This marks the Activity as a Daydream Activity and allows it
|
||||
to be launched from the Daydream Home. -->
|
||||
<category android:name="com.google.intent.category.DAYDREAM" />
|
||||
|
||||
<!-- This marks the Activity as a Cardboard Activity and allows it
|
||||
to be launched from the Cardboard app. -->
|
||||
<category android:name="com.google.intent.category.CARDBOARD" />
|
||||
|
||||
<!-- This allows this Activity to be launched from the traditional
|
||||
Android 2D launcher as well. Remove it if you do not want
|
||||
this Activity to be launched directly from the 2D launcher. -->
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name=".PathfinderDemoVRListenerService"
|
||||
android:label="@string/service_name"
|
||||
android:permission="android.permission.BIND_VR_LISTENER_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.vr.VrListenerService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-feature android:name="android.software.vr.mode" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.vr.high_performance" android:required="false"/>
|
||||
|
||||
</manifest>
|
|
@ -2,102 +2,42 @@ package graphics.pathfinder.pathfinderdemo;
|
|||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import com.google.vr.cardboard.AndroidNCompat;
|
||||
|
||||
/**
|
||||
* An example full-screen activity that shows and hides the system UI (i.e.
|
||||
* status bar and navigation/system bar) with user interaction.
|
||||
*/
|
||||
public class PathfinderActivity extends AppCompatActivity {
|
||||
public class PathfinderActivity extends Activity {
|
||||
private PathfinderDemoRenderer mRenderer;
|
||||
|
||||
/**
|
||||
* Whether or not the system UI should be auto-hidden after
|
||||
* {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
|
||||
*/
|
||||
private static final boolean AUTO_HIDE = true;
|
||||
|
||||
/**
|
||||
* If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
|
||||
* user interaction before hiding the system UI.
|
||||
*/
|
||||
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
|
||||
|
||||
/**
|
||||
* Some older devices needs a small delay between UI widget updates
|
||||
* and a change of the status and navigation bar.
|
||||
*/
|
||||
private static final int UI_ANIMATION_DELAY = 300;
|
||||
private final Handler mHideHandler = new Handler();
|
||||
private PathfinderDemoSurfaceView mContentView;
|
||||
private final Runnable mHidePart2Runnable = new Runnable() {
|
||||
@SuppressLint("InlinedApi")
|
||||
@Override
|
||||
public void run() {
|
||||
// Delayed removal of status and navigation bar
|
||||
|
||||
// Note that some of these constants are new as of API 16 (Jelly Bean)
|
||||
// and API 19 (KitKat). It is safe to use them, as they are inlined
|
||||
// at compile-time and do nothing on earlier devices.
|
||||
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
}
|
||||
};
|
||||
private View mControlsView;
|
||||
private final Runnable mShowPart2Runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Delayed display of UI elements
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.show();
|
||||
}
|
||||
mControlsView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
};
|
||||
private boolean mVisible;
|
||||
private final Runnable mHideRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Touch listener to use for in-layout UI controls to delay hiding the
|
||||
* system UI. This is to prevent the jarring behavior of controls going away
|
||||
* while interacting with activity UI.
|
||||
*/
|
||||
private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if (AUTO_HIDE) {
|
||||
delayedHide(AUTO_HIDE_DELAY_MILLIS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
ComponentName mVRListenerComponentName;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -122,13 +62,26 @@ public class PathfinderActivity extends AppCompatActivity {
|
|||
init();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
void setVRMode(boolean enabled) {
|
||||
try {
|
||||
setVrModeEnabled(false, mVRListenerComponentName);
|
||||
} catch (PackageManager.NameNotFoundException exception) {
|
||||
startActivity(new Intent(Settings.ACTION_VR_LISTENER_SETTINGS));
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void init() {
|
||||
mVRListenerComponentName = new ComponentName("graphics.pathfinder.pathfinderdemo",
|
||||
"graphics.pathfinder.pathfinderdemo.PathfinderDemoVRListenerService");
|
||||
|
||||
setContentView(R.layout.activity_pathfinder);
|
||||
|
||||
mVisible = true;
|
||||
mControlsView = findViewById(R.id.fullscreen_content_controls);
|
||||
mContentView = findViewById(R.id.fullscreen_content);
|
||||
mContentView.setStereoModeEnabled(false);
|
||||
setVRMode(false);
|
||||
|
||||
/*
|
||||
// Set up the user interaction to manually show or hide the system UI.
|
||||
|
@ -141,7 +94,7 @@ public class PathfinderActivity extends AppCompatActivity {
|
|||
*/
|
||||
|
||||
mContentView.setEGLContextClientVersion(3);
|
||||
mRenderer = new PathfinderDemoRenderer(getAssets());
|
||||
mRenderer = new PathfinderDemoRenderer(this);
|
||||
mContentView.setRenderer(mRenderer);
|
||||
|
||||
mContentView.setOnTouchListener(new View.OnTouchListener() {
|
||||
|
@ -203,53 +156,5 @@ public class PathfinderActivity extends AppCompatActivity {
|
|||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
|
||||
// Trigger the initial hide() shortly after the activity has been
|
||||
// created, to briefly hint to the user that UI controls
|
||||
// are available.
|
||||
delayedHide(100);
|
||||
}
|
||||
|
||||
private void toggle() {
|
||||
if (mVisible) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
// Hide UI first
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.hide();
|
||||
}
|
||||
mControlsView.setVisibility(View.GONE);
|
||||
mVisible = false;
|
||||
|
||||
// Schedule a runnable to remove the status and navigation bar after a delay
|
||||
mHideHandler.removeCallbacks(mShowPart2Runnable);
|
||||
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
private void show() {
|
||||
// Show the system bar
|
||||
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
mVisible = true;
|
||||
|
||||
// Schedule a runnable to display UI elements after a delay
|
||||
mHideHandler.removeCallbacks(mHidePart2Runnable);
|
||||
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a call to hide() in delay milliseconds, canceling any
|
||||
* previously scheduled calls.
|
||||
*/
|
||||
private void delayedHide(int delayMillis) {
|
||||
mHideHandler.removeCallbacks(mHideRunnable);
|
||||
mHideHandler.postDelayed(mHideRunnable, delayMillis);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,58 +1,89 @@
|
|||
package graphics.pathfinder.pathfinderdemo;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import com.google.vr.sdk.base.Eye;
|
||||
import com.google.vr.sdk.base.GvrView;
|
||||
import com.google.vr.sdk.base.HeadTransform;
|
||||
import com.google.vr.sdk.base.Viewport;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Renderer {
|
||||
private AssetManager mAssetManager;
|
||||
public class PathfinderDemoRenderer extends Object implements GvrView.Renderer {
|
||||
private PathfinderActivity mActivity;
|
||||
private boolean mInitialized;
|
||||
private boolean mInVRMode;
|
||||
|
||||
private static native void init(PathfinderDemoResourceLoader resourceLoader,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
private static native int prepareFrame();
|
||||
|
||||
private static native void drawScene(int sceneIndex);
|
||||
|
||||
private static native void finishDrawingFrame();
|
||||
|
||||
public static native void pushWindowResizedEvent(int width, int height);
|
||||
|
||||
public static native void pushMouseDownEvent(int x, int y);
|
||||
|
||||
public static native void pushMouseDraggedEvent(int x, int y);
|
||||
|
||||
public static native void pushLookEvent(float pitch, float yaw);
|
||||
|
||||
static {
|
||||
System.loadLibrary("pathfinder_android_demo");
|
||||
}
|
||||
|
||||
protected PathfinderDemoRenderer() {}
|
||||
|
||||
PathfinderDemoRenderer(AssetManager assetManager) {
|
||||
PathfinderDemoRenderer(PathfinderActivity activity) {
|
||||
super();
|
||||
mAssetManager = assetManager;
|
||||
mActivity = activity;
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
public void onDrawFrame(HeadTransform headTransform, Eye leftEye, Eye rightEye) {
|
||||
boolean inVR = prepareFrame() > 1;
|
||||
if (inVR != mInVRMode) {
|
||||
mInVRMode = inVR;
|
||||
try {
|
||||
mActivity.setVrModeEnabled(mInVRMode, mActivity.mVRListenerComponentName);
|
||||
} catch (PackageManager.NameNotFoundException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
for (int sceneIndex = 0; sceneIndex < (inVR ? 2 : 1); sceneIndex++)
|
||||
drawScene(sceneIndex);
|
||||
finishDrawingFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
public void onFinishFrame(Viewport viewport) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged(int width, int height) {
|
||||
if (!mInitialized) {
|
||||
init(new PathfinderDemoResourceLoader(mAssetManager), width, height);
|
||||
init(new PathfinderDemoResourceLoader(mActivity.getAssets()), width, height);
|
||||
mInitialized = true;
|
||||
} else {
|
||||
pushWindowResizedEvent(width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
int sceneCount = prepareFrame();
|
||||
for (int sceneIndex = 0; sceneIndex < sceneCount; sceneIndex++)
|
||||
drawScene(sceneIndex);
|
||||
finishDrawingFrame();
|
||||
public void onSurfaceCreated(EGLConfig config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRendererShutdown() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@ import android.opengl.GLSurfaceView;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import com.google.vr.sdk.base.GvrView;
|
||||
|
||||
public class PathfinderDemoSurfaceView extends GLSurfaceView {
|
||||
public class PathfinderDemoSurfaceView extends GvrView {
|
||||
public PathfinderDemoSurfaceView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
|
||||
<string name="dummy_button">Dummy Button</string>
|
||||
<string name="dummy_content">DUMMY\nCONTENT</string>
|
||||
<string name="service_name">PathfinderVRListenerService</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue