1 /*
2  * Copyright (C) 2019 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.vehiclectrl;
18 
19 import android.annotation.IdRes;
20 import android.annotation.Nullable;
21 import android.annotation.SuppressLint;
22 import android.car.VehicleAreaWindow;
23 import android.car.VehiclePropertyIds;
24 import android.car.hardware.CarPropertyValue;
25 import android.car.hardware.property.CarPropertyManager;
26 import android.hardware.automotive.vehicle.V2_0.VehicleArea;
27 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup;
28 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType;
29 import android.os.Bundle;
30 import android.util.Log;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.TextView;
35 
36 import androidx.fragment.app.Fragment;
37 import androidx.viewpager.widget.ViewPager;
38 
39 import com.google.android.car.kitchensink.KitchenSinkActivity;
40 import com.google.android.car.kitchensink.R;
41 import com.google.android.car.kitchensink.SimplePagerAdapter;
42 
43 import java.util.HashMap;
44 import java.util.Map;
45 
46 @SuppressLint("SetTextI18n")
47 public final class VehicleCtrlFragment extends Fragment {
48     private static final String TAG = VehicleCtrlFragment.class.getSimpleName();
49 
50     public static final class CustomVehicleProperty {
51         public static final int PROTOCAN_TEST = (
52                 0x0ABC
53                 | VehiclePropertyGroup.VENDOR
54                 | VehiclePropertyType.BOOLEAN
55                 | VehicleArea.GLOBAL);
56 
CustomVehicleProperty()57         private CustomVehicleProperty() {}
58     };
59 
60     private CarPropertyManager mPropMgr;
61     private final Map<Integer, TextView> mWindowPosWidgets = new HashMap<>();
62 
63     private final CarPropertyManager.CarPropertyEventCallback mPropCb =
64             new CarPropertyManager.CarPropertyEventCallback() {
65         @Override
66         public void onChangeEvent(CarPropertyValue value) {
67             onPropertyEvent(value);
68         }
69 
70         @Override
71         public void onErrorEvent(int propId, int zone) {}
72     };
73 
74     @Override
onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)75     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
76             @Nullable Bundle savedInstanceState) {
77         View view = inflater.inflate(R.layout.vehicle_ctrl_fragment, container, false);
78 
79         ViewPager pager = view.findViewById(R.id.vehicle_ctrl_pager);
80         pager.setAdapter(new SimplePagerAdapter(pager));
81 
82         KitchenSinkActivity activity = (KitchenSinkActivity) getHost();
83         mPropMgr = activity.getPropertyManager();
84 
85         subscribeProps();
86 
87         initWindowBtns(view, VehicleAreaWindow.WINDOW_ROW_1_LEFT,
88                 R.id.winFLOpen, R.id.winFLClose, R.id.winFLPos);
89         initWindowBtns(view, VehicleAreaWindow.WINDOW_ROW_1_RIGHT,
90                 R.id.winFROpen, R.id.winFRClose, R.id.winFRPos);
91         initWindowBtns(view, VehicleAreaWindow.WINDOW_ROW_2_LEFT,
92                 R.id.winRLOpen, R.id.winRLClose, R.id.winRLPos);
93         initWindowBtns(view, VehicleAreaWindow.WINDOW_ROW_2_RIGHT,
94                 R.id.winRROpen, R.id.winRRClose, R.id.winRRPos);
95 
96         initTestBtn(view, R.id.protocan_test_on, true);
97         initTestBtn(view, R.id.protocan_test_off, false);
98 
99         return view;
100     }
101 
102     @Override
onDestroyView()103     public void onDestroyView() {
104         super.onDestroyView();
105         unsubscribeProps();
106     }
107 
subscribeProps()108     private void subscribeProps() {
109         mPropMgr.registerCallback(mPropCb, VehiclePropertyIds.WINDOW_POS, 10);
110     }
111 
unsubscribeProps()112     private void unsubscribeProps() {
113         mPropMgr.unregisterCallback(mPropCb);
114     }
115 
onPropertyEvent(CarPropertyValue prop)116     public void onPropertyEvent(CarPropertyValue prop) {
117         if (prop.getPropertyId() == VehiclePropertyIds.WINDOW_POS) {
118             Log.i(TAG, "Window pos: " + prop.getValue());
119             updateWindowPos(prop.getAreaId(), (int) prop.getValue());
120         }
121     }
122 
initWindowBtns(View view, int winId, @IdRes int openId, @IdRes int closeId, @IdRes int posId)123     private void initWindowBtns(View view, int winId, @IdRes int openId, @IdRes int closeId,
124             @IdRes int posId) {
125         // TODO(twasilczyk): fetch the actual min/max values
126         view.findViewById(openId).setOnClickListener(v -> moveWindow(winId, 1));
127         view.findViewById(closeId).setOnClickListener(v -> moveWindow(winId, -1));
128         mWindowPosWidgets.put(winId, view.findViewById(posId));
129     }
130 
moveWindow(int windowId, int speed)131     private void moveWindow(int windowId, int speed) {
132         Log.i(TAG, "Moving window " + windowId + " with speed " + speed);
133         mPropMgr.setIntProperty(VehiclePropertyIds.WINDOW_MOVE, windowId, speed);
134     }
135 
updateWindowPos(int windowId, int pos)136     private void updateWindowPos(int windowId, int pos) {
137         TextView view = mWindowPosWidgets.get(windowId);
138         view.post(() -> view.setText(pos + "%"));
139     }
140 
initTestBtn(View view, @IdRes int btnId, boolean on)141     private void initTestBtn(View view, @IdRes int btnId, boolean on) {
142         view.findViewById(btnId).setOnClickListener(v -> onTestBtnClicked(on));
143     }
144 
onTestBtnClicked(boolean on)145     private void onTestBtnClicked(boolean on) {
146         Log.i(TAG, "onTestBtnClicked " + on);
147         mPropMgr.setBooleanProperty(CustomVehicleProperty.PROTOCAN_TEST, VehicleArea.GLOBAL, on);
148     }
149 }
150