1 /* 2 * Copyright (C) 2024 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.android.car.settings.applications.appinfo; 18 19 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_APP_DEFAULT; 20 21 import android.car.drivingstate.CarUxRestrictions; 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.os.RemoteException; 25 import android.os.UserHandle; 26 27 import androidx.preference.PreferenceGroup; 28 29 import com.android.car.settings.common.FragmentController; 30 import com.android.car.settings.common.Logger; 31 import com.android.car.settings.common.PreferenceController; 32 import com.android.car.settings.common.RadioWithImagePreference; 33 import com.android.internal.annotations.VisibleForTesting; 34 35 import com.google.common.collect.BiMap; 36 import com.google.common.collect.ImmutableBiMap; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 41 /** 42 * A PreferenceController handling the logic for selecting an aspect ratio. 43 */ 44 public class AppAspectRatiosGroupPreferenceController extends 45 PreferenceController<PreferenceGroup> implements RadioWithImagePreference.OnClickListener { 46 private static final Logger LOG = new Logger(AppAspectRatiosGroupPreferenceController.class); 47 private static final String KEY_PREF_DEFAULT = "app_default_pref"; 48 private static final String KEY_PREF_FULLSCREEN = "fullscreen_pref"; 49 private static final String KEY_PREF_HALF_SCREEN = "half_screen_pref"; 50 private static final String KEY_PREF_DISPLAY_SIZE = "display_size_pref"; 51 private static final String KEY_PREF_16_9 = "16_9_pref"; 52 private static final String KEY_PREF_4_3 = "4_3_pref"; 53 private static final String KEY_PREF_3_2 = "3_2_pref"; 54 private static final String KEY_ASPECT_RATIO_UNSET = "aspect_ratio_unset"; 55 private static final BiMap<String, Integer> KEY_TO_ASPECT_RATIO_MAP = ImmutableBiMap.of( 56 KEY_PREF_DEFAULT, PackageManager.USER_MIN_ASPECT_RATIO_APP_DEFAULT, 57 KEY_PREF_FULLSCREEN, PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN, 58 KEY_PREF_HALF_SCREEN, PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN, 59 KEY_PREF_DISPLAY_SIZE, PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE, 60 KEY_PREF_4_3, PackageManager.USER_MIN_ASPECT_RATIO_4_3, 61 KEY_PREF_16_9, PackageManager.USER_MIN_ASPECT_RATIO_16_9, 62 KEY_PREF_3_2, PackageManager.USER_MIN_ASPECT_RATIO_3_2, 63 KEY_ASPECT_RATIO_UNSET, PackageManager.USER_MIN_ASPECT_RATIO_UNSET 64 ); 65 private List<RadioWithImagePreference> mPreferenceList; 66 private String mSelectedKey = KEY_PREF_DEFAULT; 67 private String mPackageName; 68 private int mUserId; 69 private AspectRatioManager mAspectRatioManager; 70 AppAspectRatiosGroupPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions restrictionInfo)71 public AppAspectRatiosGroupPreferenceController(Context context, String preferenceKey, 72 FragmentController fragmentController, CarUxRestrictions restrictionInfo) { 73 super(context, preferenceKey, fragmentController, restrictionInfo); 74 mPreferenceList = new ArrayList<>(); 75 mUserId = UserHandle.myUserId(); 76 mAspectRatioManager = new AspectRatioManager(context); 77 } 78 79 /** 80 * Set the packageName, which is used to perform actions on a particular package. 81 */ setPackageName(String packageName)82 public AppAspectRatiosGroupPreferenceController setPackageName(String packageName) { 83 mPackageName = packageName; 84 return this; 85 } 86 87 @Override getPreferenceType()88 protected Class<PreferenceGroup> getPreferenceType() { 89 return PreferenceGroup.class; 90 } 91 92 @Override onCreateInternal()93 protected void onCreateInternal() { 94 int currentAspectRatio = PackageManager.USER_MIN_ASPECT_RATIO_UNSET; 95 try { 96 currentAspectRatio = mAspectRatioManager.getUserMinAspectRatioValue(mPackageName, 97 mUserId); 98 } catch (RemoteException e) { 99 LOG.d("There is an exception when trying to get the current aspect ratio: " + e); 100 } 101 mSelectedKey = KEY_TO_ASPECT_RATIO_MAP.inverse() 102 .getOrDefault(currentAspectRatio, KEY_ASPECT_RATIO_UNSET); 103 for (int i = 0; i < getPreference().getPreferenceCount(); i++) { 104 RadioWithImagePreference child = 105 (RadioWithImagePreference) getPreference().getPreference(i); 106 mPreferenceList.add(child); 107 child.setOnClickListener(this); 108 } 109 } 110 111 @Override updateState(PreferenceGroup preference)112 protected void updateState(PreferenceGroup preference) { 113 super.updateState(preference); 114 for (RadioWithImagePreference child : mPreferenceList) { 115 child.setChecked(child.getKey().equals(mSelectedKey)); 116 } 117 } 118 119 @Override onRadioButtonClicked(RadioWithImagePreference selected)120 public void onRadioButtonClicked(RadioWithImagePreference selected) { 121 String selectedKey = selected.getKey(); 122 if (selectedKey.equals(mSelectedKey)) { 123 return; 124 } 125 int userAspectRatio = KEY_TO_ASPECT_RATIO_MAP.getOrDefault(selectedKey, 126 USER_MIN_ASPECT_RATIO_APP_DEFAULT); 127 128 try { 129 getAspectRatioManager().setUserMinAspectRatio(mPackageName, mUserId, userAspectRatio); 130 mSelectedKey = selectedKey; 131 } catch (RemoteException e) { 132 LOG.e("Unable to set user min aspect ratio"); 133 return; 134 } 135 updateState(getPreference()); 136 } 137 138 @VisibleForTesting getAspectRatioManager()139 AspectRatioManager getAspectRatioManager() { 140 return mAspectRatioManager; 141 } 142 } 143