RecentsConfiguration.java revision 53ec42cb17693b2d631746e1e5d31021a3359163
1303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/* 2303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Copyright (C) 2014 The Android Open Source Project 3303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * 4303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * you may not use this file except in compliance with the License. 6303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * You may obtain a copy of the License at 7303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * 8303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * 10303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Unless required by applicable law or agreed to in writing, software 11303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * See the License for the specific language governing permissions and 14303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * limitations under the License. 15303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 16303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 17303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpackage com.android.systemui.recents; 18303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 19303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.content.Context; 20c620bafde865f7599401f5adf0521820ee9d4a9cWinson Chungimport android.content.res.Resources; 21303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.graphics.Rect; 2247a3e65acc35cd3061bf3867e8b20753870fd892Winson Chungimport android.provider.Settings; 232f2ca08baa072376b3dfd60506625496aa05903fWinson Chungimport com.android.systemui.R; 2456e09b42a0f1670970872bef611a8036904ad6bfJason Monkimport com.android.systemui.recents.misc.SystemServicesProxy; 25303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 2635f3050959e43bf378f9a0adcaef13729206c7e4Winson/** 2735f3050959e43bf378f9a0adcaef13729206c7e4Winson * Application resources that can be retrieved from the application context and are not specifically 2835f3050959e43bf378f9a0adcaef13729206c7e4Winson * tied to the current activity. 2935f3050959e43bf378f9a0adcaef13729206c7e4Winson */ 30303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class RecentsConfiguration { 3135f3050959e43bf378f9a0adcaef13729206c7e4Winson 3235f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final int LARGE_SCREEN_MIN_DP = 600; 3335f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final int XLARGE_SCREEN_MIN_DP = 720; 3435f3050959e43bf378f9a0adcaef13729206c7e4Winson 3535f3050959e43bf378f9a0adcaef13729206c7e4Winson // Variables that are used for global calculations 3635f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final float STACK_SIDE_PADDING_PHONES_PCT = 0.03333f; 3735f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final float STACK_SIZE_PADDING_TABLETS_PCT = 0.075f; 3835f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final float STACK_SIZE_PADDING_LARGE_TABLETS_PCT = 0.15f; 3935f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final int SEARCH_BAR_SPACE_HEIGHT_PHONES_DPS = 64; 4035f3050959e43bf378f9a0adcaef13729206c7e4Winson private static final int SEARCH_BAR_SPACE_HEIGHT_TABLETS_DPS = 72; 41303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 4296d704186621f6310e0e7d39db57caff67baa96cWinson Chung /** Levels of svelte in increasing severity/austerity. */ 4396d704186621f6310e0e7d39db57caff67baa96cWinson Chung // No svelting. 4496d704186621f6310e0e7d39db57caff67baa96cWinson Chung public static final int SVELTE_NONE = 0; 4596d704186621f6310e0e7d39db57caff67baa96cWinson Chung // Limit thumbnail cache to number of visible thumbnails when Recents was loaded, disable 4696d704186621f6310e0e7d39db57caff67baa96cWinson Chung // caching thumbnails as you scroll. 4796d704186621f6310e0e7d39db57caff67baa96cWinson Chung public static final int SVELTE_LIMIT_CACHE = 1; 4896d704186621f6310e0e7d39db57caff67baa96cWinson Chung // Disable the thumbnail cache, load thumbnails asynchronously when the activity loads and 4996d704186621f6310e0e7d39db57caff67baa96cWinson Chung // evict all thumbnails when hidden. 5096d704186621f6310e0e7d39db57caff67baa96cWinson Chung public static final int SVELTE_DISABLE_CACHE = 2; 5196d704186621f6310e0e7d39db57caff67baa96cWinson Chung // Disable all thumbnail loading. 5296d704186621f6310e0e7d39db57caff67baa96cWinson Chung public static final int SVELTE_DISABLE_LOADING = 3; 5396d704186621f6310e0e7d39db57caff67baa96cWinson Chung 5435f3050959e43bf378f9a0adcaef13729206c7e4Winson // Launch states 5553ec42cb17693b2d631746e1e5d31021a3359163Winson public RecentsActivityLaunchState mLaunchState = new RecentsActivityLaunchState(); 56918c0723a169cef46b8bf59c06fd3bb8021d0defWinson Chung 5735f3050959e43bf378f9a0adcaef13729206c7e4Winson // TODO: Values determined by the current context, needs to be refactored into something that is 5835f3050959e43bf378f9a0adcaef13729206c7e4Winson // agnostic of the activity context, but still calculable from the Recents component for 5935f3050959e43bf378f9a0adcaef13729206c7e4Winson // the transition into recents 6027acf761229779e1777d380616846ac07f484ed6Winson Chung boolean hasTransposedSearchBar; 6127acf761229779e1777d380616846ac07f484ed6Winson Chung boolean hasTransposedNavBar; 62d42a6cfe2bf632222617450a1ed340268e82f06cWinson Chung public float taskStackWidthPaddingPct; 63cd23c849afefe58b213d5abb1c581f15d3ad543aWinson Chung 6435f3050959e43bf378f9a0adcaef13729206c7e4Winson // Since the positions in Recents has to be calculated globally (before the RecentsActivity 6535f3050959e43bf378f9a0adcaef13729206c7e4Winson // starts), we need to calculate some resource values ourselves, instead of relying on framework 6635f3050959e43bf378f9a0adcaef13729206c7e4Winson // resources. 6735f3050959e43bf378f9a0adcaef13729206c7e4Winson public final boolean isLargeScreen; 6835f3050959e43bf378f9a0adcaef13729206c7e4Winson public final boolean isXLargeScreen; 6935f3050959e43bf378f9a0adcaef13729206c7e4Winson public final int smallestWidth; 70b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung 71a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung /** Misc **/ 72be7607af8875236b9cf7bdb5f5aa089c207529afWinson public boolean hasDockedTasks; 73e8199c582d826a39e6e47b0d8418834c15242fecSelim Cinek public boolean useHardwareLayers; 74cb5570316d55c6fe2ff717fa6b94b14d13980263Jorim Jaggi public boolean fakeShadows; 7535f3050959e43bf378f9a0adcaef13729206c7e4Winson public int svelteLevel; 7635f3050959e43bf378f9a0adcaef13729206c7e4Winson public int searchBarSpaceHeightPx; 77a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung 7856e09b42a0f1670970872bef611a8036904ad6bfJason Monk /** Dev options and global settings */ 7956e09b42a0f1670970872bef611a8036904ad6bfJason Monk public boolean lockToAppEnabled; 8047a3e65acc35cd3061bf3867e8b20753870fd892Winson Chung 8153ec42cb17693b2d631746e1e5d31021a3359163Winson public RecentsConfiguration(Context context) { 8235f3050959e43bf378f9a0adcaef13729206c7e4Winson // Load only resources that can not change after the first load either through developer 8335f3050959e43bf378f9a0adcaef13729206c7e4Winson // settings or via multi window 8453ec42cb17693b2d631746e1e5d31021a3359163Winson SystemServicesProxy ssp = Recents.getSystemServices(); 8535f3050959e43bf378f9a0adcaef13729206c7e4Winson Context appContext = context.getApplicationContext(); 8635f3050959e43bf378f9a0adcaef13729206c7e4Winson Resources res = appContext.getResources(); 8735f3050959e43bf378f9a0adcaef13729206c7e4Winson useHardwareLayers = res.getBoolean(R.bool.config_recents_use_hardware_layers); 8835f3050959e43bf378f9a0adcaef13729206c7e4Winson fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows); 8935f3050959e43bf378f9a0adcaef13729206c7e4Winson svelteLevel = res.getInteger(R.integer.recents_svelte_level); 9035f3050959e43bf378f9a0adcaef13729206c7e4Winson 9135f3050959e43bf378f9a0adcaef13729206c7e4Winson float density = context.getResources().getDisplayMetrics().density; 9235f3050959e43bf378f9a0adcaef13729206c7e4Winson smallestWidth = ssp.getDeviceSmallestWidth(); 9335f3050959e43bf378f9a0adcaef13729206c7e4Winson isLargeScreen = smallestWidth >= (int) (density * LARGE_SCREEN_MIN_DP); 9435f3050959e43bf378f9a0adcaef13729206c7e4Winson isXLargeScreen = smallestWidth >= (int) (density * XLARGE_SCREEN_MIN_DP); 9535f3050959e43bf378f9a0adcaef13729206c7e4Winson searchBarSpaceHeightPx = isLargeScreen ? 9635f3050959e43bf378f9a0adcaef13729206c7e4Winson (int) (density * SEARCH_BAR_SPACE_HEIGHT_TABLETS_DPS) : 9735f3050959e43bf378f9a0adcaef13729206c7e4Winson (int) (density * SEARCH_BAR_SPACE_HEIGHT_PHONES_DPS); 9835f3050959e43bf378f9a0adcaef13729206c7e4Winson if (isLargeScreen) { 9935f3050959e43bf378f9a0adcaef13729206c7e4Winson taskStackWidthPaddingPct = STACK_SIZE_PADDING_TABLETS_PCT; 10035f3050959e43bf378f9a0adcaef13729206c7e4Winson } else if (isXLargeScreen) { 10135f3050959e43bf378f9a0adcaef13729206c7e4Winson taskStackWidthPaddingPct = STACK_SIZE_PADDING_LARGE_TABLETS_PCT; 10235f3050959e43bf378f9a0adcaef13729206c7e4Winson } else { 10335f3050959e43bf378f9a0adcaef13729206c7e4Winson taskStackWidthPaddingPct = STACK_SIDE_PADDING_PHONES_PCT; 10435f3050959e43bf378f9a0adcaef13729206c7e4Winson } 10535f3050959e43bf378f9a0adcaef13729206c7e4Winson } 10635f3050959e43bf378f9a0adcaef13729206c7e4Winson 10735f3050959e43bf378f9a0adcaef13729206c7e4Winson /** 10835f3050959e43bf378f9a0adcaef13729206c7e4Winson * Updates the configuration based on the current state of the system 10935f3050959e43bf378f9a0adcaef13729206c7e4Winson */ 11035f3050959e43bf378f9a0adcaef13729206c7e4Winson void update(Context context, SystemServicesProxy ssp, Rect windowRect) { 11135f3050959e43bf378f9a0adcaef13729206c7e4Winson // Only update resources that can change after the first load, either through developer 11235f3050959e43bf378f9a0adcaef13729206c7e4Winson // settings or via multi window 113e7f138c7f0a190c86cec10fb32fa106aacae4093Winson lockToAppEnabled = ssp.getSystemSetting(context, Settings.System.LOCK_TO_APP_ENABLED) != 0; 114be7607af8875236b9cf7bdb5f5aa089c207529afWinson hasDockedTasks = ssp.hasDockedTask(); 11506795630f62e1e7ad89825db23d7656f8dcd6c5aWinson Chung 11635f3050959e43bf378f9a0adcaef13729206c7e4Winson // Recompute some values based on the given state, since we can not rely on the resource 11735f3050959e43bf378f9a0adcaef13729206c7e4Winson // system to get certain values. 11835f3050959e43bf378f9a0adcaef13729206c7e4Winson boolean isLandscape = windowRect.width() > windowRect.height(); 11935f3050959e43bf378f9a0adcaef13729206c7e4Winson hasTransposedNavBar = isLandscape && isLargeScreen && !isXLargeScreen; 12035f3050959e43bf378f9a0adcaef13729206c7e4Winson hasTransposedSearchBar = isLandscape && isLargeScreen && !isXLargeScreen; 12106795630f62e1e7ad89825db23d7656f8dcd6c5aWinson Chung } 122303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 12335f3050959e43bf378f9a0adcaef13729206c7e4Winson /** 12435f3050959e43bf378f9a0adcaef13729206c7e4Winson * Returns the activity launch state. 12535f3050959e43bf378f9a0adcaef13729206c7e4Winson * TODO: This will be refactored out of RecentsConfiguration. 12635f3050959e43bf378f9a0adcaef13729206c7e4Winson */ 12735f3050959e43bf378f9a0adcaef13729206c7e4Winson public RecentsActivityLaunchState getLaunchState() { 12835f3050959e43bf378f9a0adcaef13729206c7e4Winson return mLaunchState; 12956e09b42a0f1670970872bef611a8036904ad6bfJason Monk } 13056e09b42a0f1670970872bef611a8036904ad6bfJason Monk 131e7f138c7f0a190c86cec10fb32fa106aacae4093Winson /** 132e7f138c7f0a190c86cec10fb32fa106aacae4093Winson * Called when the configuration has changed, and we want to reset any configuration specific 133e7f138c7f0a190c86cec10fb32fa106aacae4093Winson * members. 134e7f138c7f0a190c86cec10fb32fa106aacae4093Winson */ 135b01ed681fe97ff5e98471c120ff9581a78db13c5Winson Chung public void updateOnConfigurationChange() { 13635f3050959e43bf378f9a0adcaef13729206c7e4Winson mLaunchState.updateOnConfigurationChange(); 137521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung } 138521e7dc0a6782371a710ee81bf804f7e97aaa292Winson Chung 139f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** 140f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * Returns the task stack bounds in the current orientation. These bounds do not account for 141f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * the system insets. 142f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung */ 14388f00ab1df35928ad0aa0c64f75ecad88d86096cWinson public void getTaskStackBounds(Rect windowBounds, int topInset, 144af3bb6936786a8c14ac01da3d81d196d17b68b96Winson Chung int rightInset, Rect searchBarBounds, Rect taskStackBounds) { 14535f3050959e43bf378f9a0adcaef13729206c7e4Winson if (hasTransposedNavBar) { 14635f3050959e43bf378f9a0adcaef13729206c7e4Winson // In landscape phones, the search bar appears on the left, but we overlay it on top 14735f3050959e43bf378f9a0adcaef13729206c7e4Winson int swInset = getInsetToSmallestWidth(windowBounds.right - rightInset - 14835f3050959e43bf378f9a0adcaef13729206c7e4Winson windowBounds.left); 14935f3050959e43bf378f9a0adcaef13729206c7e4Winson taskStackBounds.set(windowBounds.left + swInset, windowBounds.top + topInset, 15035f3050959e43bf378f9a0adcaef13729206c7e4Winson windowBounds.right - swInset - rightInset, windowBounds.bottom); 151f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } else { 152dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung // In portrait, the search bar appears on the top (which already has the inset) 15335f3050959e43bf378f9a0adcaef13729206c7e4Winson int swInset = getInsetToSmallestWidth(windowBounds.right - windowBounds.left); 1542364f26dc24191e5bfbab45bc1bdf9babe13af80Winson int top = searchBarBounds.isEmpty() ? topInset : 0; 1552364f26dc24191e5bfbab45bc1bdf9babe13af80Winson taskStackBounds.set(windowBounds.left + swInset, searchBarBounds.bottom + top, 15635f3050959e43bf378f9a0adcaef13729206c7e4Winson windowBounds.right - swInset, windowBounds.bottom); 157f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 158f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 159f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung 160f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung /** 161f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * Returns the search bar bounds in the current orientation. These bounds do not account for 162f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung * the system insets. 163f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung */ 164147ecaf3ba5d72872e8ff324aa32c0d228ada7f5Winson public void getSearchBarBounds(Rect windowBounds, int topInset, Rect searchBarSpaceBounds) { 165ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung // Return empty rects if search is not enabled 166dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung int searchBarSize = searchBarSpaceHeightPx; 16735f3050959e43bf378f9a0adcaef13729206c7e4Winson if (hasTransposedSearchBar) { 16835f3050959e43bf378f9a0adcaef13729206c7e4Winson // In landscape phones, the search bar appears on the left 169147ecaf3ba5d72872e8ff324aa32c0d228ada7f5Winson searchBarSpaceBounds.set(windowBounds.left, windowBounds.top + topInset, 170147ecaf3ba5d72872e8ff324aa32c0d228ada7f5Winson windowBounds.left + searchBarSize, windowBounds.bottom); 171f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } else { 172f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung // In portrait, the search bar appears on the top 173147ecaf3ba5d72872e8ff324aa32c0d228ada7f5Winson searchBarSpaceBounds.set(windowBounds.left, windowBounds.top + topInset, 174147ecaf3ba5d72872e8ff324aa32c0d228ada7f5Winson windowBounds.right, windowBounds.top + topInset + searchBarSize); 175f7bca430d9356c26d6df222d2c90bc7668262f6bWinson Chung } 176ecd9b3031c9a322bd69380eae2810d53839e8f64Winson Chung } 17735f3050959e43bf378f9a0adcaef13729206c7e4Winson 17835f3050959e43bf378f9a0adcaef13729206c7e4Winson /** 17935f3050959e43bf378f9a0adcaef13729206c7e4Winson * Constrain the width of the landscape stack to the smallest width of the device. 18035f3050959e43bf378f9a0adcaef13729206c7e4Winson */ 18135f3050959e43bf378f9a0adcaef13729206c7e4Winson private int getInsetToSmallestWidth(int availableWidth) { 18235f3050959e43bf378f9a0adcaef13729206c7e4Winson if (availableWidth > smallestWidth) { 18335f3050959e43bf378f9a0adcaef13729206c7e4Winson return (availableWidth - smallestWidth) / 2; 18435f3050959e43bf378f9a0adcaef13729206c7e4Winson } 18535f3050959e43bf378f9a0adcaef13729206c7e4Winson return 0; 18635f3050959e43bf378f9a0adcaef13729206c7e4Winson } 187303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 188