/* * Copyright (C) 2019 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.android.car.settings.units; import android.car.CarNotConnectedException; import android.car.drivingstate.CarUxRestrictions; import android.car.hardware.CarPropertyValue; import android.car.hardware.property.CarPropertyManager; import android.content.Context; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import androidx.annotation.CallSuper; import androidx.preference.ListPreference; import com.android.car.settings.R; import com.android.car.settings.common.FragmentController; import com.android.car.settings.common.PreferenceController; import com.android.internal.annotations.VisibleForTesting; /** * Shared business logic for preference controllers related to Units. */ public abstract class UnitsBasePreferenceController extends PreferenceController { @VisibleForTesting protected final CarUnitsManager.OnCarServiceListener mOnCarServiceListener = new CarUnitsManager.OnCarServiceListener() { @Override public void handleServiceConnected(CarPropertyManager carPropertyManager) { try { if (carPropertyManager != null) { carPropertyManager.registerCallback(mCarPropertyEventCallback, getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE); } mSupportedUnits = mCarUnitsManager.getUnitsSupportedByProperty( getPropertyId()); if (mSupportedUnits != null && mSupportedUnits.length > 0) { // first element in the config array is the default Unit per VHAL spec. mDefaultUnit = mSupportedUnits[0]; getPreference().setEntries(getEntriesOfSupportedUnits()); getPreference().setEntryValues(getIdsOfSupportedUnits()); getPreference().setValue( Integer.toString(getUnitUsedByThisProperty().getId())); refreshUi(); } mIsCarUnitsManagerStarted = true; } catch (CarNotConnectedException e) { } } @Override public void handleServiceDisconnected() { mIsCarUnitsManagerStarted = false; } }; @VisibleForTesting protected final CarPropertyManager.CarPropertyEventCallback mCarPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() { @Override public void onChangeEvent(CarPropertyValue value) { if (value != null && value.getStatus() == CarPropertyValue.STATUS_AVAILABLE) { mUnitBeingUsed = UnitsMap.MAP.get(value.getValue()); refreshUi(); } } @Override public void onErrorEvent(int propId, int zone) { } }; private Unit[] mSupportedUnits; private Unit mUnitBeingUsed; private Unit mDefaultUnit; private boolean mIsCarUnitsManagerStarted = false; private CarUnitsManager mCarUnitsManager; public UnitsBasePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions) { super(context, preferenceKey, fragmentController, uxRestrictions); } @Override @CallSuper protected void onCreateInternal() { super.onCreateInternal(); mCarUnitsManager = createCarUnitsManager(); mCarUnitsManager.registerCarServiceListener(mOnCarServiceListener); } @Override @CallSuper protected void onDestroyInternal() { super.onDestroyInternal(); mCarUnitsManager.disconnect(); mCarUnitsManager.unregisterCarServiceListener(); } @Override @CallSuper protected void updateState(ListPreference preference) { if (mIsCarUnitsManagerStarted && mUnitBeingUsed != null) { preference.setSummary(generateSummaryFromUnit(mUnitBeingUsed)); preference.setValue(Integer.toString(mUnitBeingUsed.getId())); } } @Override @CallSuper public boolean handlePreferenceChanged(ListPreference preference, Object newValue) { int unitId = Integer.parseInt((String) newValue); mCarUnitsManager.setUnitUsedByProperty(getPropertyId(), unitId); return true; } @Override protected int getAvailabilityStatus() { return mSupportedUnits != null && mSupportedUnits.length > 0 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } protected abstract int getPropertyId(); protected String[] getEntriesOfSupportedUnits() { String[] names = new String[mSupportedUnits.length]; for (int i = 0; i < names.length; i++) { Unit unit = mSupportedUnits[i]; names[i] = generateEntryStringFromUnit(unit); } return names; } protected String generateSummaryFromUnit(Unit unit) { return getContext().getString(unit.getAbbreviationResId()); } protected String generateEntryStringFromUnit(Unit unit) { return BidiFormatter.getInstance().unicodeWrap( getContext().getString(R.string.units_list_entry, getContext().getString(unit.getAbbreviationResId()), getContext().getString(unit.getNameResId())), TextDirectionHeuristics.LOCALE); } protected String[] getIdsOfSupportedUnits() { String[] ids = new String[mSupportedUnits.length]; for (int i = 0; i < ids.length; i++) { ids[i] = Integer.toString(mSupportedUnits[i].getId()); } return ids; } protected CarUnitsManager getCarUnitsManager() { return mCarUnitsManager; } @VisibleForTesting CarUnitsManager createCarUnitsManager() { return new CarUnitsManager(getContext()); } private Unit getUnitUsedByThisProperty() { Unit savedUnit = mCarUnitsManager.getUnitUsedByProperty(getPropertyId()); if (savedUnit == null) { return mDefaultUnit; } return savedUnit; } }