2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.systemui.recents.misc;
19 import android.animation.Animator;
20 import android.animation.AnimatorSet;
21 import android.animation.RectEvaluator;
22 import android.annotation.FloatRange;
23 import android.app.Activity;
24 import android.content.Context;
25 import android.content.res.Configuration;
26 import android.content.res.Resources;
27 import android.graphics.Color;
28 import android.graphics.Rect;
29 import android.graphics.RectF;
30 import android.graphics.drawable.Drawable;
31 import android.os.Trace;
32 import android.util.ArraySet;
33 import android.util.IntProperty;
34 import android.util.Property;
35 import android.util.TypedValue;
36 import android.view.View;
37 import android.view.ViewParent;
38 import android.view.ViewStub;
40 import com.android.systemui.recents.model.Task;
41 import com.android.systemui.recents.views.TaskViewTransform;
43 import java.util.ArrayList;
44 import java.util.Collections;
45 import java.util.List;
48 public class Utilities {
50 public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
51 new IntProperty<Drawable>("drawableAlpha") {
53 public void setValue(Drawable object, int alpha) {
54 object.setAlpha(alpha);
58 public Integer get(Drawable object) {
59 return object.getAlpha();
63 public static final Property<Drawable, Rect> DRAWABLE_RECT =
64 new Property<Drawable, Rect>(Rect.class, "drawableBounds") {
66 public void set(Drawable object, Rect bounds) {
67 object.setBounds(bounds);
71 public Rect get(Drawable object) {
72 return object.getBounds();
76 public static final RectFEvaluator RECTF_EVALUATOR = new RectFEvaluator();
77 public static final RectEvaluator RECT_EVALUATOR = new RectEvaluator(new Rect());
78 public static final Rect EMPTY_RECT = new Rect();
81 * @return the first parent walking up the view hierarchy that has the given class type.
83 * @param parentClass must be a class derived from {@link View}
85 public static <T extends View> T findParent(View v, Class<T> parentClass) {
86 ViewParent parent = v.getParent();
87 while (parent != null) {
88 if (parent.getClass().equals(parentClass)) {
91 parent = parent.getParent();
97 * Initializes the {@param setOut} with the given object.
99 public static <T> ArraySet<T> objectToSet(T obj, ArraySet<T> setOut) {
108 * Replaces the contents of {@param setOut} with the contents of the {@param array}.
110 public static <T> ArraySet<T> arrayToSet(T[] array, ArraySet<T> setOut) {
113 Collections.addAll(setOut, array);
119 * @return the clamped {@param value} between the provided {@param min} and {@param max}.
121 public static float clamp(float value, float min, float max) {
122 return Math.max(min, Math.min(max, value));
126 * @return the clamped {@param value} between the provided {@param min} and {@param max}.
128 public static int clamp(int value, int min, int max) {
129 return Math.max(min, Math.min(max, value));
133 * @return the clamped {@param value} between 0 and 1.
135 public static float clamp01(float value) {
136 return Math.max(0f, Math.min(1f, value));
140 * Scales the {@param value} to be proportionally between the {@param min} and
141 * {@param max} values.
143 * @param value must be between 0 and 1
145 public static float mapRange(@FloatRange(from=0.0,to=1.0) float value, float min, float max) {
146 return min + (value * (max - min));
150 * Scales the {@param value} proportionally from {@param min} and {@param max} to 0 and 1.
152 * @param value must be between {@param min} and {@param max}
154 public static float unmapRange(float value, float min, float max) {
155 return (value - min) / (max - min);
158 /** Scales a rect about its centroid */
159 public static void scaleRectAboutCenter(RectF r, float scale) {
161 float cx = r.centerX();
162 float cy = r.centerY();
172 /** Calculates the constrast between two colors, using the algorithm provided by the WCAG v2. */
173 public static float computeContrastBetweenColors(int bg, int fg) {
174 float bgR = Color.red(bg) / 255f;
175 float bgG = Color.green(bg) / 255f;
176 float bgB = Color.blue(bg) / 255f;
177 bgR = (bgR < 0.03928f) ? bgR / 12.92f : (float) Math.pow((bgR + 0.055f) / 1.055f, 2.4f);
178 bgG = (bgG < 0.03928f) ? bgG / 12.92f : (float) Math.pow((bgG + 0.055f) / 1.055f, 2.4f);
179 bgB = (bgB < 0.03928f) ? bgB / 12.92f : (float) Math.pow((bgB + 0.055f) / 1.055f, 2.4f);
180 float bgL = 0.2126f * bgR + 0.7152f * bgG + 0.0722f * bgB;
182 float fgR = Color.red(fg) / 255f;
183 float fgG = Color.green(fg) / 255f;
184 float fgB = Color.blue(fg) / 255f;
185 fgR = (fgR < 0.03928f) ? fgR / 12.92f : (float) Math.pow((fgR + 0.055f) / 1.055f, 2.4f);
186 fgG = (fgG < 0.03928f) ? fgG / 12.92f : (float) Math.pow((fgG + 0.055f) / 1.055f, 2.4f);
187 fgB = (fgB < 0.03928f) ? fgB / 12.92f : (float) Math.pow((fgB + 0.055f) / 1.055f, 2.4f);
188 float fgL = 0.2126f * fgR + 0.7152f * fgG + 0.0722f * fgB;
190 return Math.abs((fgL + 0.05f) / (bgL + 0.05f));
193 /** Returns the base color overlaid with another overlay color with a specified alpha. */
194 public static int getColorWithOverlay(int baseColor, int overlayColor, float overlayAlpha) {
196 (int) (overlayAlpha * Color.red(baseColor) +
197 (1f - overlayAlpha) * Color.red(overlayColor)),
198 (int) (overlayAlpha * Color.green(baseColor) +
199 (1f - overlayAlpha) * Color.green(overlayColor)),
200 (int) (overlayAlpha * Color.blue(baseColor) +
201 (1f - overlayAlpha) * Color.blue(overlayColor)));
205 * Cancels an animation ensuring that if it has listeners, onCancel and onEnd
208 public static void cancelAnimationWithoutCallbacks(Animator animator) {
209 if (animator != null && animator.isStarted()) {
210 removeAnimationListenersRecursive(animator);
216 * Recursively removes all the listeners of all children of this animator
218 public static void removeAnimationListenersRecursive(Animator animator) {
219 if (animator instanceof AnimatorSet) {
220 ArrayList<Animator> animators = ((AnimatorSet) animator).getChildAnimations();
221 for (int i = animators.size() - 1; i >= 0; i--) {
222 removeAnimationListenersRecursive(animators.get(i));
225 animator.removeAllListeners();
229 * Sets the given {@link View}'s frame from its current translation.
231 public static void setViewFrameFromTranslation(View v) {
232 RectF taskViewRect = new RectF(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
233 taskViewRect.offset(v.getTranslationX(), v.getTranslationY());
234 v.setTranslationX(0);
235 v.setTranslationY(0);
236 v.setLeftTopRightBottom((int) taskViewRect.left, (int) taskViewRect.top,
237 (int) taskViewRect.right, (int) taskViewRect.bottom);
241 * Returns a view stub for the given view id.
243 public static ViewStub findViewStubById(View v, int stubId) {
244 return (ViewStub) v.findViewById(stubId);
248 * Returns a view stub for the given view id.
250 public static ViewStub findViewStubById(Activity a, int stubId) {
251 return (ViewStub) a.findViewById(stubId);
255 * Updates {@param transforms} to be the same size as {@param tasks}.
257 public static void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
258 // We can reuse the task transforms where possible to reduce object allocation
259 int taskTransformCount = transforms.size();
260 int taskCount = tasks.size();
261 if (taskTransformCount < taskCount) {
262 // If there are less transforms than tasks, then add as many transforms as necessary
263 for (int i = taskTransformCount; i < taskCount; i++) {
264 transforms.add(new TaskViewTransform());
266 } else if (taskTransformCount > taskCount) {
267 // If there are more transforms than tasks, then just subset the transform list
268 transforms.subList(taskCount, taskTransformCount).clear();
273 * Used for debugging, converts DP to PX.
275 public static float dpToPx(Resources res, float dp) {
276 return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics());
280 * Adds a trace event for debugging.
282 public static void addTraceEvent(String event) {
283 Trace.traceBegin(Trace.TRACE_TAG_VIEW, event);
284 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
288 * Returns the application configuration, which is independent of the activity's current
289 * configuration in multiwindow.
291 public static Configuration getAppConfiguration(Context context) {
292 return context.getApplicationContext().getResources().getConfiguration();
296 * Returns a lightweight dump of a rect.
298 public static String dumpRect(Rect r) {
302 return r.left + "," + r.top + "-" + r.right + "," + r.bottom;