aboutsummaryrefslogtreecommitdiff
path: root/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property
diff options
context:
space:
mode:
authorSteve Paik <spaik@google.com>2018-04-27 13:28:31 -0700
committerSteve Paik <spaik@google.com>2018-06-02 03:48:39 +0000
commit4d257023389c23b8836f10cda1bfa1ea136f56c9 (patch)
treed9b0d6e859dc1db4b0f7acd01c6fb28d85c42026 /tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property
parentd3cb98e76080151bdfb5085b8971b5070f11d28b (diff)
downloadCar-4d257023389c23b8836f10cda1bfa1ea136f56c9.tar.gz
Create CarPropertyService and CarPropertyManager
CarPropertyService replaces Cabin, Hvac, Info, Sensor, and VendorExtension services. Bug: 78782959 Bug: 36649684 Bug: 68056035 Test: runtest -x packages/services/Car/tests/android_car_api_test runtest -x packages/services/Car/tests/carservice_unit_test Change-Id: I69756654473fe66ef95e9e2cd4f3c1045e3ac938 Merged-In: Ic0a94805f83cc0222fb2bcf9674b6031bc050986 (cherry picked from commit fc0257133967edcb217e07e9ab942690eeaae3de) (cherry picked from commit 0265d8348716b2971f76e697f410f4cf7128371c)
Diffstat (limited to 'tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property')
-rw-r--r--tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyInfo.java55
-rw-r--r--tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyListAdapter.java149
-rw-r--r--tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyTestFragment.java205
3 files changed, 409 insertions, 0 deletions
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyInfo.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyInfo.java
new file mode 100644
index 0000000000..0f0b5d4614
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyInfo.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package com.google.android.car.kitchensink.property;
+
+import android.car.hardware.CarPropertyConfig;
+import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
+
+class PropertyInfo implements Comparable<PropertyInfo> {
+ public final CarPropertyConfig mConfig;
+ public final String mName;
+ public final int mPropId;
+
+ PropertyInfo(CarPropertyConfig config) {
+ mConfig = config;
+ mPropId = config.getPropertyId();
+ mName = VehicleProperty.toString(mPropId);
+ }
+
+ @Override
+ public String toString() {
+ return mName;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof PropertyInfo) {
+ return ((PropertyInfo) other).mPropId == mPropId;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return mPropId;
+ }
+
+ @Override
+ public int compareTo(PropertyInfo propertyInfo) {
+ return mName.compareTo(propertyInfo.mName);
+ }
+}
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
new file mode 100644
index 0000000000..06ea4eef4c
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyListAdapter.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package com.google.android.car.kitchensink.property;
+
+import static java.lang.Integer.toHexString;
+
+import android.car.hardware.CarPropertyConfig;
+import android.car.hardware.CarPropertyValue;
+import android.car.hardware.property.CarPropertyManager;
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListAdapter;
+import android.widget.ScrollView;
+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 String TAG = "PropertyListAdapter";
+ private final Context mContext;
+ private final PropertyListEventListener mListener;
+ private final CarPropertyManager mMgr;
+ private final List<PropertyInfo> mPropInfo;
+ private final TextView mTvEventLog;
+
+ PropertyListAdapter(List<PropertyInfo> propInfo, CarPropertyManager mgr, TextView eventLog,
+ ScrollView svEventLog, Context context) {
+ mContext = context;
+ mListener = new PropertyListEventListener(eventLog, svEventLog);
+ mMgr = mgr;
+ mPropInfo = propInfo;
+ mTvEventLog = eventLog;
+ }
+
+ @Override
+ public int getCount() {
+ return mPropInfo.size();
+ }
+
+ @Override
+ public Object getItem(int pos) {
+ return mPropInfo.get(pos);
+ }
+
+ @Override
+ public long getItemId(int pos) {
+ return mPropInfo.get(pos).mPropId;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ View view = convertView;
+ if (view == null) {
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ view = inflater.inflate(R.layout.property_list_item, null);
+ }
+
+ //Handle TextView and display string from your list
+ 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);
+
+ btn.setOnClickListener(new View.OnClickListener(){
+ @Override
+ public void onClick(View v) {
+ CarPropertyConfig c = mPropInfo.get(position).mConfig;
+ int propId = c.getPropertyId();
+ try {
+ if (btn.isChecked()) {
+ mMgr.registerListener(mListener, propId, DEFAULT_RATE);
+ } else {
+ mMgr.unregisterListener(mListener, propId);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unhandled exception: ", e);
+ }
+ }
+ });
+ return view;
+ }
+
+
+ private static class PropertyListEventListener implements
+ CarPropertyManager.CarPropertyEventListener {
+ private int mNumEvents;
+ private ScrollView mScrollView;
+ private TextView mTvLogEvent;
+
+ PropertyListEventListener(TextView logEvent, ScrollView scrollView) {
+ mScrollView = scrollView;
+ mTvLogEvent = logEvent;
+ }
+
+ @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");
+ scrollToBottom();
+ }
+
+ @Override
+ public void onErrorEvent(int propId, int areaId) {
+ mTvLogEvent.append("Received error event propId=0x" + toHexString(propId)
+ + ", areaId=0x" + toHexString(areaId));
+ scrollToBottom();
+ }
+
+ private void scrollToBottom() {
+ mScrollView.post(new Runnable() {
+ public void run() {
+ mScrollView.fullScroll(View.FOCUS_DOWN);
+ //mScrollView.smoothScrollTo(0, mTextStatus.getBottom());
+ }
+ });
+ }
+
+ }
+}
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
new file mode 100644
index 0000000000..fc6621a7ca
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/property/PropertyTestFragment.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package com.google.android.car.kitchensink.property;
+
+import static java.lang.Integer.toHexString;
+
+import android.annotation.Nullable;
+import android.car.hardware.CarPropertyValue;
+import android.car.hardware.property.CarPropertyManager;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
+import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.ScrollView;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.android.car.kitchensink.KitchenSinkActivity;
+import com.google.android.car.kitchensink.R;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PropertyTestFragment extends Fragment implements OnItemSelectedListener{
+ private static final String TAG = "PropertyTestFragment";
+
+ private KitchenSinkActivity mActivity;
+ private CarPropertyManager mMgr;
+ private List<PropertyInfo> mPropInfo = null;
+ private Spinner mAreaId;
+ private TextView mEventLog;
+ private TextView mGetValue;
+ private ListView mListView;
+ private Spinner mPropertyId;
+ private ScrollView mScrollView;
+ private EditText mSetValue;
+
+ private final OnClickListener mNopOnClickListener = new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) { }
+ };
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.property, container, false);
+ mActivity = (KitchenSinkActivity) getHost();
+ mMgr = mActivity.getPropertyManager();
+
+ // Get resource IDs
+ mAreaId = view.findViewById(R.id.sAreaId);
+ mEventLog = view.findViewById(R.id.tvEventLog);
+ mGetValue = view.findViewById(R.id.tvGetPropertyValue);
+ mListView = view.findViewById(R.id.lvPropertyList);
+ mPropertyId = view.findViewById(R.id.sPropertyId);
+ mScrollView = view.findViewById(R.id.svEventLog);
+ mSetValue = view.findViewById(R.id.etSetPropertyValue);
+
+ populateConfigList();
+ mListView.setAdapter(new PropertyListAdapter(mPropInfo, mMgr, mEventLog, mScrollView,
+ mActivity));
+
+ // Configure dropdown menu for propertyId spinner
+ ArrayAdapter<PropertyInfo> adapter =
+ new ArrayAdapter<PropertyInfo>(mActivity, android.R.layout.simple_spinner_item,
+ mPropInfo);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mPropertyId.setAdapter(adapter);
+ mPropertyId.setOnItemSelectedListener(this);
+
+
+
+ // Configure listeners for buttons
+ Button b = view.findViewById(R.id.bGetProperty);
+ b.setOnClickListener(v -> {
+ try {
+ PropertyInfo info = (PropertyInfo) mPropertyId.getSelectedItem();
+ int propId = info.mConfig.getPropertyId();
+ int areaId = Integer.decode(mAreaId.getSelectedItem().toString());
+ CarPropertyValue value = mMgr.getProperty(propId, areaId);
+ if (propId == VehicleProperty.WHEEL_TICK) {
+ Object[] ticks = (Object[]) value.getValue();
+ mGetValue.setText("Timestamp=" + value.getTimestamp()
+ + "\nstatus=" + value.getStatus()
+ + "\n[0]=" + (Long) ticks[0]
+ + "\n[1]=" + (Long) ticks[1] + " [2]=" + (Long) ticks[2]
+ + "\n[3]=" + (Long) ticks[3] + " [4]=" + (Long) ticks[4]);
+ } else {
+ mGetValue.setText("Timestamp=" + value.getTimestamp()
+ + "\nstatus=" + value.getStatus()
+ + "\nvalue=" + value.getValue());
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to get property", e);
+ }
+ });
+
+ b = view.findViewById(R.id.bSetProperty);
+ b.setOnClickListener(v -> {
+ try {
+ PropertyInfo info = (PropertyInfo) mPropertyId.getSelectedItem();
+ int propId = info.mConfig.getPropertyId();
+ int areaId = Integer.decode(mAreaId.getSelectedItem().toString());
+ String valueString = mSetValue.getText().toString();
+
+ switch (propId & VehiclePropertyType.MASK) {
+ case VehiclePropertyType.BOOLEAN:
+ Boolean boolVal = Boolean.parseBoolean(valueString);
+ mMgr.setBooleanProperty(propId, areaId, boolVal);
+ break;
+ case VehiclePropertyType.FLOAT:
+ Float floatVal = Float.parseFloat(valueString);
+ mMgr.setFloatProperty(propId, areaId, floatVal);
+ break;
+ case VehiclePropertyType.INT32:
+ Integer intVal = Integer.parseInt(valueString);
+ mMgr.setIntProperty(propId, areaId, intVal);
+ break;
+ default:
+ Toast.makeText(mActivity, "PropertyType=0x" + toHexString(propId
+ & VehiclePropertyType.MASK) + " is not handled!",
+ Toast.LENGTH_LONG).show();
+ break;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to set HVAC boolean property", e);
+ }
+ });
+
+ b = view.findViewById(R.id.bClearLog);
+ b.setOnClickListener(v -> {
+ mEventLog.setText("");
+ });
+
+ return view;
+ }
+
+ private void populateConfigList() {
+ try {
+ mPropInfo = mMgr.getPropertyList()
+ .stream()
+ .map(PropertyInfo::new)
+ .sorted()
+ .collect(Collectors.toList());
+ } catch (Exception e) {
+ Log.e(TAG, "Unhandled exception in populateConfigList: ", e);
+ }
+ }
+
+ // 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>();
+ if (areaIds.length == 0) {
+ areaString.add("0x0");
+ } else {
+ for (int areaId : areaIds) {
+ areaString.add("0x" + toHexString(areaId));
+ }
+ }
+
+ // Configure dropdown menu for propertyId spinner
+ ArrayAdapter<String> adapter =
+ new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item,
+ areaString);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mAreaId.setAdapter(adapter);
+ }
+
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Another interface callback
+ }
+}