1616
1717package com .projecttango .experiments .javapointcloud ;
1818
19+ import com .google .atap .tango .ux .UxExceptionEvent ;
20+ import com .google .atap .tango .ux .UxExceptionEventListener ;
1921import com .google .atap .tangoservice .Tango ;
2022import com .google .atap .tangoservice .Tango .OnTangoUpdateListener ;
2123import com .google .atap .tangoservice .TangoConfig ;
2729import com .google .atap .tangoservice .TangoPoseData ;
2830import com .google .atap .tangoservice .TangoXyzIjData ;
2931
32+ import com .google .atap .tango .ux .TangoUx ;
33+ import com .google .atap .tango .ux .TangoUxLayout ;
34+
35+
3036import android .app .Activity ;
3137import android .content .Intent ;
3238import android .content .pm .PackageInfo ;
@@ -88,10 +94,62 @@ public class PointCloudActivity extends Activity implements OnClickListener {
8894 private String mServiceVersion ;
8995 private boolean mIsTangoServiceConnected ;
9096 private TangoPoseData mPose ;
97+
98+ private TangoUx mTangoUx ;
99+ private TangoUxLayout mTangoUxLayout ;
100+
91101 private static final int UPDATE_INTERVAL_MS = 100 ;
92102 public static Object poseLock = new Object ();
93103 public static Object depthLock = new Object ();
94104
105+
106+ /*
107+ * This is an advanced way of using UX exceptions. In most cases developers can just use the in
108+ * built exception notifications using the Ux Exception layout. In case a developer doesn't want
109+ * to use the default Ux Exception notifications, he can set the UxException listener as shown
110+ * below.
111+ * In this example we are just logging all the ux exceptions to logcat, but in a real app,
112+ * developers should use these exceptions to contextually notify the user and help direct the
113+ * user in using the device in a way Tango service expects it.
114+ */
115+ private UxExceptionEventListener mUxExceptionListener = new UxExceptionEventListener () {
116+
117+ @ Override
118+ public void onUxExceptionEvent (UxExceptionEvent uxExceptionEvent ) {
119+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_LYING_ON_SURFACE ){
120+ Log .i (TAG , "Device lying on surface " );
121+ }
122+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_FEW_DEPTH_POINTS ){
123+ Log .i (TAG , "Very few depth points in point cloud " );
124+ }
125+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_FEW_FEATURES ){
126+ Log .i (TAG , "Invalid poses in MotionTracking " );
127+ }
128+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_INCOMPATIBLE_VM ){
129+ Log .i (TAG , "Device not running on ART" );
130+ }
131+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_MOTION_TRACK_INVALID ){
132+ Log .i (TAG , "Invalid poses in MotionTracking " );
133+ }
134+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_MOVING_TOO_FAST ){
135+ Log .i (TAG , "Invalid poses in MotionTracking " );
136+ }
137+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_OVER_EXPOSED ){
138+ Log .i (TAG , "Camera Over Exposed" );
139+ }
140+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_TANGO_SERVICE_NOT_RESPONDING ){
141+ Log .i (TAG , "TangoService is not responding " );
142+ }
143+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_TANGO_UPDATE_NEEDED ){
144+ Log .i (TAG , "Device not running on ART" );
145+ }
146+ if (uxExceptionEvent .getType () == UxExceptionEvent .TYPE_UNDER_EXPOSED ){
147+ Log .i (TAG , "Camera Under Exposed " );
148+ }
149+
150+ }
151+ };
152+
95153 @ Override
96154 protected void onCreate (Bundle savedInstanceState ) {
97155 super .onCreate (savedInstanceState );
@@ -121,6 +179,12 @@ protected void onCreate(Bundle savedInstanceState) {
121179 mConfig = mTango .getConfig (TangoConfig .CONFIG_TYPE_CURRENT );
122180 mConfig .putBoolean (TangoConfig .KEY_BOOLEAN_DEPTH , true );
123181
182+ mTangoUx = new TangoUx .Builder (this ).build ();
183+ mTangoUxLayout = (TangoUxLayout ) findViewById (R .id .layout_tango );
184+ mTangoUx = new TangoUx .Builder (this ).setTangoUxLayout (mTangoUxLayout ).build ();
185+ mTangoUx .setUxExceptionEventListener (mUxExceptionListener );
186+
187+
124188 int maxDepthPoints = mConfig .getInt ("max_point_cloud_elements" );
125189 mRenderer = new PCRenderer (maxDepthPoints );
126190 mGLView = (GLSurfaceView ) findViewById (R .id .gl_surface_view );
@@ -145,6 +209,7 @@ protected void onCreate(Bundle savedInstanceState) {
145209 @ Override
146210 protected void onPause () {
147211 super .onPause ();
212+ mTangoUx .stop ();
148213 try {
149214 mTango .disconnect ();
150215 mIsTangoServiceConnected = false ;
@@ -156,6 +221,7 @@ protected void onPause() {
156221 @ Override
157222 protected void onResume () {
158223 super .onResume ();
224+ mTangoUx .start ();
159225 if (!mIsTangoServiceConnected ) {
160226 startActivityForResult (
161227 Tango .getRequestPermissionIntent (Tango .PERMISSIONTYPE_MOTION_TRACKING ),
@@ -186,9 +252,10 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
186252 try {
187253 mTango .connect (mConfig );
188254 mIsTangoServiceConnected = true ;
189- } catch (TangoOutOfDateException e ) {
190- Toast .makeText (getApplicationContext (), R .string .TangoOutOfDateException ,
191- Toast .LENGTH_SHORT ).show ();
255+ } catch (TangoOutOfDateException outDateEx ) {
256+ if (mTangoUx != null ) {
257+ mTangoUx .onTangoOutOfDate ();
258+ }
192259 } catch (TangoErrorException e ) {
193260 Toast .makeText (getApplicationContext (), R .string .TangoError , Toast .LENGTH_SHORT )
194261 .show ();
@@ -264,6 +331,10 @@ private void setTangoListeners() {
264331
265332 @ Override
266333 public void onPoseAvailable (final TangoPoseData pose ) {
334+ // Passing in the pose data to UX library produce exceptions.
335+ if (mTangoUx != null ) {
336+ mTangoUx .updatePoseStatus (pose .statusCode );
337+ }
267338 // Make sure to have atomic access to Tango Pose Data so that
268339 // render loop doesn't interfere while Pose call back is updating
269340 // the data.
@@ -289,6 +360,9 @@ public void onPoseAvailable(final TangoPoseData pose) {
289360
290361 @ Override
291362 public void onXyzIjAvailable (final TangoXyzIjData xyzIj ) {
363+ if (mTangoUx !=null ){
364+ mTangoUx .updateXyzCount (xyzIj .xyzCount );
365+ }
292366 // Make sure to have atomic access to TangoXyzIjData so that
293367 // render loop doesn't interfere while onXYZijAvailable callback is updating
294368 // the point cloud data.
@@ -322,6 +396,9 @@ public void onXyzIjAvailable(final TangoXyzIjData xyzIj) {
322396
323397 @ Override
324398 public void onTangoEvent (final TangoEvent event ) {
399+ if (mTangoUx !=null ){
400+ mTangoUx .onTangoEvent (event );
401+ }
325402 runOnUiThread (new Runnable () {
326403 @ Override
327404 public void run () {
0 commit comments