Merge "Add maximum and average sample rates in KitchenSyn app." into sc-dev
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/custom_spinner_dropdown_item.xml b/tests/EmbeddedKitchenSinkApp/res/layout/custom_spinner_dropdown_item.xml
new file mode 100644
index 0000000..4bc954d
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/custom_spinner_dropdown_item.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ 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.
+ -->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/property_list_item.xml b/tests/EmbeddedKitchenSinkApp/res/layout/property_list_item.xml
index f8051ee..e550d45 100644
--- a/tests/EmbeddedKitchenSinkApp/res/layout/property_list_item.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/property_list_item.xml
@@ -15,8 +15,8 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<TextView
android:id="@+id/tvPropertyName"
@@ -25,14 +25,13 @@
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:paddingLeft="8dp"
- android:textSize="@dimen/propertyTextSize" />
+ android:textSize="@dimen/propertyTextSize"/>
- <ToggleButton
- android:id="@+id/tbRegisterPropertyBtn"
+ <Spinner
+ android:id="@+id/tbRegisterPropertySpinner"
+ android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:text="@string/property_register" />
+ android:gravity="right"/>
</RelativeLayout>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyListAdapter.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyListAdapter.java
index 92ed8c5..d81ea8c 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyListAdapter.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyListAdapter.java
@@ -18,36 +18,50 @@
import static java.lang.Integer.toHexString;
+import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyConfig;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.content.Context;
import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.util.SparseLongArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ScrollView;
+import android.widget.Spinner;
import android.widget.TextView;
-import android.widget.ToggleButton;
import com.google.android.car.kitchensink.R;
import java.util.List;
class PropertyListAdapter extends BaseAdapter implements ListAdapter {
- private static final int DEFAULT_RATE = 1;
+ private static final float DEFAULT_RATE = 1f;
private static final String TAG = "PropertyListAdapter";
+ private static final String OFF = "Off";
+ private static final String ON = "On";
+ private static final String MAX_SAMPLE_RATE = "Maximum sample rate";
+ private static final String AVG_SAMPLE_RATE = "Average sample rate";
+ private static final String[] DROP_MENU_FOR_CONTINUOUS =
+ new String[]{OFF, MAX_SAMPLE_RATE, AVG_SAMPLE_RATE};
+ private static final String[] DROP_MENU_FOR_ON_CHANGE = new String[]{OFF, ON};
private final Context mContext;
private final PropertyListEventListener mListener;
private final CarPropertyManager mMgr;
private final List<PropertyInfo> mPropInfo;
private final TextView mTvEventLog;
+ private String[] mItems;
PropertyListAdapter(List<PropertyInfo> propInfo, CarPropertyManager mgr, TextView eventLog,
- ScrollView svEventLog, Context context) {
+ ScrollView svEventLog, Context context) {
mContext = context;
mListener = new PropertyListEventListener(eventLog, svEventLog);
mMgr = mgr;
@@ -83,56 +97,111 @@
TextView listItemText = (TextView) view.findViewById(R.id.tvPropertyName);
listItemText.setText(mPropInfo.get(position).toString());
- //Handle buttons and add onClickListeners
- ToggleButton btn = (ToggleButton) view.findViewById(R.id.tbRegisterPropertyBtn);
+ Spinner dropdown = view.findViewById(R.id.tbRegisterPropertySpinner);
- btn.setOnClickListener(new View.OnClickListener(){
+ CarPropertyConfig c = mPropInfo.get(position).mConfig;
+ if (c.getChangeMode() == CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) {
+ mItems = DROP_MENU_FOR_CONTINUOUS;
+ } else {
+ mItems = DROP_MENU_FOR_ON_CHANGE;
+ }
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,
+ R.layout.custom_spinner_dropdown_item, mItems);
+
+ adapter.setDropDownViewResource(R.layout.custom_spinner_dropdown_item);
+ dropdown.setAdapter(adapter);
+ dropdown.setSelection(0);
+ dropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
- public void onClick(View v) {
+ public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) {
+ String item = (String) adapterView.getItemAtPosition(pos);
CarPropertyConfig c = mPropInfo.get(position).mConfig;
int propId = c.getPropertyId();
try {
- if (btn.isChecked()) {
- mMgr.registerCallback(mListener, propId, DEFAULT_RATE);
- } else {
+ if (OFF.equals(item)) {
mMgr.unregisterCallback(mListener, propId);
+ } else if (MAX_SAMPLE_RATE.equals(item)) {
+ mListener.addPropertySelectedSampleRate(propId, c.getMaxSampleRate());
+ mListener.updatePropertyStartTime(propId);
+ mListener.resetEventCountForProperty(propId);
+ mMgr.registerCallback(mListener, propId, c.getMaxSampleRate());
+ } else if (AVG_SAMPLE_RATE.equals(item)) {
+ mListener.addPropertySelectedSampleRate(propId,
+ (c.getMaxSampleRate() + c.getMinSampleRate()) / 2);
+ mListener.updatePropertyStartTime(propId);
+ mListener.resetEventCountForProperty(propId);
+ mMgr.registerCallback(mListener, propId,
+ (c.getMaxSampleRate() + c.getMinSampleRate()) / 2);
+ } else if (ON.equals(item)) {
+ mListener.addPropertySelectedSampleRate(propId,
+ DEFAULT_RATE);
+ mListener.updatePropertyStartTime(propId);
+ mListener.resetEventCountForProperty(propId);
+ mMgr.registerCallback(mListener, propId, DEFAULT_RATE);
}
} catch (Exception e) {
Log.e(TAG, "Unhandled exception: ", e);
}
}
+
+ @Override
+ public void onNothingSelected(AdapterView<?> adapterView) {
+ // do nothing.
+ }
});
return view;
}
private static class PropertyListEventListener implements CarPropertyEventCallback {
- private int mNumEvents;
- private ScrollView mScrollView;
- private TextView mTvLogEvent;
+ private final ScrollView mScrollView;
+ private final TextView mTvLogEvent;
+ private final SparseArray<Float> mPropSampleRate = new SparseArray<>();
+ private final SparseLongArray mStartTime = new SparseLongArray();
+ private final SparseIntArray mNumEvents = new SparseIntArray();
PropertyListEventListener(TextView logEvent, ScrollView scrollView) {
mScrollView = scrollView;
mTvLogEvent = logEvent;
}
+ void addPropertySelectedSampleRate(Integer propId, Float sampleRate) {
+ mPropSampleRate.put(propId, sampleRate);
+ }
+
+ void updatePropertyStartTime(Integer propId) {
+ mStartTime.put(propId, System.currentTimeMillis());
+ }
+
+ void resetEventCountForProperty(Integer propId) {
+ mNumEvents.put(propId, 0);
+ }
+
@Override
public void onChangeEvent(CarPropertyValue value) {
- mNumEvents++;
- mTvLogEvent.append("Event " + mNumEvents + ":"
- + " time=" + value.getTimestamp()
- + " propId=0x" + toHexString(value.getPropertyId())
- + " areaId=0x" + toHexString(value.getAreaId())
- + " status=" + value.getStatus()
- + " value=" + value.getValue()
- + "\n");
+ int propId = value.getPropertyId();
+
+ mNumEvents.put(propId, mNumEvents.get(propId) + 1);
+ mTvLogEvent.append(String.format("Event %1$s: time=%2$s propId=0x%3$s areaId=0x%3$s "
+ + "name=%4$s status=%5$s value=%6$s", mNumEvents.get(propId),
+ value.getTimestamp(), toHexString(propId), VehiclePropertyIds.toString(propId),
+ value.getStatus(), value.getValue()));
+ if (mPropSampleRate.contains(propId)) {
+ mTvLogEvent.append(
+ String.format(" selected sample rate=%1$s actual sample rate=%2$s\n",
+ mPropSampleRate.get(propId),
+ mNumEvents.get(propId) / (System.currentTimeMillis()
+ - mStartTime.get(propId))));
+ } else {
+ mTvLogEvent.append("\n");
+ }
scrollToBottom();
}
@Override
public void onErrorEvent(int propId, int areaId) {
mTvLogEvent.append("Received error event propId=0x" + toHexString(propId)
- + ", areaId=0x" + toHexString(areaId));
+ + ", areaId=0x" + toHexString(areaId));
scrollToBottom();
}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyTestFragment.java
index 6122330..c65b6df 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyTestFragment.java
@@ -188,7 +188,6 @@
// Spinner callbacks
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
- // An item was selected. You can retrieve the selected item using
PropertyInfo info = (PropertyInfo) parent.getItemAtPosition(pos);
int[] areaIds = info.mConfig.getAreaIds();
List<String> areaString = new LinkedList<String>();