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