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