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