Merge "Showing turn-by-turn directions only when navigation focus is active"
diff --git a/tests/DirectRenderingClusterSample/AndroidManifest.xml b/tests/DirectRenderingClusterSample/AndroidManifest.xml
index be7026c..c9ec9b6 100644
--- a/tests/DirectRenderingClusterSample/AndroidManifest.xml
+++ b/tests/DirectRenderingClusterSample/AndroidManifest.xml
@@ -43,7 +43,7 @@
<application android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:directBootAware="true">
- <service android:name=".SampleClusterServiceImpl"
+ <service android:name=".ClusterRenderingServiceImpl"
android:exported="false"
android:singleUser="true"
android:permission="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
diff --git a/tests/DirectRenderingClusterSample/res/layout/activity_main.xml b/tests/DirectRenderingClusterSample/res/layout/activity_main.xml
index 393db54..2cb9662 100644
--- a/tests/DirectRenderingClusterSample/res/layout/activity_main.xml
+++ b/tests/DirectRenderingClusterSample/res/layout/activity_main.xml
@@ -60,29 +60,12 @@
android:layout_width="20dp"
android:layout_height="1dp" />
- <ImageView
- android:id="@+id/maneuver"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:layout_margin="10dp"
- android:tint="@android:color/white"/>
+ <include
+ android:id="@+id/navigation_state"
+ layout="@layout/include_navigation_state"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
- <LinearLayout
- android:layout_width="250dp"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/distance"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textSize="30sp"/>
- <TextView
- android:id="@+id/segment"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textSize="18sp"/>
- </LinearLayout>
</LinearLayout>
</LinearLayout>
diff --git a/tests/DirectRenderingClusterSample/res/layout/include_navigation_state.xml b/tests/DirectRenderingClusterSample/res/layout/include_navigation_state.xml
new file mode 100644
index 0000000..1946f0c
--- /dev/null
+++ b/tests/DirectRenderingClusterSample/res/layout/include_navigation_state.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/maneuver"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_margin="10dp"
+ android:tint="@android:color/white"/>
+
+ <LinearLayout
+ android:layout_width="250dp"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/distance"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textSize="30sp"/>
+ <TextView
+ android:id="@+id/segment"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textSize="18sp"/>
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/SampleClusterServiceImpl.java b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterRenderingServiceImpl.java
similarity index 97%
rename from tests/DirectRenderingClusterSample/src/android/car/cluster/sample/SampleClusterServiceImpl.java
rename to tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterRenderingServiceImpl.java
index f8a5b06..c68f722 100644
--- a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/SampleClusterServiceImpl.java
+++ b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterRenderingServiceImpl.java
@@ -69,7 +69,7 @@
* Implementation of {@link InstrumentClusterRenderingService} which renders an activity on a
* virtual display that is transmitted to an external screen.
*/
-public class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
+public class ClusterRenderingServiceImpl extends InstrumentClusterRenderingService {
private static final String TAG = "Cluster.SampleService";
private static final int NO_DISPLAY = -1;
@@ -118,9 +118,9 @@
};
private static class UserReceiver extends BroadcastReceiver {
- private WeakReference<SampleClusterServiceImpl> mService;
+ private WeakReference<ClusterRenderingServiceImpl> mService;
- UserReceiver(SampleClusterServiceImpl service) {
+ UserReceiver(ClusterRenderingServiceImpl service) {
mService = new WeakReference<>(service);
}
@@ -136,16 +136,16 @@
@Override
public void onReceive(Context context, Intent intent) {
- SampleClusterServiceImpl service = mService.get();
+ ClusterRenderingServiceImpl service = mService.get();
Log.d(TAG, "Broadcast received: " + intent);
service.tryLaunchActivity();
}
}
private static class MessageHandler extends Handler {
- private final WeakReference<SampleClusterServiceImpl> mService;
+ private final WeakReference<ClusterRenderingServiceImpl> mService;
- MessageHandler(SampleClusterServiceImpl service) {
+ MessageHandler(ClusterRenderingServiceImpl service) {
mService = new WeakReference<>(service);
}
@@ -364,7 +364,7 @@
}
case "destroyOverlayDisplay": {
Settings.Global.putString(getContentResolver(),
- Global.OVERLAY_DISPLAY_DEVICES, "");
+ Global.OVERLAY_DISPLAY_DEVICES, "");
break;
}
diff --git a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java
index 2e38054..7464552 100644
--- a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java
+++ b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java
@@ -16,17 +16,20 @@
package android.car.cluster.sample;
import static android.car.cluster.CarInstrumentClusterManager.CATEGORY_NAVIGATION;
-import static android.car.cluster.sample.SampleClusterServiceImpl.LOCAL_BINDING_ACTION;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_KEY_ACTIVITY_DISPLAY_ID;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_KEY_ACTIVITY_STATE;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_KEY_CATEGORY;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_KEY_KEY_EVENT;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_ON_KEY_EVENT;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_ON_NAVIGATION_STATE_CHANGED;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_REGISTER_CLIENT;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_SET_ACTIVITY_LAUNCH_OPTIONS;
-import static android.car.cluster.sample.SampleClusterServiceImpl.MSG_UNREGISTER_CLIENT;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.LOCAL_BINDING_ACTION;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_KEY_ACTIVITY_DISPLAY_ID;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_KEY_ACTIVITY_STATE;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_KEY_CATEGORY;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_KEY_KEY_EVENT;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_ON_KEY_EVENT;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_ON_NAVIGATION_STATE_CHANGED;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_REGISTER_CLIENT;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_SET_ACTIVITY_LAUNCH_OPTIONS;
+import static android.car.cluster.sample.ClusterRenderingServiceImpl.MSG_UNREGISTER_CLIENT;
+import android.car.Car;
+import android.car.CarAppFocusManager;
+import android.car.CarNotConnectedException;
import android.car.cluster.ClusterActivityState;
import android.content.ComponentName;
import android.content.Intent;
@@ -74,7 +77,8 @@
private Messenger mService;
private Messenger mServiceCallbacks = new Messenger(new MessageHandler(this));
private VirtualDisplay mPendingVirtualDisplay = null;
- private final Handler mHandler = new Handler();
+ private Car mCar;
+ private CarAppFocusManager mCarAppFocusManager;
public static class VirtualDisplay {
public final int mDisplayId;
@@ -96,7 +100,7 @@
}
};
- private ServiceConnection mServiceConnection = new ServiceConnection() {
+ private ServiceConnection mClusterRenderingServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected, name: " + name + ", service: " + service);
@@ -117,6 +121,32 @@
}
};
+ private ServiceConnection mCarServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ try {
+ Log.i(TAG, "onServiceConnected, name: " + name + ", service: " + service);
+ mCarAppFocusManager = (CarAppFocusManager) mCar.getCarManager(
+ Car.APP_FOCUS_SERVICE);
+ if (mCarAppFocusManager == null) {
+ Log.e(TAG, "onServiceConnected: unable to obtain CarAppFocusManager");
+ return;
+ }
+ mCarAppFocusManager.addFocusListener((appType, active) -> {
+ onNavigationFocusChanged(active);
+ }, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
+ } catch (CarNotConnectedException e) {
+ Log.e(TAG, "onServiceConnected: error obtaining manager", e);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.i(TAG, "onServiceDisconnected, name: " + name);
+ mCarAppFocusManager = null;
+ }
+ };
+
private static class MessageHandler extends Handler {
private final WeakReference<MainClusterActivity> mActivity;
@@ -138,7 +168,7 @@
data.setClassLoader(ParcelUtils.class.getClassLoader());
NavigationState navState = NavigationState
.fromParcelable(data.getParcelable(
- SampleClusterServiceImpl.NAV_STATE_BUNDLE_KEY));
+ ClusterRenderingServiceImpl.NAV_STATE_BUNDLE_KEY));
mActivity.get().onNavigationStateChange(navState);
}
break;
@@ -156,9 +186,9 @@
mInputMethodManager = getSystemService(InputMethodManager.class);
- Intent intent = new Intent(this, SampleClusterServiceImpl.class);
+ Intent intent = new Intent(this, ClusterRenderingServiceImpl.class);
intent.setAction(LOCAL_BINDING_ACTION);
- bindService(intent, mServiceConnection, 0);
+ bindService(intent, mClusterRenderingServiceConnection, 0);
registerFacets(
new Facet<>(findViewById(R.id.btn_nav), 0, NavigationFragment.class),
@@ -169,19 +199,23 @@
mPager = findViewById(R.id.pager);
mPager.setAdapter(new ClusterPageAdapter(getSupportFragmentManager()));
mOrderToFacet.get(0).button.requestFocus();
- mNavStateController = new NavStateController(findViewById(R.id.maneuver),
- findViewById(R.id.distance), findViewById(R.id.segment));
+ mNavStateController = new NavStateController(findViewById(R.id.navigation_state));
+
+ mCar = Car.createCar(this, mCarServiceConnection);
+ mCar.connect();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
+ mCar.disconnect();
+ mCarAppFocusManager = null;
if (mService != null) {
sendServiceMessage(MSG_UNREGISTER_CLIENT, null, mServiceCallbacks);
mService = null;
}
- unbindService(mServiceConnection);
+ unbindService(mClusterRenderingServiceConnection);
}
private void onKeyEvent(KeyEvent event) {
@@ -201,6 +235,12 @@
}
}
+ private void onNavigationFocusChanged(boolean active) {
+ if (mNavStateController != null) {
+ mNavStateController.setActive(active);
+ }
+ }
+
public void updateNavDisplay(VirtualDisplay virtualDisplay) {
if (mService == null) {
// Service is not bound yet. Hold the information and notify when the service is bound.
@@ -223,8 +263,8 @@
}
/**
- * Sends a message to the {@link SampleClusterServiceImpl}, which runs on a different process.
-
+ * Sends a message to the {@link ClusterRenderingServiceImpl}, which runs on a different
+ * process.
* @param what action to perform
* @param data action data
* @param replyTo {@link Messenger} where to reply back
diff --git a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/NavStateController.java b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/NavStateController.java
index b45a806..44b6268 100644
--- a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/NavStateController.java
+++ b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/NavStateController.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
+import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -36,21 +37,21 @@
private ImageView mManeuver;
private TextView mDistance;
private TextView mSegment;
+ private View mNavigationState;
private Context mContext;
/**
* Creates a controller to coordinate updates to the views displaying navigation state
* data.
*
- * @param maneuver {@link ImageView} used to display the immediate navigation maneuver
- * @param distance {@link TextView} displaying distance to the maneuver
- * @param segment {@link TextView} displaying the current street.
+ * @param container {@link View} containing the navigation state views
*/
- public NavStateController(ImageView maneuver, TextView distance, TextView segment) {
- mManeuver = maneuver;
- mDistance = distance;
- mSegment = segment;
- mContext = maneuver.getContext();
+ public NavStateController(View container) {
+ mNavigationState = container;
+ mManeuver = container.findViewById(R.id.maneuver);
+ mDistance = container.findViewById(R.id.distance);
+ mSegment = container.findViewById(R.id.segment);
+ mContext = container.getContext();
}
/**
@@ -63,6 +64,18 @@
mDistance.setText(formatDistance(step != null ? step.getDistance() : null));
}
+ /**
+ * Updates whether turn-by-turn display is active or not. Turn-by-turn would be active whenever
+ * a navigation application has focus.
+ */
+ public void setActive(boolean active) {
+ Log.i(TAG, "Navigation status active: " + active);
+ if (!active) {
+ mManeuver.setImageDrawable(null);
+ mDistance.setText(null);
+ }
+ }
+
private Drawable getManeuverIcon(@Nullable Maneuver maneuver) {
if (maneuver == null) {
return null;