diff options
Diffstat (limited to 'platform_tools/android/apps/arcore/src/main/java/org/skia/arcore/HelloArActivity.java')
-rw-r--r-- | platform_tools/android/apps/arcore/src/main/java/org/skia/arcore/HelloArActivity.java | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/platform_tools/android/apps/arcore/src/main/java/org/skia/arcore/HelloArActivity.java b/platform_tools/android/apps/arcore/src/main/java/org/skia/arcore/HelloArActivity.java new file mode 100644 index 0000000000..73651f51c6 --- /dev/null +++ b/platform_tools/android/apps/arcore/src/main/java/org/skia/arcore/HelloArActivity.java @@ -0,0 +1,364 @@ +/* + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.skia.arcore; + +import android.app.Activity; +import android.content.Context; +import android.hardware.display.DisplayManager; +import android.opengl.GLES20; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.os.Handler; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.ActionMode; +import android.view.ContextMenu; +import android.view.GestureDetector; +import android.view.Gravity; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.PopupMenu; +import android.widget.Toast; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +/** + * This is a simple example that shows how to create an augmented reality (AR) application using the + * ARCore C API. + */ +public class HelloArActivity extends AppCompatActivity + implements GLSurfaceView.Renderer, DisplayManager.DisplayListener { + private static final String TAG = HelloArActivity.class.getSimpleName(); + private static final int SNACKBAR_UPDATE_INTERVAL_MILLIS = 1000; // In milliseconds. + + private GLSurfaceView mSurfaceView; + private Activity activity = null; + private boolean mViewportChanged = false; + private int mViewportWidth; + private int mViewportHeight; + private View contextView = null; + private int mCurrentObjectRotation = 0; + private float mCurrentValue = 0; + private float X = 0; + private float Y = 0; + + private boolean toEdit = false; + + // Opaque native pointer to the native application instance. + private long mNativeApplication; + private GestureDetector mGestureDetector; + + private Snackbar mLoadingMessageSnackbar; + private Handler mPlaneStatusCheckingHandler; + private final Runnable mPlaneStatusCheckingRunnable = + new Runnable() { + @Override + public void run() { + // The runnable is executed on main UI thread. + try { + if (JniInterface.hasDetectedPlanes(mNativeApplication)) { + if (mLoadingMessageSnackbar != null) { + mLoadingMessageSnackbar.dismiss(); + } + mLoadingMessageSnackbar = null; + } else { + mPlaneStatusCheckingHandler.postDelayed( + mPlaneStatusCheckingRunnable, SNACKBAR_UPDATE_INTERVAL_MILLIS); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + }; + private int mDrawMode = -1; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar); + setSupportActionBar(myToolbar); + + activity = this; + + //hide notifications bar + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + + mSurfaceView = (GLSurfaceView) findViewById(R.id.surfaceview); + + mGestureDetector = + new GestureDetector( + this, + new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onSingleTapUp(final MotionEvent e) { + toEdit = JniInterface.onTouchedFirst(mNativeApplication, e.getX(), e.getY(), mDrawMode); + + Log.i(TAG, "toEdit: " + toEdit); + X = e.getX(); + Y = e.getY(); + contextView.showContextMenu(e.getX(), e.getY()); + return true; + } + + @Override + public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + Log.i(TAG, "Scrolling!"); + JniInterface.onTouchTranslate(mNativeApplication, e2.getX(), e2.getY()); + return true; + } + + @Override + public boolean onDown(MotionEvent e) { + return true; + } + }); + + mSurfaceView.setOnTouchListener( + new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return mGestureDetector.onTouchEvent(event); + } + }); + + // Set up renderer. + mSurfaceView.setPreserveEGLContextOnPause(true); + mSurfaceView.setEGLContextClientVersion(2); + mSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // Alpha used for plane blending. + mSurfaceView.setRenderer(this); + mSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); + + JniInterface.assetManager = getAssets(); + mNativeApplication = JniInterface.createNativeApplication(getAssets()); + + mPlaneStatusCheckingHandler = new Handler(); + + //Floating context menu + contextView = findViewById(R.id.menuView); + this.registerForContextMenu(contextView); + View.OnLongClickListener listener = new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + activity.closeContextMenu(); + return false; + } + }; + contextView.setOnLongClickListener(listener); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) + { + super.onCreateContextMenu(menu, v, menuInfo); + + if (!toEdit) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.draw_menu, menu); + menu.setHeaderTitle("Draw Options"); + } + + v.setClickable(false); + v.setFocusable(false); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); + switch (item.getItemId()) { + case R.id.draw_text: + JniInterface.onTouchedFinal(mNativeApplication, 0); + return true; + case R.id.draw_circle: + JniInterface.onTouchedFinal(mNativeApplication, 1); + return true; + case R.id.draw_rect: + JniInterface.onTouchedFinal(mNativeApplication, 2); + return true; + case R.id.edit_size: + return true; + case R.id.edit_text: + return true; + default: + return super.onContextItemSelected(item); + } + } + + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.rotation_mode, menu); + return true; + } + + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.rotation_axis_aligned: + mCurrentObjectRotation = 0; + break; + case R.id.rotation_camera_aligned: + mCurrentObjectRotation = 1; + break; + case R.id.rotation_snap_aligned: + mCurrentObjectRotation = 2; + break; + case R.id.action: + mCurrentValue = 180; + JniInterface.onAction(mNativeApplication, mCurrentValue); + return true; + default: + return true; + } + JniInterface.onObjectRotationChanged(mNativeApplication, mCurrentObjectRotation); + return true; + } + + @Override + protected void onResume() { + super.onResume(); + // ARCore requires camera permissions to operate. If we did not yet obtain runtime + // permission on Android M and above, now is a good time to ask the user for it. + if (!CameraPermissionHelper.hasCameraPermission(this)) { + CameraPermissionHelper.requestCameraPermission(this); + return; + } + + JniInterface.onResume(mNativeApplication, getApplicationContext(), this); + mSurfaceView.onResume(); + + mLoadingMessageSnackbar = + Snackbar.make( + HelloArActivity.this.findViewById(android.R.id.content), + "Searching for surfaces...", + Snackbar.LENGTH_INDEFINITE); + // Set the snackbar background to light transparent black color. + mLoadingMessageSnackbar.getView().setBackgroundColor(0xbf323232); + mLoadingMessageSnackbar.show(); + mPlaneStatusCheckingHandler.postDelayed( + mPlaneStatusCheckingRunnable, SNACKBAR_UPDATE_INTERVAL_MILLIS); + + // Listen to display changed events to detect 180° rotation, which does not cause a config + // change or view resize. + getSystemService(DisplayManager.class).registerDisplayListener(this, null); + } + + @Override + public void onPause() { + super.onPause(); + mSurfaceView.onPause(); + JniInterface.onPause(mNativeApplication); + + mPlaneStatusCheckingHandler.removeCallbacks(mPlaneStatusCheckingRunnable); + + getSystemService(DisplayManager.class).unregisterDisplayListener(this); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + // Synchronized to avoid racing onDrawFrame. + synchronized (this) { + JniInterface.destroyNativeApplication(mNativeApplication); + mNativeApplication = 0; + } + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (hasFocus) { + // Standard Android full-screen functionality. + getWindow() + .getDecorView() + .setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + GLES20.glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + JniInterface.onGlSurfaceCreated(mNativeApplication); + } + + @Override + public void onSurfaceChanged(GL10 gl, int width, int height) { + mViewportWidth = width; + mViewportHeight = height; + mViewportChanged = true; + } + + @Override + public void onDrawFrame(GL10 gl) { + // Synchronized to avoid racing onDestroy. + synchronized (this) { + if (mNativeApplication == 0) { + return; + } + if (mViewportChanged) { + int displayRotation = getWindowManager().getDefaultDisplay().getRotation(); + JniInterface.onDisplayGeometryChanged( + mNativeApplication, displayRotation, mViewportWidth, mViewportHeight); + mViewportChanged = false; + } + JniInterface.onGlSurfaceDrawFrame(mNativeApplication); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) { + if (!CameraPermissionHelper.hasCameraPermission(this)) { + Toast.makeText(this, "Camera permission is needed to run this application", Toast.LENGTH_LONG) + .show(); + if (!CameraPermissionHelper.shouldShowRequestPermissionRationale(this)) { + // Permission denied with checking "Do not ask again". + CameraPermissionHelper.launchPermissionSettings(this); + } + finish(); + } + } + + // DisplayListener methods + @Override + public void onDisplayAdded(int displayId) { + } + + @Override + public void onDisplayRemoved(int displayId) { + } + + @Override + public void onDisplayChanged(int displayId) { + mViewportChanged = true; + } +} |