Fix constantly spinning hvac views
Also clean up some things w.r.t. CarFacetButtonController Bug: 143610340 Test: manual, atest HvacControllerTest Change-Id: Idca6f5731704da893fb530deefe2e695281c6f60
This commit is contained in:
@@ -19,36 +19,16 @@ package com.android.systemui;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.systemui.dagger.SystemUIRootComponent;
|
||||
import com.android.systemui.navigationbar.car.CarFacetButtonController;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Component;
|
||||
|
||||
/**
|
||||
* Class factory to provide car specific SystemUI components.
|
||||
*/
|
||||
public class CarSystemUIFactory extends SystemUIFactory {
|
||||
|
||||
private CarDependencyComponent mCarDependencyComponent;
|
||||
|
||||
@Override
|
||||
protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
|
||||
mCarDependencyComponent = DaggerCarSystemUIFactory_CarDependencyComponent.builder()
|
||||
.contextHolder(new ContextHolder(context))
|
||||
.build();
|
||||
return DaggerCarSystemUIRootComponent.builder()
|
||||
.contextHolder(new ContextHolder(context))
|
||||
.build();
|
||||
}
|
||||
|
||||
public CarDependencyComponent getCarDependencyComponent() {
|
||||
return mCarDependencyComponent;
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Component(modules = ContextHolder.class)
|
||||
public interface CarDependencyComponent {
|
||||
CarFacetButtonController getCarFacetButtonController();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.systemui.car;
|
||||
import android.car.Car;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -50,6 +52,12 @@ public class CarServiceProvider {
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public CarServiceProvider(Context context, Car car) {
|
||||
mContext = context;
|
||||
mCar = car;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's other components hook into the connection to the car service. If we're already
|
||||
* connected to the car service, the callback is immediately triggered.
|
||||
|
||||
@@ -29,9 +29,7 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.keyguard.AlphaOptimizedImageButton;
|
||||
import com.android.systemui.CarSystemUIFactory;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUIFactory;
|
||||
|
||||
/**
|
||||
* CarFacetButton is a ui component designed to be used as a shortcut for an app of a defined
|
||||
@@ -82,10 +80,6 @@ public class CarFacetButton extends LinearLayout {
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarFacetButton);
|
||||
setupIntents(typedArray);
|
||||
setupIcons(typedArray);
|
||||
CarSystemUIFactory factory = SystemUIFactory.getInstance();
|
||||
CarFacetButtonController carFacetButtonController = factory.getCarDependencyComponent()
|
||||
.getCarFacetButtonController();
|
||||
carFacetButtonController.addFacetButton(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,6 +43,8 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class CarFacetButtonController {
|
||||
|
||||
private final Set<CarFacetButton> mRegisteredViews = new HashSet<>();
|
||||
|
||||
protected ButtonMap mButtonsByCategory = new ButtonMap();
|
||||
protected ButtonMap mButtonsByPackage = new ButtonMap();
|
||||
protected ButtonMap mButtonsByComponentName = new ButtonMap();
|
||||
@@ -60,7 +62,11 @@ public class CarFacetButtonController {
|
||||
* to get a reference to this controller via {@link com.android.systemui.Dependency}
|
||||
* and self add.
|
||||
*/
|
||||
public void addFacetButton(CarFacetButton facetButton) {
|
||||
private void addFacetButton(CarFacetButton facetButton) {
|
||||
if (mRegisteredViews.contains(facetButton)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] categories = facetButton.getCategories();
|
||||
for (int i = 0; i < categories.length; i++) {
|
||||
mButtonsByCategory.add(categories[i], facetButton);
|
||||
@@ -74,6 +80,8 @@ public class CarFacetButtonController {
|
||||
for (int i = 0; i < componentNames.length; i++) {
|
||||
mButtonsByComponentName.add(componentNames[i], facetButton);
|
||||
}
|
||||
|
||||
mRegisteredViews.add(facetButton);
|
||||
}
|
||||
|
||||
/** Removes all buttons from the button maps. */
|
||||
@@ -82,6 +90,7 @@ public class CarFacetButtonController {
|
||||
mButtonsByPackage.clear();
|
||||
mButtonsByComponentName.clear();
|
||||
mSelectedFacetButtons.clear();
|
||||
mRegisteredViews.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,10 +32,12 @@ import com.android.systemui.car.CarServiceProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -49,6 +51,7 @@ public class HvacController {
|
||||
public static final String TAG = "HvacController";
|
||||
|
||||
private final CarServiceProvider mCarServiceProvider;
|
||||
private final Set<TemperatureView> mRegisteredViews = new HashSet<>();
|
||||
|
||||
private CarHvacManager mHvacManager;
|
||||
private HashMap<HvacKey, List<TemperatureView>> mTempComponents = new HashMap<>();
|
||||
@@ -112,7 +115,10 @@ public class HvacController {
|
||||
/**
|
||||
* Add component to list and initialize it if the connection is up.
|
||||
*/
|
||||
public void addHvacTextView(TemperatureView temperatureView) {
|
||||
private void addHvacTextView(TemperatureView temperatureView) {
|
||||
if (mRegisteredViews.contains(temperatureView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HvacKey hvacKey = new HvacKey(temperatureView.getPropertyId(), temperatureView.getAreaId());
|
||||
if (!mTempComponents.containsKey(hvacKey)) {
|
||||
@@ -120,6 +126,8 @@ public class HvacController {
|
||||
}
|
||||
mTempComponents.get(hvacKey).add(temperatureView);
|
||||
initComponent(temperatureView);
|
||||
|
||||
mRegisteredViews.add(temperatureView);
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
@@ -165,6 +173,7 @@ public class HvacController {
|
||||
*/
|
||||
public void removeAllComponents() {
|
||||
mTempComponents.clear();
|
||||
mRegisteredViews.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.systemui.navigationbar.car.hvac;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.car.Car;
|
||||
import android.car.hardware.hvac.CarHvacManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.car.CarServiceProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
@SmallTest
|
||||
public class HvacControllerTest extends SysuiTestCase {
|
||||
|
||||
private static final int PROPERTY_ID = 1;
|
||||
private static final int AREA_ID = 1;
|
||||
private static final float VALUE = 72.0f;
|
||||
|
||||
private HvacController mHvacController;
|
||||
private CarServiceProvider mCarServiceProvider;
|
||||
|
||||
@Mock
|
||||
private Car mCar;
|
||||
@Mock
|
||||
private CarHvacManager mCarHvacManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mCar.isConnected()).thenReturn(true);
|
||||
when(mCar.getCarManager(Car.HVAC_SERVICE)).thenReturn(mCarHvacManager);
|
||||
|
||||
mCarServiceProvider = new CarServiceProvider(mContext, mCar);
|
||||
mHvacController = new HvacController(mCarServiceProvider);
|
||||
mHvacController.connectToCarService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectToCarService_registersCallback() {
|
||||
verify(mCarHvacManager).registerCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addTemperatureViewToController_usingTemperatureView_registersView() {
|
||||
TemperatureTextView v = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE);
|
||||
mHvacController.addTemperatureViewToController(v);
|
||||
|
||||
verify(v).setTemp(VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addTemperatureViewToController_usingSameTemperatureView_registersFirstView() {
|
||||
TemperatureTextView v = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE);
|
||||
mHvacController.addTemperatureViewToController(v);
|
||||
verify(v).setTemp(VALUE);
|
||||
resetTemperatureView(v, PROPERTY_ID, AREA_ID);
|
||||
|
||||
mHvacController.addTemperatureViewToController(v);
|
||||
verify(v, never()).setTemp(VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addTemperatureViewToController_usingDifferentTemperatureView_registersBothViews() {
|
||||
TemperatureTextView v1 = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE);
|
||||
mHvacController.addTemperatureViewToController(v1);
|
||||
verify(v1).setTemp(VALUE);
|
||||
|
||||
TemperatureTextView v2 = setupMockTemperatureTextView(
|
||||
PROPERTY_ID + 1,
|
||||
AREA_ID + 1,
|
||||
VALUE + 1);
|
||||
mHvacController.addTemperatureViewToController(v2);
|
||||
verify(v2).setTemp(VALUE + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeAllComponents_ableToRegisterSameView() {
|
||||
TemperatureTextView v = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE);
|
||||
mHvacController.addTemperatureViewToController(v);
|
||||
verify(v).setTemp(VALUE);
|
||||
|
||||
mHvacController.removeAllComponents();
|
||||
resetTemperatureView(v, PROPERTY_ID, AREA_ID);
|
||||
|
||||
mHvacController.addTemperatureViewToController(v);
|
||||
verify(v).setTemp(VALUE);
|
||||
}
|
||||
|
||||
private TemperatureTextView setupMockTemperatureTextView(int propertyId, int areaId,
|
||||
float value) {
|
||||
TemperatureTextView v = mock(TemperatureTextView.class);
|
||||
resetTemperatureView(v, propertyId, areaId);
|
||||
when(mCarHvacManager.isPropertyAvailable(propertyId, areaId)).thenReturn(true);
|
||||
when(mCarHvacManager.getFloatProperty(propertyId, areaId)).thenReturn(value);
|
||||
return v;
|
||||
}
|
||||
|
||||
private void resetTemperatureView(TemperatureTextView view, int propertyId, int areaId) {
|
||||
reset(view);
|
||||
when(view.getPropertyId()).thenReturn(propertyId);
|
||||
when(view.getAreaId()).thenReturn(areaId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user