• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.car.kitchensink.property;
18 
19 import static java.lang.Integer.toHexString;
20 
21 import android.car.VehiclePropertyIds;
22 import android.car.hardware.CarPropertyConfig;
23 import android.car.hardware.CarPropertyValue;
24 import android.car.hardware.property.CarPropertyManager;
25 import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
26 import android.content.Context;
27 import android.util.Log;
28 import android.util.SparseArray;
29 import android.util.SparseIntArray;
30 import android.util.SparseLongArray;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.AdapterView;
35 import android.widget.ArrayAdapter;
36 import android.widget.BaseAdapter;
37 import android.widget.ListAdapter;
38 import android.widget.ScrollView;
39 import android.widget.Spinner;
40 import android.widget.TextView;
41 
42 import com.google.android.car.kitchensink.R;
43 
44 import java.util.List;
45 
46 class PropertyListAdapter extends BaseAdapter implements ListAdapter {
47     private static final float DEFAULT_RATE = 1f;
48     private static final String TAG = "PropertyListAdapter";
49     private static final String OFF = "Off";
50     private static final String ON = "On";
51     private static final String MAX_SAMPLE_RATE = "Maximum sample rate";
52     private static final String AVG_SAMPLE_RATE = "Average sample rate";
53     private static final String[] DROP_MENU_FOR_CONTINUOUS =
54             new String[]{OFF, MAX_SAMPLE_RATE, AVG_SAMPLE_RATE};
55     private static final String[] DROP_MENU_FOR_ON_CHANGE = new String[]{OFF, ON};
56     private final Context mContext;
57     private final PropertyListEventListener mListener;
58     private final CarPropertyManager mMgr;
59     private final List<PropertyInfo> mPropInfo;
60     private final TextView mTvEventLog;
61     private String[] mItems;
62 
PropertyListAdapter(List<PropertyInfo> propInfo, CarPropertyManager mgr, TextView eventLog, ScrollView svEventLog, Context context)63     PropertyListAdapter(List<PropertyInfo> propInfo, CarPropertyManager mgr, TextView eventLog,
64             ScrollView svEventLog, Context context) {
65         mContext = context;
66         mListener = new PropertyListEventListener(eventLog, svEventLog);
67         mMgr = mgr;
68         mPropInfo = propInfo;
69         mTvEventLog = eventLog;
70     }
71 
72     @Override
getCount()73     public int getCount() {
74         return mPropInfo.size();
75     }
76 
77     @Override
getItem(int pos)78     public Object getItem(int pos) {
79         return mPropInfo.get(pos);
80     }
81 
82     @Override
getItemId(int pos)83     public long getItemId(int pos) {
84         return mPropInfo.get(pos).mPropId;
85     }
86 
87     @Override
getView(final int position, View convertView, ViewGroup parent)88     public View getView(final int position, View convertView, ViewGroup parent) {
89         View view = convertView;
90         if (view == null) {
91             LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
92                     Context.LAYOUT_INFLATER_SERVICE);
93             view = inflater.inflate(R.layout.property_list_item, null);
94         }
95 
96         //Handle TextView and display string from your list
97         TextView listItemText = (TextView) view.findViewById(R.id.tvPropertyName);
98         listItemText.setText(mPropInfo.get(position).toString());
99 
100         Spinner dropdown = view.findViewById(R.id.tbRegisterPropertySpinner);
101 
102         CarPropertyConfig c = mPropInfo.get(position).mConfig;
103         if (c.getChangeMode() == CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) {
104             mItems = DROP_MENU_FOR_CONTINUOUS;
105         } else {
106             mItems = DROP_MENU_FOR_ON_CHANGE;
107         }
108         ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,
109                 R.layout.custom_spinner_dropdown_item, mItems);
110 
111         adapter.setDropDownViewResource(R.layout.custom_spinner_dropdown_item);
112         dropdown.setAdapter(adapter);
113         dropdown.setSelection(0);
114         dropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
115             @Override
116             public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) {
117                 String item = (String) adapterView.getItemAtPosition(pos);
118                 CarPropertyConfig c = mPropInfo.get(position).mConfig;
119                 int propId = c.getPropertyId();
120                 try {
121                     if (OFF.equals(item)) {
122                         mMgr.unregisterCallback(mListener, propId);
123                     } else if (MAX_SAMPLE_RATE.equals(item)) {
124                         mListener.addPropertySelectedSampleRate(propId, c.getMaxSampleRate());
125                         mListener.updatePropertyStartTime(propId);
126                         mListener.resetEventCountForProperty(propId);
127                         mMgr.registerCallback(mListener, propId, c.getMaxSampleRate());
128                     } else if (AVG_SAMPLE_RATE.equals(item)) {
129                         mListener.addPropertySelectedSampleRate(propId,
130                                 (c.getMaxSampleRate() + c.getMinSampleRate()) / 2);
131                         mListener.updatePropertyStartTime(propId);
132                         mListener.resetEventCountForProperty(propId);
133                         mMgr.registerCallback(mListener, propId,
134                                 (c.getMaxSampleRate() + c.getMinSampleRate()) / 2);
135                     } else if (ON.equals(item)) {
136                         mListener.addPropertySelectedSampleRate(propId,
137                                 DEFAULT_RATE);
138                         mListener.updatePropertyStartTime(propId);
139                         mListener.resetEventCountForProperty(propId);
140                         mMgr.registerCallback(mListener, propId, DEFAULT_RATE);
141                     }
142                 } catch (Exception e) {
143                     Log.e(TAG, "Unhandled exception: ", e);
144                 }
145             }
146 
147             @Override
148             public void onNothingSelected(AdapterView<?> adapterView) {
149                 // do nothing.
150             }
151         });
152         return view;
153     }
154 
155 
156     private static class PropertyListEventListener implements CarPropertyEventCallback {
157         private final ScrollView mScrollView;
158         private final TextView mTvLogEvent;
159         private final SparseArray<Float> mPropSampleRate = new SparseArray<>();
160         private final SparseLongArray mStartTime = new SparseLongArray();
161         private final SparseIntArray mNumEvents = new SparseIntArray();
162 
PropertyListEventListener(TextView logEvent, ScrollView scrollView)163         PropertyListEventListener(TextView logEvent, ScrollView scrollView) {
164             mScrollView = scrollView;
165             mTvLogEvent = logEvent;
166         }
167 
addPropertySelectedSampleRate(Integer propId, Float sampleRate)168         void addPropertySelectedSampleRate(Integer propId, Float sampleRate) {
169             mPropSampleRate.put(propId, sampleRate);
170         }
171 
updatePropertyStartTime(Integer propId)172         void updatePropertyStartTime(Integer propId) {
173             mStartTime.put(propId, System.currentTimeMillis());
174         }
175 
resetEventCountForProperty(Integer propId)176         void resetEventCountForProperty(Integer propId) {
177             mNumEvents.put(propId, 0);
178         }
179 
180         @Override
onChangeEvent(CarPropertyValue value)181         public void onChangeEvent(CarPropertyValue value) {
182             int propId = value.getPropertyId();
183 
184             mNumEvents.put(propId, mNumEvents.get(propId) + 1);
185             mTvLogEvent.append(String.format("Event %1$s: time=%2$s propId=0x%3$s areaId=0x%3$s "
186                             + "name=%4$s status=%5$s value=%6$s", mNumEvents.get(propId),
187                     value.getTimestamp(), toHexString(propId), VehiclePropertyIds.toString(propId),
188                     value.getStatus(), value.getValue()));
189             if (mPropSampleRate.contains(propId)) {
190                 mTvLogEvent.append(
191                         String.format(" selected sample rate=%1$s actual sample rate=%2$s\n",
192                                 mPropSampleRate.get(propId),
193                                 mNumEvents.get(propId) / (System.currentTimeMillis()
194                                         - mStartTime.get(propId))));
195             } else {
196                 mTvLogEvent.append("\n");
197             }
198             scrollToBottom();
199         }
200 
201         @Override
onErrorEvent(int propId, int areaId)202         public void onErrorEvent(int propId, int areaId) {
203             mTvLogEvent.append("Received error event propId=0x" + toHexString(propId)
204                     + ", areaId=0x" + toHexString(areaId));
205             scrollToBottom();
206         }
207 
scrollToBottom()208         private void scrollToBottom() {
209             mScrollView.post(new Runnable() {
210                 public void run() {
211                     mScrollView.fullScroll(View.FOCUS_DOWN);
212                     //mScrollView.smoothScrollTo(0, mTextStatus.getBottom());
213                 }
214             });
215         }
216 
217     }
218 }
219