Skip to content

Commit

Permalink
UI to realign controller on startup
Browse files Browse the repository at this point in the history
Display a dialog informing the user that it is necessary to
point the phone straight ahead to set up the controller.
This dialog will be dismissed automatically after 5 seconds,
clicking the realign button on it will close it faster.
  • Loading branch information
felipeerias committed Apr 30, 2024
1 parent d719eda commit 924d654
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 13 deletions.
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2557,5 +2557,7 @@ the Select` button. When clicked it closes all the previously selected tabs -->
<string name="vision_glass_disconnected_message">Please connect Vision Glass</string>
<!-- Vision Glass: instruct the user to unplug the device and try again -->
<string name="vision_glass_error_message">An error happened.\nPlease try again.</string>
<!-- Vision Glass: instruct the user to point the phone straight ahead to re-align the controller. -->
<string name="vision_glass_realign_dialog_explanation">Please point your phone straight ahead.</string>

</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.igalia.wolvic;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;

public class AlignDialogFragment extends DialogFragment {
private AlignDynamicButton mRealignButton;
private View.OnClickListener mRealignButtonClickListener;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_align, container);
mRealignButton = view.findViewById(R.id.realign_button);
if (mRealignButtonClickListener != null)
mRealignButton.setOnClickListener(mRealignButtonClickListener);

return view;
}

public void updatePosition(float x, float y) {
mRealignButton.updatePosition(x, y);
}

public void setOnRealignButtonClickListener(View.OnClickListener listener) {
mRealignButtonClickListener = listener;
if (mRealignButton != null)
mRealignButton.setOnClickListener(listener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private void init() {
// metrics
mStrokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
mCornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());
mSquarePadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
mSquarePadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
mCirclePadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());

mPaint = new Paint();
Expand All @@ -60,17 +60,22 @@ protected void onDraw(Canvas canvas) {

// Draw square
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAlpha(150);
mPaint.setAlpha(120);
mSquareRect.set(mSquarePadding, mSquarePadding, getWidth() - mSquarePadding, getHeight() - mSquarePadding);

canvas.drawRoundRect(mSquareRect, mCornerRadius, mCornerRadius, mPaint);

// Draw crosshair
float crosshairLength = getWidth() / 12f;
canvas.drawLine(getWidth() / 2f - crosshairLength, getHeight() / 2f, getWidth() / 2f + crosshairLength, getHeight() / 2f, mPaint);
canvas.drawLine(getWidth() / 2f, getHeight() / 2f - crosshairLength, getWidth() / 2f, getHeight() / 2f + crosshairLength, mPaint);

// Draw circle
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAlpha(255);
float radius = Math.min(getWidth(), getHeight()) / 10f;
float centerX = mCirclePadding + ((mPointPosition.x + 1) * (getWidth() - mCirclePadding) / 2f);
float centerY = mCirclePadding + ((mPointPosition.y + 1) * (getHeight() - mCirclePadding) / 2f);
float centerX = mCirclePadding + ((mPointPosition.x + 1) / 2f) * (getWidth() - 2 * mCirclePadding);
float centerY = mCirclePadding + ((mPointPosition.y + 1) / 2f) * (getHeight() - 2 * mCirclePadding);

canvas.drawCircle(centerX, centerY, radius, mPaint);
}
Expand Down
48 changes: 39 additions & 9 deletions app/src/visionglass/java/com/igalia/wolvic/PlatformActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.hardware.display.DisplayManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
Expand All @@ -30,11 +31,11 @@
import android.widget.Button;
import android.widget.SeekBar;

import androidx.activity.ComponentActivity;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;

import com.huawei.usblib.DisplayMode;
Expand All @@ -55,10 +56,11 @@
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class PlatformActivity extends ComponentActivity implements SensorEventListener, OnConnectionListener {
public class PlatformActivity extends FragmentActivity implements SensorEventListener, OnConnectionListener {
static String LOGTAG = SystemUtils.createLogtag(PlatformActivity.class);

public static final String HUAWEI_USB_PERMISSION = "com.huawei.usblib.USB_PERMISSION";
private static final int REORIENT_UI_DELAY_MS = 5_000;

private boolean mIsAskingForPermission;
private PhoneUIViewModel mViewModel;
Expand All @@ -69,6 +71,7 @@ public class PlatformActivity extends ComponentActivity implements SensorEventLi
private int mDisplayModeRetryCount = 0;
private int mUSBPermissionRequestCount = 0;
private boolean mSwitchedTo3DMode = false;
private AlignDialogFragment mAlignDialogFragment;

@SuppressWarnings("unused")
public static boolean filterPermission(final String aPermission) {
Expand Down Expand Up @@ -185,6 +188,34 @@ private void registerPhoneIMUListener() {
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_NORMAL);
}

private void reorientController() {
mSensorManager.unregisterListener(this);
registerPhoneIMUListener();
queueRunnable(this::calibrateController);
runVRBrowserActivityCallback(activity -> activity.recenterUIYaw(WidgetManagerDelegate.YAW_TARGET_ALL));
}

private void onConnectionStateChanged(PhoneUIViewModel.ConnectionState connectionState) {
Log.d(LOGTAG, "Connection state updated: " + connectionState);

if (connectionState == PhoneUIViewModel.ConnectionState.ACTIVE) {
Handler autoDismiss = new Handler(getMainLooper());
autoDismiss.postDelayed(() -> {
if (mAlignDialogFragment != null && mAlignDialogFragment.isVisible()) {
reorientController();
mAlignDialogFragment.dismiss();
}
}, REORIENT_UI_DELAY_MS);

mAlignDialogFragment = new AlignDialogFragment();
mAlignDialogFragment.setOnRealignButtonClickListener(v -> {
reorientController();
mAlignDialogFragment.dismiss();
});
mAlignDialogFragment.show(getSupportFragmentManager(), "AlignDialogFragment");
}
}

private void initVisionGlassPhoneUI() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Expand All @@ -195,16 +226,11 @@ private void initVisionGlassPhoneUI() {
mBinding.setViewModel(mViewModel);
mBinding.setLifecycleOwner(this);

mViewModel.getConnectionState().observe(this, connectionState ->
Log.d(LOGTAG, "Connection state updated: " + connectionState));
mViewModel.getConnectionState().observe(this, this::onConnectionStateChanged);

mBinding.voiceSearchButton.setEnabled(false);

mBinding.realignButton.setOnClickListener(v -> {
mSensorManager.unregisterListener(this);
registerPhoneIMUListener();
queueRunnable(this::calibrateController);
});
mBinding.realignButton.setOnClickListener(v -> reorientController());

Button backButton = findViewById(R.id.back_button);
backButton.setOnClickListener(v -> onBackPressed());
Expand Down Expand Up @@ -295,6 +321,10 @@ public void onSensorChanged(SensorEvent event) {
queueRunnable(() -> setControllerOrientation(quaternion[1], quaternion[3], quaternion[2], quaternion[0]));

mBinding.realignButton.updatePosition(-quaternion[3], -quaternion[1]);

if (mAlignDialogFragment != null && mAlignDialogFragment.isVisible()) {
mAlignDialogFragment.updatePosition(-quaternion[3], -quaternion[1]);
}
}

@Override
Expand Down
28 changes: 28 additions & 0 deletions app/src/visionglass/res/layout/dialog_align.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:orientation="vertical"
android:padding="72dp">


<com.igalia.wolvic.AlignDynamicButton
android:id="@+id/realign_button"
android:layout_width="144dp"
android:layout_height="144dp"
android:layout_gravity="center"
android:backgroundTint="@color/azure"
app:iconTint="@color/white" />

<TextView
android:id="@+id/tvMessage"
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/vision_glass_realign_dialog_explanation"
android:textAlignment="center"
android:textColor="?colorOnPrimary" />

</LinearLayout>

0 comments on commit 924d654

Please sign in to comment.