Simulating navigation state events
Change-Id: I37312a1f82b9a648778d2f0cbd9f80baa796a562
But: 79884417
Test: Manually on device
diff --git a/tests/EmbeddedKitchenSinkApp/Android.mk b/tests/EmbeddedKitchenSinkApp/Android.mk
index 8239f3c..e6f457e 100644
--- a/tests/EmbeddedKitchenSinkApp/Android.mk
+++ b/tests/EmbeddedKitchenSinkApp/Android.mk
@@ -41,17 +41,29 @@
LOCAL_DEX_PREOPT := false
LOCAL_STATIC_ANDROID_LIBRARIES += \
+ car-service-lib-for-test \
+ car-apps-common \
androidx.car_car \
- car-service-lib-for-test
+ androidx.car_car-cluster
LOCAL_STATIC_JAVA_LIBRARIES += \
android.hidl.base-V1.0-java \
android.hardware.automotive.vehicle-V2.0-java \
vehicle-hal-support-lib \
- com.android.car.keventreader-client
+ com.android.car.keventreader-client \
+ kitchensink-gson
LOCAL_JAVA_LIBRARIES += android.car
include $(BUILD_PACKAGE)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+ kitchensink-gson:libs/gson-2.1.jar
+
+include $(BUILD_MULTI_PREBUILT)
+
+include $(CLEAR_VARS)
+
endif #TARGET_BUILD_PDK
diff --git a/tests/EmbeddedKitchenSinkApp/libs/gson-2.1-sources.jar b/tests/EmbeddedKitchenSinkApp/libs/gson-2.1-sources.jar
new file mode 100644
index 0000000..09396a0
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/libs/gson-2.1-sources.jar
Binary files differ
diff --git a/tests/EmbeddedKitchenSinkApp/libs/gson-2.1.jar b/tests/EmbeddedKitchenSinkApp/libs/gson-2.1.jar
new file mode 100644
index 0000000..83c5c99
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/libs/gson-2.1.jar
Binary files differ
diff --git a/tests/EmbeddedKitchenSinkApp/res/raw/nav_state_data.json b/tests/EmbeddedKitchenSinkApp/res/raw/nav_state_data.json
new file mode 100644
index 0000000..2aa5cd0
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/raw/nav_state_data.json
@@ -0,0 +1,55 @@
+[
+ {
+ "mSteps": [
+ {
+ "mDistance": {
+ "mMeters": 200,
+ "mDisplayValue": "0.2",
+ "mDisplayUnit": { "mValues": [ "KILOMETERS" ] }
+ },
+ "mManeuver": {
+ "mType": { "mValues": [ "DEPART" ] }
+ }
+ }
+ ],
+ "mDestinations": [
+ {
+ "mTitle": "Home",
+ "mAddress": "123 Main st",
+ "mDistance": {
+ "mMeters": 2000,
+ "mDisplayValue": "2",
+ "mDisplayUnit": { "mValues": [ "KILOMETERS" ] }
+ }
+ }
+ ]
+ },
+ {
+ "mSteps": [
+ {
+ "mDistance": {
+ "mMeters": 91,
+ "mDisplayValue": "300",
+ "mDisplayUnit": { "mValues": [ "FEET" ] }
+ },
+ "mManeuver": {
+ "mType": { "mValues": [ "TURN_NORMAL_LEFT" ] }
+ }
+ }
+ ]
+ },
+ {
+ "mSteps": [
+ {
+ "mDistance": {
+ "mMeters": 3218,
+ "mDisplayValue": "2",
+ "mDisplayUnit": { "mValues": [ "MILES" ] }
+ },
+ "mManeuver": {
+ "mType": { "mValues": [ "TURN_NORMAL_RIGHT" ] }
+ }
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java
index 4f5fc5b..ad4b93a 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/cluster/InstrumentClusterFragment.java
@@ -33,22 +33,38 @@
import android.view.ViewGroup;
import android.widget.Toast;
+import androidx.annotation.IdRes;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.car.cluster.navigation.NavigationState;
import androidx.fragment.app.Fragment;
import com.google.android.car.kitchensink.R;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.stream.Collectors;
/**
* Contains functions to test instrument cluster API.
*/
public class InstrumentClusterFragment extends Fragment {
- private static final String TAG = InstrumentClusterFragment.class.getSimpleName();
+ private static final String TAG = "Cluster.KitchenSink";
private static final int DISPLAY_IN_CLUSTER_PERMISSION_REQUEST = 1;
private CarNavigationStatusManager mCarNavigationStatusManager;
private CarAppFocusManager mCarAppFocusManager;
private Car mCarApi;
+ private Timer mTimer;
+ private NavigationState[] mNavStateData;
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
@@ -81,6 +97,37 @@
mCarApi.connect();
}
+ /**
+ * Loads sample navigation data from the "nav_state_data.json" file.
+ */
+ @NonNull
+ private NavigationState[] getNavStateData() {
+ try {
+ Gson gson = new GsonBuilder().create();
+ String navStateData = getRawResourceAsString(R.raw.nav_state_data);
+ NavigationState[] navigationState = gson.fromJson(navStateData,
+ NavigationState[].class);
+ return navigationState;
+ } catch (IOException ex) {
+ Log.e(TAG, "Unable to read navigation state data", ex);
+ return new NavigationState[0];
+ }
+ }
+
+ /**
+ * Loads a raw resource as a single string.
+ */
+ @NonNull
+ private String getRawResourceAsString(@IdRes int resId) throws IOException {
+ InputStream inputStream = getResources().openRawResource(resId);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ StringBuilder builder = new StringBuilder();
+ for (String line = null; (line = reader.readLine()) != null; ) {
+ builder.append(line).append("\n");
+ }
+ return builder.toString();
+ }
+
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -88,7 +135,7 @@
View view = inflater.inflate(R.layout.instrument_cluster, container, false);
view.findViewById(R.id.cluster_start_button).setOnClickListener(v -> initCluster());
- view.findViewById(R.id.cluster_turn_left_button).setOnClickListener(v -> sendTurn());
+ view.findViewById(R.id.cluster_turn_left_button).setOnClickListener(v -> toogleSendTurn());
view.findViewById(R.id.cluster_start_activity).setOnClickListener(v -> startNavActivity());
return view;
@@ -97,7 +144,6 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
initCarApi();
-
super.onCreate(savedInstanceState);
}
@@ -126,12 +172,46 @@
}
}
- private void sendTurn() {
- // TODO(deanh): Make this actually meaningful.
- Bundle bundle = new Bundle();
- bundle.putString("someName", "someValue time=" + System.currentTimeMillis());
+ /**
+ * Enables/disables sending turn-by-turn data through the {@link CarNavigationStatusManager}
+ */
+ private void toogleSendTurn() {
+ // If we haven't yet load the sample navigation state data, do so.
+ if (mNavStateData == null) {
+ mNavStateData = getNavStateData();
+ Log.i(TAG, "Loaded: " + Arrays.asList(mNavStateData)
+ .stream()
+ .map(n -> n.toString())
+ .collect(Collectors.joining(", ")));
+ }
+
+ // Toggle a timer to send update periodically.
+ if (mTimer == null) {
+ mTimer = new Timer();
+ mTimer.schedule(new TimerTask() {
+ private int mPos;
+
+ @Override
+ public void run() {
+ sendTurn(mNavStateData[mPos]);
+ mPos = (mPos + 1) % mNavStateData.length;
+ }
+ }, 0, 1000);
+ } else {
+ mTimer.cancel();
+ mTimer = null;
+ }
+ }
+
+ /**
+ * Sends one update of the navigation state through the {@link CarNavigationStatusManager}
+ */
+ private void sendTurn(@NonNull NavigationState state) {
try {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("navstate", state.toParcelable());
mCarNavigationStatusManager.sendEvent(1, bundle);
+ Log.i(TAG, "Sending nav state: " + state);
} catch(CarNotConnectedException e) {
Log.e(TAG, "Failed to send turn information.", e);
}
@@ -185,8 +265,6 @@
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to get owned focus", e);
}
-
- // TODO(deanh): re-implement this using sendEvent()
}
@Override