• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 package com.android.car.settings.units;
19 
20 import android.car.CarNotConnectedException;
21 import android.car.drivingstate.CarUxRestrictions;
22 import android.car.hardware.CarPropertyValue;
23 import android.car.hardware.property.CarPropertyManager;
24 import android.content.Context;
25 import android.text.BidiFormatter;
26 import android.text.TextDirectionHeuristics;
27 
28 import androidx.annotation.CallSuper;
29 import androidx.preference.ListPreference;
30 
31 import com.android.car.settings.R;
32 import com.android.car.settings.common.FragmentController;
33 import com.android.car.settings.common.PreferenceController;
34 import com.android.internal.annotations.VisibleForTesting;
35 
36 /**
37  * Shared business logic for preference controllers related to Units.
38  */
39 public abstract class UnitsBasePreferenceController extends PreferenceController<ListPreference> {
40 
41     @VisibleForTesting
42     protected final CarUnitsManager.OnCarServiceListener mOnCarServiceListener =
43             new CarUnitsManager.OnCarServiceListener() {
44                 @Override
45                 public void handleServiceConnected(CarPropertyManager carPropertyManager) {
46                     try {
47                         if (carPropertyManager != null) {
48                             carPropertyManager.registerCallback(mCarPropertyEventCallback,
49                                     getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
50                         }
51                         mSupportedUnits = mCarUnitsManager.getUnitsSupportedByProperty(
52                                 getPropertyId());
53                         if (mSupportedUnits != null && mSupportedUnits.length > 0) {
54                             // first element in the config array is the default Unit per VHAL spec.
55                             mDefaultUnit = mSupportedUnits[0];
56                             getPreference().setEntries(getEntriesOfSupportedUnits());
57                             getPreference().setEntryValues(getIdsOfSupportedUnits());
58                             getPreference().setValue(
59                                     Integer.toString(getUnitUsedByThisProperty().getId()));
60                             refreshUi();
61                         }
62 
63                         mIsCarUnitsManagerStarted = true;
64                     } catch (CarNotConnectedException e) {
65                     }
66                 }
67 
68                 @Override
69                 public void handleServiceDisconnected() {
70                     mIsCarUnitsManagerStarted = false;
71                 }
72             };
73 
74     @VisibleForTesting
75     protected final CarPropertyManager.CarPropertyEventCallback mCarPropertyEventCallback =
76             new CarPropertyManager.CarPropertyEventCallback() {
77                 @Override
78                 public void onChangeEvent(CarPropertyValue value) {
79                     if (value != null && value.getStatus() == CarPropertyValue.STATUS_AVAILABLE) {
80                         mUnitBeingUsed = UnitsMap.MAP.get(value.getValue());
81                         refreshUi();
82                     }
83                 }
84 
85                 @Override
86                 public void onErrorEvent(int propId, int zone) {
87                 }
88             };
89 
90     private Unit[] mSupportedUnits;
91     private Unit mUnitBeingUsed;
92     private Unit mDefaultUnit;
93     private boolean mIsCarUnitsManagerStarted = false;
94     private CarUnitsManager mCarUnitsManager;
95 
UnitsBasePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)96     public UnitsBasePreferenceController(Context context, String preferenceKey,
97             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
98         super(context, preferenceKey, fragmentController, uxRestrictions);
99     }
100 
101     @Override
102     @CallSuper
onCreateInternal()103     protected void onCreateInternal() {
104         super.onCreateInternal();
105         mCarUnitsManager = createCarUnitsManager();
106         mCarUnitsManager.registerCarServiceListener(mOnCarServiceListener);
107     }
108 
109     @Override
110     @CallSuper
onDestroyInternal()111     protected void onDestroyInternal() {
112         super.onDestroyInternal();
113         mCarUnitsManager.disconnect();
114         mCarUnitsManager.unregisterCarServiceListener();
115     }
116 
117     @Override
118     @CallSuper
updateState(ListPreference preference)119     protected void updateState(ListPreference preference) {
120         if (mIsCarUnitsManagerStarted && mUnitBeingUsed != null) {
121             preference.setSummary(generateSummaryFromUnit(mUnitBeingUsed));
122             preference.setValue(Integer.toString(mUnitBeingUsed.getId()));
123         }
124     }
125 
126     @Override
127     @CallSuper
handlePreferenceChanged(ListPreference preference, Object newValue)128     public boolean handlePreferenceChanged(ListPreference preference, Object newValue) {
129         int unitId = Integer.parseInt((String) newValue);
130         mCarUnitsManager.setUnitUsedByProperty(getPropertyId(), unitId);
131         return true;
132     }
133 
134     @Override
getAvailabilityStatus()135     protected int getAvailabilityStatus() {
136         return mSupportedUnits != null && mSupportedUnits.length > 0
137                 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
138     }
139 
getPropertyId()140     protected abstract int getPropertyId();
141 
getEntriesOfSupportedUnits()142     protected String[] getEntriesOfSupportedUnits() {
143         String[] names = new String[mSupportedUnits.length];
144         for (int i = 0; i < names.length; i++) {
145             Unit unit = mSupportedUnits[i];
146             names[i] = generateEntryStringFromUnit(unit);
147         }
148         return names;
149     }
150 
generateSummaryFromUnit(Unit unit)151     protected String generateSummaryFromUnit(Unit unit) {
152         return getContext().getString(unit.getAbbreviationResId());
153     }
154 
generateEntryStringFromUnit(Unit unit)155     protected String generateEntryStringFromUnit(Unit unit) {
156         return BidiFormatter.getInstance().unicodeWrap(
157                 getContext().getString(R.string.units_list_entry,
158                         getContext().getString(unit.getAbbreviationResId()),
159                         getContext().getString(unit.getNameResId())),
160                 TextDirectionHeuristics.LOCALE);
161     }
162 
getIdsOfSupportedUnits()163     protected String[] getIdsOfSupportedUnits() {
164         String[] ids = new String[mSupportedUnits.length];
165         for (int i = 0; i < ids.length; i++) {
166             ids[i] = Integer.toString(mSupportedUnits[i].getId());
167         }
168         return ids;
169     }
170 
getCarUnitsManager()171     protected CarUnitsManager getCarUnitsManager() {
172         return mCarUnitsManager;
173     }
174 
175     @VisibleForTesting
createCarUnitsManager()176     CarUnitsManager createCarUnitsManager() {
177         return new CarUnitsManager(getContext());
178     }
179 
getUnitUsedByThisProperty()180     private Unit getUnitUsedByThisProperty() {
181         Unit savedUnit = mCarUnitsManager.getUnitUsedByProperty(getPropertyId());
182         if (savedUnit == null) {
183             return mDefaultUnit;
184         }
185         return savedUnit;
186     }
187 
188 }
189