RecentsConfiguration.java revision 521e7dc0a6782371a710ee81bf804f7e97aaa292
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;
31
32
33/** A static Recents configuration for the current context
34 * NOTE: We should not hold any references to a Context from a static instance */
35public class RecentsConfiguration {
36    static RecentsConfiguration sInstance;
37
38    DisplayMetrics mDisplayMetrics;
39
40    public Rect systemInsets = new Rect();
41    public Rect displayRect = new Rect();
42
43    boolean isLandscape;
44    boolean transposeRecentsLayoutWithOrientation;
45    int searchBarAppWidgetId = -1;
46
47    public float animationPxMovementPerSecond;
48
49    public Interpolator fastOutSlowInInterpolator;
50    public Interpolator fastOutLinearInInterpolator;
51    public Interpolator linearOutSlowInInterpolator;
52
53    public int filteringCurrentViewsMinAnimDuration;
54    public int filteringNewViewsMinAnimDuration;
55
56    public int taskStackScrollDismissInfoPaneDistance;
57    public int taskStackMaxDim;
58    public float taskStackWidthPaddingPct;
59    public int taskStackTopPaddingPx;
60
61    public int taskViewRemoveAnimDuration;
62    public int taskViewRemoveAnimTranslationXPx;
63    public int taskViewTranslationZMinPx;
64    public int taskViewTranslationZIncrementPx;
65    public int taskViewShadowOutlineBottomInsetPx;
66    public int taskViewRoundedCornerRadiusPx;
67    public int taskViewHighlightPx;
68
69    public int searchBarSpaceHeightPx;
70
71    public int taskBarViewDefaultBackgroundColor;
72    public int taskBarViewDefaultTextColor;
73    public int taskBarViewLightTextColor;
74    public int taskBarViewDarkTextColor;
75    public int taskBarViewHighlightColor;
76
77    public int taskBarEnterAnimDuration;
78    public int taskBarEnterAnimDelay;
79    public int taskBarExitAnimDuration;
80
81    public int navBarScrimEnterDuration;
82
83    public boolean launchedFromAltTab;
84    public boolean launchedWithThumbnailAnimation;
85
86    public boolean developerOptionsEnabled;
87
88    /** Private constructor */
89    private RecentsConfiguration() {}
90
91    /** Updates the configuration to the current context */
92    public static RecentsConfiguration reinitialize(Context context) {
93        if (sInstance == null) {
94            sInstance = new RecentsConfiguration();
95        }
96        sInstance.update(context);
97        return sInstance;
98    }
99
100    /** Returns the current recents configuration */
101    public static RecentsConfiguration getInstance() {
102        return sInstance;
103    }
104
105    /** Updates the state, given the specified context */
106    void update(Context context) {
107        Resources res = context.getResources();
108        DisplayMetrics dm = res.getDisplayMetrics();
109        mDisplayMetrics = dm;
110
111        isLandscape = res.getConfiguration().orientation ==
112                Configuration.ORIENTATION_LANDSCAPE;
113        transposeRecentsLayoutWithOrientation =
114                res.getBoolean(R.bool.recents_transpose_layout_with_orientation);
115        if (Console.Enabled) {
116            Console.log(Constants.Log.UI.MeasureAndLayout,
117                    "[RecentsConfiguration|orientation]", isLandscape ? "Landscape" : "Portrait",
118                    Console.AnsiGreen);
119        }
120
121        displayRect.set(0, 0, dm.widthPixels, dm.heightPixels);
122        animationPxMovementPerSecond =
123                res.getDimensionPixelSize(R.dimen.recents_animation_movement_in_dps_per_second);
124        filteringCurrentViewsMinAnimDuration =
125                res.getInteger(R.integer.recents_filter_animate_current_views_min_duration);
126        filteringNewViewsMinAnimDuration =
127                res.getInteger(R.integer.recents_filter_animate_new_views_min_duration);
128
129        taskStackScrollDismissInfoPaneDistance = res.getDimensionPixelSize(
130                R.dimen.recents_task_stack_scroll_dismiss_info_pane_distance);
131        taskStackMaxDim = res.getInteger(R.integer.recents_max_task_stack_view_dim);
132
133        TypedValue widthPaddingPctValue = new TypedValue();
134        res.getValue(R.dimen.recents_stack_width_padding_percentage, widthPaddingPctValue, true);
135        taskStackWidthPaddingPct = widthPaddingPctValue.getFloat();
136        taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding);
137
138        taskViewRemoveAnimDuration =
139                res.getInteger(R.integer.recents_animate_task_view_remove_duration);
140        taskViewRemoveAnimTranslationXPx =
141                res.getDimensionPixelSize(R.dimen.recents_task_view_remove_anim_translation_x);
142        taskViewRoundedCornerRadiusPx =
143                res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
144        taskViewHighlightPx = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
145        taskViewTranslationZMinPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
146        taskViewTranslationZIncrementPx =
147                res.getDimensionPixelSize(R.dimen.recents_task_view_z_increment);
148        taskViewShadowOutlineBottomInsetPx =
149                res.getDimensionPixelSize(R.dimen.recents_task_view_shadow_outline_bottom_inset);
150
151        searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height);
152
153        taskBarViewDefaultBackgroundColor =
154                res.getColor(R.color.recents_task_bar_default_background_color);
155        taskBarViewDefaultTextColor =
156                res.getColor(R.color.recents_task_bar_default_text_color);
157        taskBarViewLightTextColor =
158                res.getColor(R.color.recents_task_bar_light_text_color);
159        taskBarViewDarkTextColor =
160                res.getColor(R.color.recents_task_bar_dark_text_color);
161        taskBarViewHighlightColor =
162                res.getColor(R.color.recents_task_bar_highlight_color);
163
164        taskBarEnterAnimDuration =
165                res.getInteger(R.integer.recents_animate_task_bar_enter_duration);
166        taskBarEnterAnimDelay =
167                res.getInteger(R.integer.recents_animate_task_bar_enter_delay);
168        taskBarExitAnimDuration =
169                res.getInteger(R.integer.recents_animate_task_bar_exit_duration);
170
171        navBarScrimEnterDuration =
172                res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration);
173
174        fastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
175                        com.android.internal.R.interpolator.fast_out_slow_in);
176        fastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
177                com.android.internal.R.interpolator.fast_out_linear_in);
178        linearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
179                com.android.internal.R.interpolator.linear_out_slow_in);
180
181        // Check if the developer options are enabled
182        ContentResolver cr = context.getContentResolver();
183        developerOptionsEnabled = Settings.Global.getInt(cr,
184                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
185
186        // Update the search widget id
187        SharedPreferences settings = context.getSharedPreferences(context.getPackageName(), 0);
188        searchBarAppWidgetId = settings.getInt(Constants.Values.App.Key_SearchAppWidgetId, -1);
189    }
190
191    /** Updates the system insets */
192    public void updateSystemInsets(Rect insets) {
193        systemInsets.set(insets);
194    }
195
196    /** Updates the search bar app widget */
197    public void updateSearchBarAppWidgetId(Context context, int appWidgetId) {
198        searchBarAppWidgetId = appWidgetId;
199        SharedPreferences settings = context.getSharedPreferences(context.getPackageName(), 0);
200        settings.edit().putInt(Constants.Values.App.Key_SearchAppWidgetId,
201                appWidgetId).apply();
202    }
203
204    /** Called when the configuration has changed, and we want to reset any configuration specific
205     * members. */
206    public void updateOnConfigurationChange() {
207        launchedFromAltTab = false;
208        launchedWithThumbnailAnimation = false;
209    }
210
211    /** Returns whether the search bar app widget exists. */
212    public boolean hasSearchBarAppWidget() {
213        return searchBarAppWidgetId >= 0;
214    }
215
216    /** Returns whether the nav bar scrim should be visible. */
217    public boolean hasNavBarScrim() {
218        return !transposeRecentsLayoutWithOrientation || !isLandscape;
219    }
220
221    /**
222     * Returns the task stack bounds in the current orientation. These bounds do not account for
223     * the system insets.
224     */
225    public void getTaskStackBounds(int width, int height, Rect taskStackBounds) {
226        if (hasSearchBarAppWidget()) {
227            Rect searchBarBounds = new Rect();
228            getSearchBarBounds(width, height, searchBarBounds);
229            if (isLandscape && transposeRecentsLayoutWithOrientation) {
230                // In landscape, the search bar appears on the left, so shift the task rect right
231                taskStackBounds.set(searchBarBounds.width(), 0, width, height);
232            } else {
233                // In portrait, the search bar appears on the top, so shift the task rect below
234                taskStackBounds.set(0, searchBarBounds.height(), width, height);
235            }
236        } else {
237            taskStackBounds.set(0, 0, width, height);
238        }
239    }
240
241    /**
242     * Returns the search bar bounds in the current orientation.  These bounds do not account for
243     * the system insets.
244     */
245    public void getSearchBarBounds(int width, int height, Rect searchBarSpaceBounds) {
246        // Return empty rects if search is not enabled
247        if (!Constants.DebugFlags.App.EnableSearchLayout) {
248            searchBarSpaceBounds.set(0, 0, 0, 0);
249            return;
250        }
251
252        if (isLandscape && transposeRecentsLayoutWithOrientation) {
253            // In landscape, the search bar appears on the left
254            searchBarSpaceBounds.set(0, 0, searchBarSpaceHeightPx, height);
255        } else {
256            // In portrait, the search bar appears on the top
257            searchBarSpaceBounds.set(0, 0, width, searchBarSpaceHeightPx);
258        }
259    }
260
261    /** Converts from DPs to PXs */
262    public int pxFromDp(float size) {
263        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
264                size, mDisplayMetrics));
265    }
266    /** Converts from SPs to PXs */
267    public int pxFromSp(float size) {
268        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
269                size, mDisplayMetrics));
270    }
271}
272