From 902518965037dbb8da91a9b2da7912423f9402cd Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 18 Mar 2019 18:13:13 -0700 Subject: [PATCH] Allow opening new SVGs in the Android port --- demo/android/app/build.gradle | 3 +- .../ExampleInstrumentedTest.java | 26 ------- demo/android/app/src/main/AndroidManifest.xml | 45 +++++++---- demo/android/app/src/main/assets/resources | 1 + ...ivity.java => PathfinderDemoActivity.java} | 40 ++++------ .../PathfinderDemoFileBrowserActivity.java | 48 ++++++++++++ .../PathfinderDemoRenderer.java | 20 +++-- .../PathfinderDemoResourceLoader.java | 40 ++++++++++ .../PathfinderDemoSurfaceView.java | 3 - .../PathfinderDemoVRListenerService.java | 10 +++ .../arm64-v8a/libpathfinder_android_demo.so | 1 + .../main/res/layout/activity_pathfinder.xml | 2 +- .../activity_pathfinder_demo_file_browser.xml | 18 +++++ ...pathfinder_demo_file_browser_list_item.xml | 9 +++ .../app/src/main/res/values/strings.xml | 2 + .../pathfinderdemo/ExampleUnitTest.java | 17 ----- demo/android/rust/src/lib.rs | 46 ++++++++++-- demo/common/src/lib.rs | 75 ++++++++++--------- demo/common/src/ui.rs | 7 +- demo/common/src/window.rs | 11 ++- demo/native/src/main.rs | 66 ++++++++++------ 21 files changed, 322 insertions(+), 168 deletions(-) delete mode 100644 demo/android/app/src/androidTest/java/graphics/pathfinder/pathfinderdemo/ExampleInstrumentedTest.java create mode 120000 demo/android/app/src/main/assets/resources rename demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/{PathfinderActivity.java => PathfinderDemoActivity.java} (80%) create mode 100644 demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoFileBrowserActivity.java create mode 100644 demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoResourceLoader.java create mode 100644 demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoVRListenerService.java create mode 120000 demo/android/app/src/main/jniLibs/arm64-v8a/libpathfinder_android_demo.so create mode 100644 demo/android/app/src/main/res/layout/activity_pathfinder_demo_file_browser.xml create mode 100644 demo/android/app/src/main/res/layout/layout_pathfinder_demo_file_browser_list_item.xml delete mode 100644 demo/android/app/src/test/java/graphics/pathfinder/pathfinderdemo/ExampleUnitTest.java diff --git a/demo/android/app/build.gradle b/demo/android/app/build.gradle index d51461c0..374256ce 100644 --- a/demo/android/app/build.gradle +++ b/demo/android/app/build.gradle @@ -4,7 +4,7 @@ android { compileSdkVersion 27 defaultConfig { applicationId "graphics.pathfinder.pathfinderdemo" - minSdkVersion 21 + minSdkVersion 24 targetSdkVersion 27 versionCode 1 versionName "1.0" @@ -22,6 +22,7 @@ android { } dependencies { + implementation 'com.android.support.constraint:constraint-layout:1.1.3' compile 'com.google.vr:sdk-base:1.160.0' implementation fileTree(dir: 'libs', include: ['*.jar']) diff --git a/demo/android/app/src/androidTest/java/graphics/pathfinder/pathfinderdemo/ExampleInstrumentedTest.java b/demo/android/app/src/androidTest/java/graphics/pathfinder/pathfinderdemo/ExampleInstrumentedTest.java deleted file mode 100644 index fb759831..00000000 --- a/demo/android/app/src/androidTest/java/graphics/pathfinder/pathfinderdemo/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package graphics.pathfinder.pathfinderdemo; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("graphics.pathfinder.pathfinderdemo", appContext.getPackageName()); - } -} diff --git a/demo/android/app/src/main/AndroidManifest.xml b/demo/android/app/src/main/AndroidManifest.xml index 186cf754..bdf5acdd 100644 --- a/demo/android/app/src/main/AndroidManifest.xml +++ b/demo/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,15 @@ + + + + + + android:resizeableActivity="false" + android:theme="@style/AppTheme"> - + - + - + this Activity to be launched directly from the 2D launcher. + --> - - + + - - - \ No newline at end of file diff --git a/demo/android/app/src/main/assets/resources b/demo/android/app/src/main/assets/resources new file mode 120000 index 00000000..af0ea9dc --- /dev/null +++ b/demo/android/app/src/main/assets/resources @@ -0,0 +1 @@ +../../../../../../resources \ No newline at end of file diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoActivity.java similarity index 80% rename from demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java rename to demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoActivity.java index 51faeedd..bb2406f4 100644 --- a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoActivity.java @@ -18,17 +18,14 @@ import android.support.annotation.RequiresApi; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.os.Bundle; -import android.util.Log; import android.view.MotionEvent; import android.view.View; -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 Activity { +public class PathfinderDemoActivity extends Activity { private PathfinderDemoRenderer mRenderer; /** @@ -83,32 +80,20 @@ public class PathfinderActivity extends Activity { mContentView.setStereoModeEnabled(false); setVRMode(false); - /* - // Set up the user interaction to manually show or hide the system UI. - mContentView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - toggle(); - } - }); - */ - mContentView.setEGLContextClientVersion(3); mRenderer = new PathfinderDemoRenderer(this); mContentView.setRenderer(mRenderer); mContentView.setOnTouchListener(new View.OnTouchListener() { @Override - public boolean onTouch(View view, MotionEvent event) { - int x = Math.round(event.getX()); - int y = Math.round(event.getY()); + public boolean onTouch(final View view, final MotionEvent event) { + final int x = Math.round(event.getX()); + final int y = Math.round(event.getY()); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - Log.i("Pathfinder", "DOWN " + x + " " + y); PathfinderDemoRenderer.pushMouseDownEvent(x, y); break; case MotionEvent.ACTION_MOVE: - Log.i("Pathfinder", "MOVE " + x + " " + y); PathfinderDemoRenderer.pushMouseDraggedEvent(x, y); break; } @@ -127,13 +112,13 @@ public class PathfinderActivity extends Activity { @Override public void onSensorChanged(SensorEvent event) { // https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Quaternion_to_Euler_Angles_Conversion - float[] q = event.values; - float pitch = (float)Math.asin(2.0 * (q[0] * q[2] - q[3] * q[1])); - float yaw = (float)Math.atan2(2.0 * (q[0] * q[3] + q[1] * q[2]), - 1.0 - 2.0 * (q[2] * q[2] + q[3] * q[3])); + final float[] q = event.values; + final float pitch = (float)Math.asin(2.0 * (q[0] * q[2] - q[3] * q[1])); + final float yaw = (float)Math.atan2(2.0 * (q[0] * q[3] + q[1] * q[2]), + 1.0 - 2.0 * (q[2] * q[2] + q[3] * q[3])); - float deltaPitch = pitch - mPitch; - float deltaYaw = yaw - mYaw; + final float deltaPitch = pitch - mPitch; + final float deltaYaw = yaw - mYaw; mPitch = pitch; mYaw = yaw; @@ -157,4 +142,9 @@ public class PathfinderActivity extends Activity { protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); } + + public void presentOpenSVGDialog() { + final Intent intent = new Intent(this, PathfinderDemoFileBrowserActivity.class); + startActivity(intent); + } } diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoFileBrowserActivity.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoFileBrowserActivity.java new file mode 100644 index 00000000..415d648f --- /dev/null +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoFileBrowserActivity.java @@ -0,0 +1,48 @@ +package graphics.pathfinder.pathfinderdemo; + +import android.content.res.AssetManager; +import android.os.Bundle; +import android.app.Activity; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; + +import java.io.IOException; + +public class PathfinderDemoFileBrowserActivity extends Activity { + private ListView mBrowserView; + + private static String SVG_RESOURCE_PATH = "svg/"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_pathfinder_demo_file_browser); + + mBrowserView = findViewById(R.id.fileBrowserBrowser); + + try { + final AssetManager assetManager = getAssets(); + final String[] svgFilenames = assetManager.list("resources/" + SVG_RESOURCE_PATH); + final ArrayAdapter adapter = new ArrayAdapter( + this, + R.layout.layout_pathfinder_demo_file_browser_list_item, + svgFilenames); + mBrowserView.setAdapter(adapter); + } catch (IOException exception) { + throw new RuntimeException(exception); + } + + mBrowserView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + TextView textView = (TextView)view; + PathfinderDemoRenderer.pushOpenSVGEvent(SVG_RESOURCE_PATH + textView.getText()); + finish(); + } + }); + } + +} diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java index 0ad76116..2662f04b 100644 --- a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java @@ -1,8 +1,7 @@ package graphics.pathfinder.pathfinderdemo; +import android.content.Intent; 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; @@ -11,11 +10,12 @@ import com.google.vr.sdk.base.Viewport; import javax.microedition.khronos.egl.EGLConfig; public class PathfinderDemoRenderer extends Object implements GvrView.Renderer { - private PathfinderActivity mActivity; + private final PathfinderDemoActivity mActivity; private boolean mInitialized; private boolean mInVRMode; - private static native void init(PathfinderDemoResourceLoader resourceLoader, + private static native void init(PathfinderDemoActivity activity, + PathfinderDemoResourceLoader resourceLoader, int width, int height); @@ -33,20 +33,21 @@ public class PathfinderDemoRenderer extends Object implements GvrView.Renderer { public static native void pushLookEvent(float pitch, float yaw); + public static native void pushOpenSVGEvent(String path); + static { System.loadLibrary("pathfinder_android_demo"); } - PathfinderDemoRenderer(PathfinderActivity activity) { + PathfinderDemoRenderer(PathfinderDemoActivity activity) { super(); mActivity = activity; mInitialized = false; } - @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onDrawFrame(HeadTransform headTransform, Eye leftEye, Eye rightEye) { - boolean inVR = prepareFrame() > 1; + final boolean inVR = prepareFrame() > 1; if (inVR != mInVRMode) { mInVRMode = inVR; try { @@ -69,7 +70,10 @@ public class PathfinderDemoRenderer extends Object implements GvrView.Renderer { @Override public void onSurfaceChanged(int width, int height) { if (!mInitialized) { - init(new PathfinderDemoResourceLoader(mActivity.getAssets()), width, height); + init(mActivity, + new PathfinderDemoResourceLoader(mActivity.getAssets()), + width, + height); mInitialized = true; } else { pushWindowResizedEvent(width, height); diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoResourceLoader.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoResourceLoader.java new file mode 100644 index 00000000..49e25be5 --- /dev/null +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoResourceLoader.java @@ -0,0 +1,40 @@ +package graphics.pathfinder.pathfinderdemo; + +import android.content.res.AssetManager; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +public class PathfinderDemoResourceLoader { + private AssetManager m_assetManager; + + PathfinderDemoResourceLoader(AssetManager assetManager) { + m_assetManager = assetManager; + } + + ByteBuffer slurp(String path) { + try { + InputStream inputStream = m_assetManager.open("resources/" + path); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + byte[] buffer = new byte[4096]; + while (true) { + int nRead = inputStream.read(buffer, 0, buffer.length); + if (nRead == -1) + break; + outputStream.write(buffer, 0, nRead); + } + + byte[] outputBytes = outputStream.toByteArray(); + ByteBuffer resultBuffer = ByteBuffer.allocateDirect(outputStream.size()); + resultBuffer.put(outputBytes); + return resultBuffer; + } catch (IOException exception) { + Log.e("Pathfinder", "Resource not found: " + path); + return null; + } + } +} diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoSurfaceView.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoSurfaceView.java index 3c977f8b..3628b343 100644 --- a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoSurfaceView.java +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoSurfaceView.java @@ -1,10 +1,7 @@ package graphics.pathfinder.pathfinderdemo; import android.content.Context; -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 GvrView { diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoVRListenerService.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoVRListenerService.java new file mode 100644 index 00000000..f508564f --- /dev/null +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoVRListenerService.java @@ -0,0 +1,10 @@ +package graphics.pathfinder.pathfinderdemo; + +import android.os.Build; +import android.service.vr.VrListenerService; +import android.support.annotation.RequiresApi; + +@RequiresApi(api = Build.VERSION_CODES.N) +public class PathfinderDemoVRListenerService extends VrListenerService { + +} diff --git a/demo/android/app/src/main/jniLibs/arm64-v8a/libpathfinder_android_demo.so b/demo/android/app/src/main/jniLibs/arm64-v8a/libpathfinder_android_demo.so new file mode 120000 index 00000000..d2699cb8 --- /dev/null +++ b/demo/android/app/src/main/jniLibs/arm64-v8a/libpathfinder_android_demo.so @@ -0,0 +1 @@ +../../../../../../../target/aarch64-linux-android/release/libpathfinder_android_demo.so \ No newline at end of file diff --git a/demo/android/app/src/main/res/layout/activity_pathfinder.xml b/demo/android/app/src/main/res/layout/activity_pathfinder.xml index cde78529..c1818208 100644 --- a/demo/android/app/src/main/res/layout/activity_pathfinder.xml +++ b/demo/android/app/src/main/res/layout/activity_pathfinder.xml @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="#0099cc" - tools:context=".PathfinderActivity"> + tools:context=".PathfinderDemoActivity">