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