RecentsConfiguration.java revision 7ab650cb43fc75786eadfc1c3f8eae8a358723f6
1/* 2 * Copyright (C) 2014 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 17package com.android.systemui.recents; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.content.SharedPreferences; 22import android.content.res.Configuration; 23import android.content.res.Resources; 24import android.graphics.Rect; 25import android.provider.Settings; 26import android.util.DisplayMetrics; 27import android.util.TypedValue; 28import android.view.animation.AnimationUtils; 29import android.view.animation.Interpolator; 30import com.android.systemui.R; 31 32 33/** A static Recents configuration for the current context 34 * NOTE: We should not hold any references to a Context from a static instance */ 35public class RecentsConfiguration { 36 static RecentsConfiguration sInstance; 37 38 DisplayMetrics mDisplayMetrics; 39 40 /** Animations */ 41 public float animationPxMovementPerSecond; 42 43 /** Interpolators */ 44 public Interpolator fastOutSlowInInterpolator; 45 public Interpolator fastOutLinearInInterpolator; 46 public Interpolator linearOutSlowInInterpolator; 47 public Interpolator quintOutInterpolator; 48 49 /** Filtering */ 50 public int filteringCurrentViewsAnimDuration; 51 public int filteringNewViewsAnimDuration; 52 53 /** Insets */ 54 public Rect systemInsets = new Rect(); 55 public Rect displayRect = new Rect(); 56 57 /** Layout */ 58 boolean isLandscape; 59 boolean transposeRecentsLayoutWithOrientation; 60 61 /** Search bar */ 62 int searchBarAppWidgetId = -1; 63 public int searchBarSpaceHeightPx; 64 65 /** Task stack */ 66 public int taskStackMaxDim; 67 public int taskStackTopPaddingPx; 68 public float taskStackWidthPaddingPct; 69 70 /** Task view animation and styles */ 71 public int taskViewEnterFromHomeDuration; 72 public int taskViewEnterFromHomeDelay; 73 public int taskViewExitToHomeDuration; 74 public int taskViewRemoveAnimDuration; 75 public int taskViewRemoveAnimTranslationXPx; 76 public int taskViewTranslationZMinPx; 77 public int taskViewTranslationZIncrementPx; 78 public int taskViewShadowOutlineBottomInsetPx; 79 public int taskViewRoundedCornerRadiusPx; 80 public int taskViewHighlightPx; 81 82 /** Task bar colors */ 83 public int taskBarViewDefaultBackgroundColor; 84 public int taskBarViewLightTextColor; 85 public int taskBarViewDarkTextColor; 86 public int taskBarViewHighlightColor; 87 88 /** Task bar animations */ 89 public int taskBarEnterAnimDuration; 90 public int taskBarEnterAnimDelay; 91 public int taskBarExitAnimDuration; 92 public int taskBarDismissDozeDelaySeconds; 93 94 /** Nav bar scrim */ 95 public int navBarScrimEnterDuration; 96 97 /** Launch states */ 98 public boolean launchedWithAltTab; 99 public boolean launchedWithNoRecentTasks; 100 public boolean launchedFromAppWithThumbnail; 101 public boolean launchedFromAppWithScreenshot; 102 public boolean launchedFromHome; 103 104 /** Dev options */ 105 public boolean developerOptionsEnabled; 106 107 /** Private constructor */ 108 private RecentsConfiguration(Context context) { 109 // Properties that don't have to be reloaded with each configuration change can be loaded 110 // here. 111 112 // Interpolators 113 fastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, 114 com.android.internal.R.interpolator.fast_out_slow_in); 115 fastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context, 116 com.android.internal.R.interpolator.fast_out_linear_in); 117 linearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, 118 com.android.internal.R.interpolator.linear_out_slow_in); 119 quintOutInterpolator = AnimationUtils.loadInterpolator(context, 120 com.android.internal.R.interpolator.decelerate_quint); 121 122 // Check if the developer options are enabled 123 ContentResolver cr = context.getContentResolver(); 124 developerOptionsEnabled = Settings.Global.getInt(cr, 125 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; 126 } 127 128 /** Updates the configuration to the current context */ 129 public static RecentsConfiguration reinitialize(Context context) { 130 if (sInstance == null) { 131 sInstance = new RecentsConfiguration(context); 132 } 133 sInstance.update(context); 134 return sInstance; 135 } 136 137 /** Returns the current recents configuration */ 138 public static RecentsConfiguration getInstance() { 139 return sInstance; 140 } 141 142 /** Updates the state, given the specified context */ 143 void update(Context context) { 144 Resources res = context.getResources(); 145 DisplayMetrics dm = res.getDisplayMetrics(); 146 mDisplayMetrics = dm; 147 148 // Animations 149 animationPxMovementPerSecond = 150 res.getDimensionPixelSize(R.dimen.recents_animation_movement_in_dps_per_second); 151 152 // Filtering 153 filteringCurrentViewsAnimDuration = 154 res.getInteger(R.integer.recents_filter_animate_current_views_duration); 155 filteringNewViewsAnimDuration = 156 res.getInteger(R.integer.recents_filter_animate_new_views_duration); 157 158 // Insets 159 displayRect.set(0, 0, dm.widthPixels, dm.heightPixels); 160 161 // Layout 162 isLandscape = res.getConfiguration().orientation == 163 Configuration.ORIENTATION_LANDSCAPE; 164 transposeRecentsLayoutWithOrientation = 165 res.getBoolean(R.bool.recents_transpose_layout_with_orientation); 166 167 // Search bar 168 searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height); 169 170 // Update the search widget id 171 SharedPreferences settings = context.getSharedPreferences(context.getPackageName(), 0); 172 searchBarAppWidgetId = settings.getInt(Constants.Values.App.Key_SearchAppWidgetId, -1); 173 174 // Task stack 175 TypedValue widthPaddingPctValue = new TypedValue(); 176 res.getValue(R.dimen.recents_stack_width_padding_percentage, widthPaddingPctValue, true); 177 taskStackWidthPaddingPct = widthPaddingPctValue.getFloat(); 178 taskStackMaxDim = res.getInteger(R.integer.recents_max_task_stack_view_dim); 179 taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding); 180 181 // Task view animation and styles 182 taskViewEnterFromHomeDuration = 183 res.getInteger(R.integer.recents_animate_task_enter_from_home_duration); 184 taskViewEnterFromHomeDelay = 185 res.getInteger(R.integer.recents_animate_task_enter_from_home_delay); 186 taskViewExitToHomeDuration = 187 res.getInteger(R.integer.recents_animate_task_exit_to_home_duration); 188 taskViewRemoveAnimDuration = 189 res.getInteger(R.integer.recents_animate_task_view_remove_duration); 190 taskViewRemoveAnimTranslationXPx = 191 res.getDimensionPixelSize(R.dimen.recents_task_view_remove_anim_translation_x); 192 taskViewRoundedCornerRadiusPx = 193 res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius); 194 taskViewHighlightPx = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight); 195 taskViewTranslationZMinPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min); 196 taskViewTranslationZIncrementPx = 197 res.getDimensionPixelSize(R.dimen.recents_task_view_z_increment); 198 taskViewShadowOutlineBottomInsetPx = 199 res.getDimensionPixelSize(R.dimen.recents_task_view_shadow_outline_bottom_inset); 200 201 // Task bar colors 202 taskBarViewDefaultBackgroundColor = 203 res.getColor(R.color.recents_task_bar_default_background_color); 204 taskBarViewLightTextColor = 205 res.getColor(R.color.recents_task_bar_light_text_color); 206 taskBarViewDarkTextColor = 207 res.getColor(R.color.recents_task_bar_dark_text_color); 208 taskBarViewHighlightColor = 209 res.getColor(R.color.recents_task_bar_highlight_color); 210 211 // Task bar animations 212 taskBarEnterAnimDuration = 213 res.getInteger(R.integer.recents_animate_task_bar_enter_duration); 214 taskBarEnterAnimDelay = 215 res.getInteger(R.integer.recents_animate_task_bar_enter_delay); 216 taskBarExitAnimDuration = 217 res.getInteger(R.integer.recents_animate_task_bar_exit_duration); 218 taskBarDismissDozeDelaySeconds = 219 res.getInteger(R.integer.recents_task_bar_dismiss_delay_seconds); 220 221 // Nav bar scrim 222 navBarScrimEnterDuration = 223 res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration); 224 225 if (Console.Enabled) { 226 Console.log(Constants.Log.UI.MeasureAndLayout, 227 "[RecentsConfiguration|orientation]", isLandscape ? "Landscape" : "Portrait", 228 Console.AnsiGreen); 229 } 230 } 231 232 /** Updates the system insets */ 233 public void updateSystemInsets(Rect insets) { 234 systemInsets.set(insets); 235 } 236 237 /** Updates the search bar app widget */ 238 public void updateSearchBarAppWidgetId(Context context, int appWidgetId) { 239 searchBarAppWidgetId = appWidgetId; 240 SharedPreferences settings = context.getSharedPreferences(context.getPackageName(), 0); 241 settings.edit().putInt(Constants.Values.App.Key_SearchAppWidgetId, 242 appWidgetId).apply(); 243 } 244 245 /** Called when the configuration has changed, and we want to reset any configuration specific 246 * members. */ 247 public void updateOnConfigurationChange() { 248 launchedWithAltTab = false; 249 launchedWithNoRecentTasks = false; 250 launchedFromAppWithThumbnail = false; 251 launchedFromAppWithScreenshot = false; 252 launchedFromHome = false; 253 } 254 255 /** Returns whether the search bar app widget exists. */ 256 public boolean hasSearchBarAppWidget() { 257 return searchBarAppWidgetId >= 0; 258 } 259 260 /** Returns whether the status bar scrim should be animated when shown for the first time. */ 261 public boolean shouldAnimateStatusBarScrim() { 262 return launchedFromHome; 263 } 264 265 /** Returns whether the status bar scrim should be visible. */ 266 public boolean hasStatusBarScrim() { 267 return !launchedWithNoRecentTasks; 268 } 269 270 /** Returns whether the nav bar scrim should be animated when shown for the first time. */ 271 public boolean shouldAnimateNavBarScrim() { 272 return true; 273 } 274 275 /** Returns whether the nav bar scrim should be visible. */ 276 public boolean hasNavBarScrim() { 277 // Only show the scrim if we have recent tasks, and if the nav bar is not transposed 278 return !launchedWithNoRecentTasks && 279 (!transposeRecentsLayoutWithOrientation || !isLandscape); 280 } 281 282 /** 283 * Returns the task stack bounds in the current orientation. These bounds do not account for 284 * the system insets. 285 */ 286 public void getTaskStackBounds(int width, int height, Rect taskStackBounds) { 287 if (hasSearchBarAppWidget()) { 288 Rect searchBarBounds = new Rect(); 289 getSearchBarBounds(width, height, searchBarBounds); 290 if (isLandscape && transposeRecentsLayoutWithOrientation) { 291 // In landscape, the search bar appears on the left, so shift the task rect right 292 taskStackBounds.set(searchBarBounds.width(), 0, width, height); 293 } else { 294 // In portrait, the search bar appears on the top, so shift the task rect below 295 taskStackBounds.set(0, searchBarBounds.height(), width, height); 296 } 297 } else { 298 taskStackBounds.set(0, 0, width, height); 299 } 300 } 301 302 /** 303 * Returns the search bar bounds in the current orientation. These bounds do not account for 304 * the system insets. 305 */ 306 public void getSearchBarBounds(int width, int height, Rect searchBarSpaceBounds) { 307 // Return empty rects if search is not enabled 308 if (!Constants.DebugFlags.App.EnableSearchLayout) { 309 searchBarSpaceBounds.set(0, 0, 0, 0); 310 return; 311 } 312 313 if (isLandscape && transposeRecentsLayoutWithOrientation) { 314 // In landscape, the search bar appears on the left 315 searchBarSpaceBounds.set(0, 0, searchBarSpaceHeightPx, height); 316 } else { 317 // In portrait, the search bar appears on the top 318 searchBarSpaceBounds.set(0, 0, width, searchBarSpaceHeightPx); 319 } 320 } 321} 322