blob: 09fb35a385707a9be71d3a9a1dd45cab30bce70c [file] [log] [blame]
/*
* Copyright (C) 2020 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.car.systembar;
import android.content.Context;
import android.util.ArrayMap;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import com.android.car.ui.FocusParkingView;
import com.android.systemui.R;
import com.android.systemui.car.statusicon.ui.QuickControlsEntryPointsController;
import com.android.systemui.car.statusicon.ui.ReadOnlyIconsController;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
import javax.inject.Inject;
/** A factory that creates and caches views for navigation bars. */
@SysUISingleton
public class CarSystemBarViewFactory {
private static final String TAG = CarSystemBarViewFactory.class.getSimpleName();
private static final ArrayMap<Type, Integer> sLayoutMap = setupLayoutMapping();
private static ArrayMap<Type, Integer> setupLayoutMapping() {
ArrayMap<Type, Integer> map = new ArrayMap<>();
map.put(Type.TOP, R.layout.car_top_system_bar);
map.put(Type.TOP_UNPROVISIONED, R.layout.car_top_system_bar_unprovisioned);
map.put(Type.BOTTOM, R.layout.car_bottom_system_bar);
map.put(Type.BOTTOM_UNPROVISIONED, R.layout.car_bottom_system_bar_unprovisioned);
map.put(Type.LEFT, R.layout.car_left_system_bar);
map.put(Type.LEFT_UNPROVISIONED, R.layout.car_left_system_bar_unprovisioned);
map.put(Type.RIGHT, R.layout.car_right_system_bar);
map.put(Type.RIGHT_UNPROVISIONED, R.layout.car_right_system_bar_unprovisioned);
return map;
}
private final Context mContext;
private final ArrayMap<Type, CarSystemBarView> mCachedViewMap = new ArrayMap<>(
Type.values().length);
private final ArrayMap<Type, ViewGroup> mCachedContainerMap = new ArrayMap<>();
private final FeatureFlags mFeatureFlags;
private final QuickControlsEntryPointsController mQuickControlsEntryPointsController;
private final ReadOnlyIconsController mReadOnlyIconsController;
/** Type of navigation bar to be created. */
private enum Type {
TOP,
TOP_UNPROVISIONED,
BOTTOM,
BOTTOM_UNPROVISIONED,
LEFT,
LEFT_UNPROVISIONED,
RIGHT,
RIGHT_UNPROVISIONED
}
@Inject
public CarSystemBarViewFactory(
Context context,
FeatureFlags featureFlags,
QuickControlsEntryPointsController quickControlsEntryPointsController,
ReadOnlyIconsController readOnlyIconsController
) {
mContext = context;
mFeatureFlags = featureFlags;
mQuickControlsEntryPointsController = quickControlsEntryPointsController;
mReadOnlyIconsController = readOnlyIconsController;
}
/** Gets the top window. */
public ViewGroup getTopWindow() {
return getWindowCached(Type.TOP);
}
/** Gets the bottom window. */
public ViewGroup getBottomWindow() {
return getWindowCached(Type.BOTTOM);
}
/** Gets the left window. */
public ViewGroup getLeftWindow() {
return getWindowCached(Type.LEFT);
}
/** Gets the right window. */
public ViewGroup getRightWindow() {
return getWindowCached(Type.RIGHT);
}
/** Gets the top bar. */
public CarSystemBarView getTopBar(boolean isSetUp) {
return getBar(isSetUp, Type.TOP, Type.TOP_UNPROVISIONED);
}
/** Gets the bottom bar. */
public CarSystemBarView getBottomBar(boolean isSetUp) {
return getBar(isSetUp, Type.BOTTOM, Type.BOTTOM_UNPROVISIONED);
}
/** Gets the left bar. */
public CarSystemBarView getLeftBar(boolean isSetUp) {
return getBar(isSetUp, Type.LEFT, Type.LEFT_UNPROVISIONED);
}
/** Gets the right bar. */
public CarSystemBarView getRightBar(boolean isSetUp) {
return getBar(isSetUp, Type.RIGHT, Type.RIGHT_UNPROVISIONED);
}
private ViewGroup getWindowCached(Type type) {
if (mCachedContainerMap.containsKey(type)) {
return mCachedContainerMap.get(type);
}
ViewGroup window = (ViewGroup) View.inflate(mContext,
R.layout.navigation_bar_window, /* root= */ null);
mCachedContainerMap.put(type, window);
return mCachedContainerMap.get(type);
}
private CarSystemBarView getBar(boolean isSetUp, Type provisioned, Type unprovisioned) {
CarSystemBarView view = getBarCached(isSetUp, provisioned, unprovisioned);
if (view == null) {
String name = isSetUp ? provisioned.name() : unprovisioned.name();
Log.e(TAG, "CarStatusBar failed inflate for " + name);
throw new RuntimeException(
"Unable to build " + name + " nav bar due to missing layout");
}
return view;
}
private CarSystemBarView getBarCached(boolean isSetUp, Type provisioned, Type unprovisioned) {
Type type = isSetUp ? provisioned : unprovisioned;
if (mCachedViewMap.containsKey(type)) {
return mCachedViewMap.get(type);
}
@LayoutRes int barLayout = sLayoutMap.get(type);
CarSystemBarView view = (CarSystemBarView) View.inflate(mContext, barLayout,
/* root= */ null);
view.setupHvacButton();
view.setupQuickControlsEntryPoints(mQuickControlsEntryPointsController, isSetUp);
view.setupReadOnlyIcons(mReadOnlyIconsController);
// Include a FocusParkingView at the beginning. The rotary controller "parks" the focus here
// when the user navigates to another window. This is also used to prevent wrap-around.
view.addView(new FocusParkingView(mContext), 0);
mCachedViewMap.put(type, view);
return mCachedViewMap.get(type);
}
/** Gets the selected Quick Controls class name. */
protected String getSelectedQuickControlsClassName() {
return mQuickControlsEntryPointsController.getClassNameOfSelectedView();
}
/** Calls onClick for the given Quick Controls class name. */
protected void callQuickControlsOnClickFromClassName(String clsName) {
View statusIconView = mQuickControlsEntryPointsController.getViewFromClassName(clsName);
if (statusIconView != null) {
statusIconView.callOnClick();
}
}
/** Resets the cached Views. */
protected void resetCache() {
mQuickControlsEntryPointsController.resetCache();
mReadOnlyIconsController.resetCache();
mCachedViewMap.clear();
}
}