You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
borrow relevant parts of AOSP commit dbee9bb342cdfaa5155b1918f90262c05e2464cb
Our SVG-based VectorDrawable implementation still relies on `getDefaultColor` but exceptions are no longer thrown when parsing VectorDrawable xml files which use gradients as colors.
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class android_graphics_SweepGradient */
|
||||||
|
|
||||||
|
#ifndef _Included_android_graphics_SweepGradient
|
||||||
|
#define _Included_android_graphics_SweepGradient
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#undef android_graphics_SweepGradient_TYPE_COLORS_AND_POSITIONS
|
||||||
|
#define android_graphics_SweepGradient_TYPE_COLORS_AND_POSITIONS 1L
|
||||||
|
#undef android_graphics_SweepGradient_TYPE_COLOR_START_AND_COLOR_END
|
||||||
|
#define android_graphics_SweepGradient_TYPE_COLOR_START_AND_COLOR_END 2L
|
||||||
|
/*
|
||||||
|
* Class: android_graphics_SweepGradient
|
||||||
|
* Method: nativeCreate1
|
||||||
|
* Signature: (FF[I[F)J
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_android_graphics_SweepGradient_nativeCreate1
|
||||||
|
(JNIEnv *, jclass, jfloat, jfloat, jintArray, jfloatArray);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: android_graphics_SweepGradient
|
||||||
|
* Method: nativeCreate2
|
||||||
|
* Signature: (FFII)J
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_android_graphics_SweepGradient_nativeCreate2
|
||||||
|
(JNIEnv *, jclass, jfloat, jfloat, jint, jint);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -817,8 +817,6 @@ public final class AssetManager {
|
|||||||
int defStyleRes, int[] inValues,
|
int defStyleRes, int[] inValues,
|
||||||
int[] inAttrs, int[] outValues,
|
int[] inAttrs, int[] outValues,
|
||||||
int[] outIndices);
|
int[] outIndices);
|
||||||
/*package*/ native final boolean retrieveAttributes(int xmlParser, int[] inAttrs,
|
|
||||||
int[] outValues, int[] outIndices);
|
|
||||||
/*package*/ native final int getArraySize(int resource);
|
/*package*/ native final int getArraySize(int resource);
|
||||||
/*package*/ native final int retrieveArray(int resource, int[] outValues);
|
/*package*/ native final int retrieveArray(int resource, int[] outValues);
|
||||||
private native final int getStringBlockCount();
|
private native final int getStringBlockCount();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
55
src/api-impl/android/content/res/ComplexColor.java
Normal file
55
src/api-impl/android/content/res/ComplexColor.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
//import android.annotation.ColorInt;
|
||||||
|
import android.content.res.Resources.Theme;
|
||||||
|
import android.graphics.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an abstract class for the complex color information, like
|
||||||
|
* {@link android.content.res.ColorStateList} or {@link android.content.res.GradientColor}
|
||||||
|
*/
|
||||||
|
public abstract class ComplexColor {
|
||||||
|
/**
|
||||||
|
* @return {@code true} if this ComplexColor changes color based on state, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isStateful() { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the default color.
|
||||||
|
*/
|
||||||
|
//@ColorInt
|
||||||
|
public abstract int getDefaultColor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide only for resource preloading
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract ConstantState<ComplexColor> getConstantState();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide only for resource preloading
|
||||||
|
*/
|
||||||
|
public abstract boolean canApplyTheme();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide only for resource preloading
|
||||||
|
*/
|
||||||
|
public abstract ComplexColor obtainForTheme(Theme t);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Cache class which can be used to cache resource objects that are easy to clone but more
|
||||||
|
* expensive to inflate.
|
||||||
|
*
|
||||||
|
* @hide For internal use only.
|
||||||
|
*/
|
||||||
|
public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<ConstantState<T>> {
|
||||||
|
private final Resources mResources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a cache for the given Resources instance.
|
||||||
|
*
|
||||||
|
* @param resources the resources to use when creating new instances
|
||||||
|
*/
|
||||||
|
public ConfigurationBoundResourceCache(Resources resources) {
|
||||||
|
mResources = resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the resource is cached, creates and returns a new instance of it.
|
||||||
|
*
|
||||||
|
* @param key a key that uniquely identifies the drawable resource
|
||||||
|
* @param theme the theme where the resource will be used
|
||||||
|
* @return a new instance of the resource, or {@code null} if not in
|
||||||
|
* the cache
|
||||||
|
*/
|
||||||
|
public T getInstance(long key, Resources.Theme theme) {
|
||||||
|
final ConstantState<T> entry = get(key, theme);
|
||||||
|
if (entry != null) {
|
||||||
|
return entry.newInstance(mResources, theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldInvalidateEntry(ConstantState<T> entry, int configChanges) {
|
||||||
|
return Configuration.needNewResources(configChanges, entry.getChangingConfigurations());
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/api-impl/android/content/res/ConstantState.java
Normal file
61
src/api-impl/android/content/res/ConstantState.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cache class that can provide new instances of a particular resource which may change
|
||||||
|
* depending on the current {@link Resources.Theme} or {@link Configuration}.
|
||||||
|
* <p>
|
||||||
|
* A constant state should be able to return a bitmask of changing configurations, which
|
||||||
|
* identifies the type of configuration changes that may invalidate this resource. These
|
||||||
|
* configuration changes can be obtained from {@link android.util.TypedValue}. Entities such as
|
||||||
|
* {@link android.animation.Animator} also provide a changing configuration method to include
|
||||||
|
* their dependencies (e.g. An AnimatorSet's changing configuration is the union of the
|
||||||
|
* changing configurations of each Animator in the set)
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
abstract public class ConstantState<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a bit mask of configuration changes that will impact
|
||||||
|
* this resource (and thus require completely reloading it).
|
||||||
|
*/
|
||||||
|
abstract public int getChangingConfigurations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance without supplying resources the caller
|
||||||
|
* is running in.
|
||||||
|
*/
|
||||||
|
public abstract T newInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from its constant state. This
|
||||||
|
* must be implemented for resources that change based on the target
|
||||||
|
* density of their caller (that is depending on whether it is
|
||||||
|
* in compatibility mode).
|
||||||
|
*/
|
||||||
|
public T newInstance(Resources res) {
|
||||||
|
return newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from its constant state. This must be
|
||||||
|
* implemented for resources that can have a theme applied.
|
||||||
|
*/
|
||||||
|
public T newInstance(Resources res, Resources.Theme theme) {
|
||||||
|
return newInstance(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
512
src/api-impl/android/content/res/GradientColor.java
Normal file
512
src/api-impl/android/content/res/GradientColor.java
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
230
src/api-impl/android/content/res/ThemedResourceCache.java
Normal file
230
src/api-impl/android/content/res/ThemedResourceCache.java
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.content.res.Resources.Theme;
|
||||||
|
import android.content.res.Resources.ThemeKey;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.LongSparseArray;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data structure used for caching data against themes.
|
||||||
|
*
|
||||||
|
* @param <T> type of data to cache
|
||||||
|
*/
|
||||||
|
abstract class ThemedResourceCache<T> {
|
||||||
|
private ArrayMap<ThemeKey, LongSparseArray<WeakReference<T>>> mThemedEntries;
|
||||||
|
private LongSparseArray<WeakReference<T>> mUnthemedEntries;
|
||||||
|
private LongSparseArray<WeakReference<T>> mNullThemedEntries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new theme-dependent entry to the cache.
|
||||||
|
*
|
||||||
|
* @param key a key that uniquely identifies the entry
|
||||||
|
* @param theme the theme against which this entry was inflated, or
|
||||||
|
* {@code null} if the entry has no theme applied
|
||||||
|
* @param entry the entry to cache
|
||||||
|
*/
|
||||||
|
public void put(long key, @Nullable Theme theme, @NonNull T entry) {
|
||||||
|
put(key, theme, entry, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new entry to the cache.
|
||||||
|
*
|
||||||
|
* @param key a key that uniquely identifies the entry
|
||||||
|
* @param theme the theme against which this entry was inflated, or
|
||||||
|
* {@code null} if the entry has no theme applied
|
||||||
|
* @param entry the entry to cache
|
||||||
|
* @param usesTheme {@code true} if the entry is affected theme changes,
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
public void put(long key, @Nullable Theme theme, @NonNull T entry, boolean usesTheme) {
|
||||||
|
if (entry == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
final LongSparseArray<WeakReference<T>> entries;
|
||||||
|
if (!usesTheme) {
|
||||||
|
entries = getUnthemedLocked(true);
|
||||||
|
} else {
|
||||||
|
entries = getThemedLocked(theme, true);
|
||||||
|
}
|
||||||
|
if (entries != null) {
|
||||||
|
entries.put(key, new WeakReference<>(entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an entry from the cache.
|
||||||
|
*
|
||||||
|
* @param key a key that uniquely identifies the entry
|
||||||
|
* @param theme the theme where the entry will be used
|
||||||
|
* @return a cached entry, or {@code null} if not in the cache
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public T get(long key, @Nullable Theme theme) {
|
||||||
|
// The themed (includes null-themed) and unthemed caches are mutually
|
||||||
|
// exclusive, so we'll give priority to whichever one we think we'll
|
||||||
|
// hit first. Since most of the framework drawables are themed, that's
|
||||||
|
// probably going to be the themed cache.
|
||||||
|
synchronized (this) {
|
||||||
|
final LongSparseArray<WeakReference<T>> themedEntries = getThemedLocked(theme, false);
|
||||||
|
if (themedEntries != null) {
|
||||||
|
final WeakReference<T> themedEntry = themedEntries.get(key);
|
||||||
|
if (themedEntry != null) {
|
||||||
|
return themedEntry.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final LongSparseArray<WeakReference<T>> unthemedEntries = getUnthemedLocked(false);
|
||||||
|
if (unthemedEntries != null) {
|
||||||
|
final WeakReference<T> unthemedEntry = unthemedEntries.get(key);
|
||||||
|
if (unthemedEntry != null) {
|
||||||
|
return unthemedEntry.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prunes cache entries that have been invalidated by a configuration
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param configChanges a bitmask of configuration changes
|
||||||
|
*/
|
||||||
|
public void onConfigurationChange(int configChanges) {
|
||||||
|
prune(configChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a cached entry has been invalidated by a configuration
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param entry a cached entry
|
||||||
|
* @param configChanges a non-zero bitmask of configuration changes
|
||||||
|
* @return {@code true} if the entry is invalid, {@code false} otherwise
|
||||||
|
*/
|
||||||
|
protected abstract boolean shouldInvalidateEntry(@NonNull T entry, int configChanges);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cached data for the specified theme, optionally creating a
|
||||||
|
* new entry if one does not already exist.
|
||||||
|
*
|
||||||
|
* @param t the theme for which to return cached data
|
||||||
|
* @param create {@code true} to create an entry if one does not already
|
||||||
|
* exist, {@code false} otherwise
|
||||||
|
* @return the cached data for the theme, or {@code null} if the cache is
|
||||||
|
* empty and {@code create} was {@code false}
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private LongSparseArray<WeakReference<T>> getThemedLocked(@Nullable Theme t, boolean create) {
|
||||||
|
if (t == null) {
|
||||||
|
if (mNullThemedEntries == null && create) {
|
||||||
|
mNullThemedEntries = new LongSparseArray<>(1);
|
||||||
|
}
|
||||||
|
return mNullThemedEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mThemedEntries == null) {
|
||||||
|
if (create) {
|
||||||
|
mThemedEntries = new ArrayMap<>(1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final ThemeKey key = t.getKey();
|
||||||
|
LongSparseArray<WeakReference<T>> cache = mThemedEntries.get(key);
|
||||||
|
if (cache == null && create) {
|
||||||
|
cache = new LongSparseArray<>(1);
|
||||||
|
|
||||||
|
final ThemeKey keyClone = key.clone();
|
||||||
|
mThemedEntries.put(keyClone, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the theme-agnostic cached data.
|
||||||
|
*
|
||||||
|
* @param create {@code true} to create an entry if one does not already
|
||||||
|
* exist, {@code false} otherwise
|
||||||
|
* @return the theme-agnostic cached data, or {@code null} if the cache is
|
||||||
|
* empty and {@code create} was {@code false}
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private LongSparseArray<WeakReference<T>> getUnthemedLocked(boolean create) {
|
||||||
|
if (mUnthemedEntries == null && create) {
|
||||||
|
mUnthemedEntries = new LongSparseArray<>(1);
|
||||||
|
}
|
||||||
|
return mUnthemedEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prunes cache entries affected by configuration changes or where weak
|
||||||
|
* references have expired.
|
||||||
|
*
|
||||||
|
* @param configChanges a bitmask of configuration changes, or {@code 0} to
|
||||||
|
* simply prune missing weak references
|
||||||
|
* @return {@code true} if the cache is completely empty after pruning
|
||||||
|
*/
|
||||||
|
private boolean prune(int configChanges) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (mThemedEntries != null) {
|
||||||
|
for (int i = mThemedEntries.size() - 1; i >= 0; i--) {
|
||||||
|
if (pruneEntriesLocked(mThemedEntries.valueAt(i), configChanges)) {
|
||||||
|
mThemedEntries.removeAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pruneEntriesLocked(mNullThemedEntries, configChanges);
|
||||||
|
pruneEntriesLocked(mUnthemedEntries, configChanges);
|
||||||
|
|
||||||
|
return mThemedEntries == null && mNullThemedEntries == null && mUnthemedEntries == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pruneEntriesLocked(@Nullable LongSparseArray<WeakReference<T>> entries,
|
||||||
|
int configChanges) {
|
||||||
|
if (entries == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = entries.size() - 1; i >= 0; i--) {
|
||||||
|
final WeakReference<T> ref = entries.valueAt(i);
|
||||||
|
if (ref == null || pruneEntryLocked(ref.get(), configChanges)) {
|
||||||
|
entries.removeAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pruneEntryLocked(@Nullable T entry, int configChanges) {
|
||||||
|
return entry == null || (configChanges != 0 && shouldInvalidateEntry(entry, configChanges));
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -8,5 +8,11 @@ public class Shader {
|
|||||||
REPEAT
|
REPEAT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void init(long ni) {
|
||||||
|
}
|
||||||
|
|
||||||
public void setLocalMatrix(Matrix matrix) {}
|
public void setLocalMatrix(Matrix matrix) {}
|
||||||
|
|
||||||
|
|
||||||
|
protected void copyLocalMatrix(Shader dest) {}
|
||||||
}
|
}
|
||||||
|
|||||||
110
src/api-impl/android/graphics/SweepGradient.java
Normal file
110
src/api-impl/android/graphics/SweepGradient.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2007 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
public class SweepGradient extends Shader {
|
||||||
|
|
||||||
|
private static final int TYPE_COLORS_AND_POSITIONS = 1;
|
||||||
|
private static final int TYPE_COLOR_START_AND_COLOR_END = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of the LinearGradient: can be either TYPE_COLORS_AND_POSITIONS or
|
||||||
|
* TYPE_COLOR_START_AND_COLOR_END.
|
||||||
|
*/
|
||||||
|
private int mType;
|
||||||
|
|
||||||
|
private float mCx;
|
||||||
|
private float mCy;
|
||||||
|
private int[] mColors;
|
||||||
|
private float[] mPositions;
|
||||||
|
private int mColor0;
|
||||||
|
private int mColor1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subclass of Shader that draws a sweep gradient around a center point.
|
||||||
|
*
|
||||||
|
* @param cx The x-coordinate of the center
|
||||||
|
* @param cy The y-coordinate of the center
|
||||||
|
* @param colors The colors to be distributed between around the center.
|
||||||
|
* There must be at least 2 colors in the array.
|
||||||
|
* @param positions May be NULL. The relative position of
|
||||||
|
* each corresponding color in the colors array, beginning
|
||||||
|
* with 0 and ending with 1.0. If the values are not
|
||||||
|
* monotonic, the drawing may produce unexpected results.
|
||||||
|
* If positions is NULL, then the colors are automatically
|
||||||
|
* spaced evenly.
|
||||||
|
*/
|
||||||
|
public SweepGradient(float cx, float cy,
|
||||||
|
int colors[], float positions[]) {
|
||||||
|
if (colors.length < 2) {
|
||||||
|
throw new IllegalArgumentException("needs >= 2 number of colors");
|
||||||
|
}
|
||||||
|
if (positions != null && colors.length != positions.length) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"color and position arrays must be of equal length");
|
||||||
|
}
|
||||||
|
mType = TYPE_COLORS_AND_POSITIONS;
|
||||||
|
mCx = cx;
|
||||||
|
mCy = cy;
|
||||||
|
mColors = colors;
|
||||||
|
mPositions = positions;
|
||||||
|
init(nativeCreate1(cx, cy, colors, positions));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subclass of Shader that draws a sweep gradient around a center point.
|
||||||
|
*
|
||||||
|
* @param cx The x-coordinate of the center
|
||||||
|
* @param cy The y-coordinate of the center
|
||||||
|
* @param color0 The color to use at the start of the sweep
|
||||||
|
* @param color1 The color to use at the end of the sweep
|
||||||
|
*/
|
||||||
|
public SweepGradient(float cx, float cy, int color0, int color1) {
|
||||||
|
mType = TYPE_COLOR_START_AND_COLOR_END;
|
||||||
|
mCx = cx;
|
||||||
|
mCy = cy;
|
||||||
|
mColor0 = color0;
|
||||||
|
mColor1 = color1;
|
||||||
|
init(nativeCreate2(cx, cy, color0, color1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
//@Override
|
||||||
|
protected Shader copy() {
|
||||||
|
final SweepGradient copy;
|
||||||
|
switch (mType) {
|
||||||
|
case TYPE_COLORS_AND_POSITIONS:
|
||||||
|
copy = new SweepGradient(mCx, mCy, mColors.clone(),
|
||||||
|
mPositions != null ? mPositions.clone() : null);
|
||||||
|
break;
|
||||||
|
case TYPE_COLOR_START_AND_COLOR_END:
|
||||||
|
copy = new SweepGradient(mCx, mCy, mColor0, mColor1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("SweepGradient should be created with either "
|
||||||
|
+
|
||||||
|
"colors and positions or start color and end color");
|
||||||
|
}
|
||||||
|
copyLocalMatrix(copy);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native long nativeCreate1(float x, float y, int colors[], float positions[]);
|
||||||
|
private static native long nativeCreate2(float x, float y, int color0, int color1);
|
||||||
|
}
|
||||||
299
src/api-impl/android/util/MathUtils.java
Normal file
299
src/api-impl/android/util/MathUtils.java
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.util;
|
||||||
|
|
||||||
|
//import android.compat.annotation.UnsupportedAppUsage;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that contains utility methods related to numbers.
|
||||||
|
*
|
||||||
|
* @hide Pending API council approval
|
||||||
|
*/
|
||||||
|
public final class MathUtils {
|
||||||
|
private static final float DEG_TO_RAD = 3.1415926f / 180.0f;
|
||||||
|
private static final float RAD_TO_DEG = 180.0f / 3.1415926f;
|
||||||
|
|
||||||
|
private MathUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//@UnsupportedAppUsage
|
||||||
|
public static float abs(float v) {
|
||||||
|
return v > 0 ? v : -v;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@UnsupportedAppUsage
|
||||||
|
public static int constrain(int amount, int low, int high) {
|
||||||
|
return amount < low ? low : (amount > high ? high : amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long constrain(long amount, long low, long high) {
|
||||||
|
return amount < low ? low : (amount > high ? high : amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@UnsupportedAppUsage
|
||||||
|
public static float constrain(float amount, float low, float high) {
|
||||||
|
return amount < low ? low : (amount > high ? high : amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float log(float a) {
|
||||||
|
return (float)Math.log(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float exp(float a) {
|
||||||
|
return (float)Math.exp(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float pow(float a, float b) {
|
||||||
|
return (float)Math.pow(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float sqrt(float a) {
|
||||||
|
return (float)Math.sqrt(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float max(float a, float b) {
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@UnsupportedAppUsage
|
||||||
|
public static float max(int a, int b) {
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float max(float a, float b, float c) {
|
||||||
|
return a > b ? (a > c ? a : c) : (b > c ? b : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float max(int a, int b, int c) {
|
||||||
|
return a > b ? (a > c ? a : c) : (b > c ? b : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float min(float a, float b) {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float min(int a, int b) {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float min(float a, float b, float c) {
|
||||||
|
return a < b ? (a < c ? a : c) : (b < c ? b : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float min(int a, int b, int c) {
|
||||||
|
return a < b ? (a < c ? a : c) : (b < c ? b : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float dist(float x1, float y1, float x2, float y2) {
|
||||||
|
final float x = (x2 - x1);
|
||||||
|
final float y = (y2 - y1);
|
||||||
|
return (float)Math.hypot(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) {
|
||||||
|
final float x = (x2 - x1);
|
||||||
|
final float y = (y2 - y1);
|
||||||
|
final float z = (z2 - z1);
|
||||||
|
return (float)Math.sqrt(x * x + y * y + z * z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float mag(float a, float b) {
|
||||||
|
return (float)Math.hypot(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float mag(float a, float b, float c) {
|
||||||
|
return (float)Math.sqrt(a * a + b * b + c * c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float sq(float v) {
|
||||||
|
return v * v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float dot(float v1x, float v1y, float v2x, float v2y) {
|
||||||
|
return v1x * v2x + v1y * v2y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float cross(float v1x, float v1y, float v2x, float v2y) {
|
||||||
|
return v1x * v2y - v1y * v2x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float radians(float degrees) {
|
||||||
|
return degrees * DEG_TO_RAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float degrees(float radians) {
|
||||||
|
return radians * RAD_TO_DEG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float acos(float value) {
|
||||||
|
return (float)Math.acos(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float asin(float value) {
|
||||||
|
return (float)Math.asin(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float atan(float value) {
|
||||||
|
return (float)Math.atan(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float atan2(float a, float b) {
|
||||||
|
return (float)Math.atan2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float tan(float angle) {
|
||||||
|
return (float)Math.tan(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@UnsupportedAppUsage
|
||||||
|
public static float lerp(float start, float stop, float amount) {
|
||||||
|
return start + (stop - start) * amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float lerp(int start, int stop, float amount) {
|
||||||
|
return lerp((float)start, (float)stop, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the interpolation scalar (s) that satisfies the equation: {@code value = }{@link
|
||||||
|
* #lerp}{@code (a, b, s)}
|
||||||
|
*
|
||||||
|
* <p>If {@code a == b}, then this function will return 0.
|
||||||
|
*/
|
||||||
|
public static float lerpInv(float a, float b, float value) {
|
||||||
|
return a != b ? ((value - a) / (b - a)) : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the single argument constrained between [0.0, 1.0].
|
||||||
|
*/
|
||||||
|
public static float saturate(float value) {
|
||||||
|
return constrain(value, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the saturated (constrained between [0, 1]) result of {@link #lerpInv}.
|
||||||
|
*/
|
||||||
|
public static float lerpInvSat(float a, float b, float value) {
|
||||||
|
return saturate(lerpInv(a, b, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an interpolated angle in degrees between a set of start and end
|
||||||
|
* angles.
|
||||||
|
* <p>
|
||||||
|
* Unlike {@link #lerp(float, float, float)}, the direction and distance of
|
||||||
|
* travel is determined by the shortest angle between the start and end
|
||||||
|
* angles. For example, if the starting angle is 0 and the ending angle is
|
||||||
|
* 350, then the interpolated angle will be in the range [0,-10] rather
|
||||||
|
* than [0,350].
|
||||||
|
*
|
||||||
|
* @param start the starting angle in degrees
|
||||||
|
* @param end the ending angle in degrees
|
||||||
|
* @param amount the position between start and end in the range [0,1]
|
||||||
|
* where 0 is the starting angle and 1 is the ending angle
|
||||||
|
* @return the interpolated angle in degrees
|
||||||
|
*/
|
||||||
|
public static float lerpDeg(float start, float end, float amount) {
|
||||||
|
final float minAngle = (((end - start) + 180) % 360) - 180;
|
||||||
|
return minAngle * amount + start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float norm(float start, float stop, float value) {
|
||||||
|
return (value - start) / (stop - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) {
|
||||||
|
return maxStart + (maxStop - maxStart) * ((value - minStart) / (minStop - minStart));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates a value in [rangeMin, rangeMax] that maps value in [valueMin, valueMax] to
|
||||||
|
* returnVal in [rangeMin, rangeMax].
|
||||||
|
* <p>
|
||||||
|
* Always returns a constrained value in the range [rangeMin, rangeMax], even if value is
|
||||||
|
* outside [valueMin, valueMax].
|
||||||
|
* <p>
|
||||||
|
* Eg:
|
||||||
|
* constrainedMap(0f, 100f, 0f, 1f, 0.5f) = 50f
|
||||||
|
* constrainedMap(20f, 200f, 10f, 20f, 20f) = 200f
|
||||||
|
* constrainedMap(20f, 200f, 10f, 20f, 50f) = 200f
|
||||||
|
* constrainedMap(10f, 50f, 10f, 20f, 5f) = 10f
|
||||||
|
*
|
||||||
|
* @param rangeMin minimum of the range that should be returned.
|
||||||
|
* @param rangeMax maximum of the range that should be returned.
|
||||||
|
* @param valueMin minimum of range to map {@code value} to.
|
||||||
|
* @param valueMax maximum of range to map {@code value} to.
|
||||||
|
* @param value to map to the range [{@code valueMin}, {@code valueMax}]. Note, can be outside
|
||||||
|
* this range, resulting in a clamped value.
|
||||||
|
* @return the mapped value, constrained to [{@code rangeMin}, {@code rangeMax}.
|
||||||
|
*/
|
||||||
|
public static float constrainedMap(
|
||||||
|
float rangeMin, float rangeMax, float valueMin, float valueMax, float value) {
|
||||||
|
return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform Hermite interpolation between two values.
|
||||||
|
* Eg:
|
||||||
|
* smoothStep(0, 0.5f, 0.5f) = 1f
|
||||||
|
* smoothStep(0, 0.5f, 0.25f) = 0.5f
|
||||||
|
*
|
||||||
|
* @param start Left edge.
|
||||||
|
* @param end Right edge.
|
||||||
|
* @param x A value between {@code start} and {@code end}.
|
||||||
|
* @return A number between 0 and 1 representing where {@code x} is in the interpolation.
|
||||||
|
*/
|
||||||
|
public static float smoothStep(float start, float end, float x) {
|
||||||
|
return constrain((x - start) / (end - start), 0f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sum of the two parameters, or throws an exception if the resulting sum would
|
||||||
|
* cause an overflow or underflow.
|
||||||
|
* @throws IllegalArgumentException when overflow or underflow would occur.
|
||||||
|
*/
|
||||||
|
public static int addOrThrow(int a, int b) throws IllegalArgumentException {
|
||||||
|
if (b == 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b > 0 && a <= (Integer.MAX_VALUE - b)) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b < 0 && a >= (Integer.MIN_VALUE - b)) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Addition overflow: " + a + " + " + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize a {@link Rect} so one size would be {@param largestSide}.
|
||||||
|
*
|
||||||
|
* @param outToResize Rectangle that will be resized.
|
||||||
|
* @param largestSide Size of the largest side.
|
||||||
|
*/
|
||||||
|
public static void fitRect(Rect outToResize, int largestSide) {
|
||||||
|
if (outToResize.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float maxSize = Math.max(outToResize.width(), outToResize.height());
|
||||||
|
outToResize.scale(largestSide / maxSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
165
src/api-impl/android/util/Pools.java
Normal file
165
src/api-impl/android/util/Pools.java
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for crating pools of objects. An example use looks like this:
|
||||||
|
* <pre>
|
||||||
|
* public class MyPooledClass {
|
||||||
|
*
|
||||||
|
* private static final SynchronizedPool<MyPooledClass> sPool =
|
||||||
|
* new SynchronizedPool<MyPooledClass>(10);
|
||||||
|
*
|
||||||
|
* public static MyPooledClass obtain() {
|
||||||
|
* MyPooledClass instance = sPool.acquire();
|
||||||
|
* return (instance != null) ? instance : new MyPooledClass();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* public void recycle() {
|
||||||
|
* // Clear state if needed.
|
||||||
|
* sPool.release(this);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* . . .
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class Pools {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for managing a pool of objects.
|
||||||
|
*
|
||||||
|
* @param <T> The pooled type.
|
||||||
|
*/
|
||||||
|
public static interface Pool<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return An instance from the pool if such, null otherwise.
|
||||||
|
*/
|
||||||
|
public T acquire();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release an instance to the pool.
|
||||||
|
*
|
||||||
|
* @param instance The instance to release.
|
||||||
|
* @return Whether the instance was put in the pool.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException If the instance is already in the pool.
|
||||||
|
*/
|
||||||
|
public boolean release(T instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pools() {
|
||||||
|
/* do nothing - hiding constructor */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple (non-synchronized) pool of objects.
|
||||||
|
*
|
||||||
|
* @param <T> The pooled type.
|
||||||
|
*/
|
||||||
|
public static class SimplePool<T> implements Pool<T> {
|
||||||
|
private final Object[] mPool;
|
||||||
|
|
||||||
|
private int mPoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param maxPoolSize The max pool size.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException If the max pool size is less than zero.
|
||||||
|
*/
|
||||||
|
public SimplePool(int maxPoolSize) {
|
||||||
|
if (maxPoolSize <= 0) {
|
||||||
|
throw new IllegalArgumentException("The max pool size must be > 0");
|
||||||
|
}
|
||||||
|
mPool = new Object[maxPoolSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T acquire() {
|
||||||
|
if (mPoolSize > 0) {
|
||||||
|
final int lastPooledIndex = mPoolSize - 1;
|
||||||
|
T instance = (T)mPool[lastPooledIndex];
|
||||||
|
mPool[lastPooledIndex] = null;
|
||||||
|
mPoolSize--;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(T instance) {
|
||||||
|
if (isInPool(instance)) {
|
||||||
|
throw new IllegalStateException("Already in the pool!");
|
||||||
|
}
|
||||||
|
if (mPoolSize < mPool.length) {
|
||||||
|
mPool[mPoolSize] = instance;
|
||||||
|
mPoolSize++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInPool(T instance) {
|
||||||
|
for (int i = 0; i < mPoolSize; i++) {
|
||||||
|
if (mPool[i] == instance) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronized) pool of objects.
|
||||||
|
*
|
||||||
|
* @param <T> The pooled type.
|
||||||
|
*/
|
||||||
|
public static class SynchronizedPool<T> extends SimplePool<T> {
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param maxPoolSize The max pool size.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException If the max pool size is less than zero.
|
||||||
|
*/
|
||||||
|
public SynchronizedPool(int maxPoolSize) {
|
||||||
|
super(maxPoolSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T acquire() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
return super.acquire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(T element) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
return super.release(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -210,6 +210,17 @@ public class TypedValue {
|
|||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link #TYPE_NULL} data indicating the value was not specified.
|
||||||
|
*/
|
||||||
|
public static final int DATA_NULL_UNDEFINED = 0;
|
||||||
|
/**
|
||||||
|
* {@link #TYPE_NULL} data indicating the value was explicitly set to null.
|
||||||
|
*/
|
||||||
|
public static final int DATA_NULL_EMPTY = 1;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If {@link #density} is equal to this value, then the density should be
|
* If {@link #density} is equal to this value, then the density should be
|
||||||
* treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
|
* treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ package com.android.internal.util;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class GrowingArrayUtils {
|
public final class GrowingArrayUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends an element to the end of the array, growing the array if there is no more room.
|
* Appends an element to the end of the array, growing the array if there is no more room.
|
||||||
* @param array The array to which to append the element. This must NOT be null.
|
* @param array The array to which to append the element. This must NOT be null.
|
||||||
@@ -38,10 +39,11 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static <T> T[] append(T[] array, int currentSize, T element) {
|
public static <T> T[] append(T[] array, int currentSize, T element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 > array.length) {
|
if (currentSize + 1 > array.length) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T[] newArray = ArrayUtils.newUnpaddedArray(
|
T[] newArray = ArrayUtils.newUnpaddedArray(
|
||||||
(Class<T>) array.getClass().getComponentType(), growSize(currentSize));
|
(Class<T>)array.getClass().getComponentType(), growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, currentSize);
|
System.arraycopy(array, 0, newArray, 0, currentSize);
|
||||||
array = newArray;
|
array = newArray;
|
||||||
}
|
}
|
||||||
@@ -54,6 +56,7 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static int[] append(int[] array, int currentSize, int element) {
|
public static int[] append(int[] array, int currentSize, int element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 > array.length) {
|
if (currentSize + 1 > array.length) {
|
||||||
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
|
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, currentSize);
|
System.arraycopy(array, 0, newArray, 0, currentSize);
|
||||||
@@ -68,6 +71,7 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static long[] append(long[] array, int currentSize, long element) {
|
public static long[] append(long[] array, int currentSize, long element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 > array.length) {
|
if (currentSize + 1 > array.length) {
|
||||||
long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
|
long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, currentSize);
|
System.arraycopy(array, 0, newArray, 0, currentSize);
|
||||||
@@ -82,6 +86,7 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean[] append(boolean[] array, int currentSize, boolean element) {
|
public static boolean[] append(boolean[] array, int currentSize, boolean element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 > array.length) {
|
if (currentSize + 1 > array.length) {
|
||||||
boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
|
boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, currentSize);
|
System.arraycopy(array, 0, newArray, 0, currentSize);
|
||||||
@@ -91,6 +96,21 @@ public final class GrowingArrayUtils {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive float version of {@link #append(Object[], int, Object)}.
|
||||||
|
*/
|
||||||
|
public static float[] append(float[] array, int currentSize, float element) {
|
||||||
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
|
if (currentSize + 1 > array.length) {
|
||||||
|
float[] newArray = ArrayUtils.newUnpaddedFloatArray(growSize(currentSize));
|
||||||
|
System.arraycopy(array, 0, newArray, 0, currentSize);
|
||||||
|
array = newArray;
|
||||||
|
}
|
||||||
|
array[currentSize] = element;
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts an element into the array at the specified index, growing the array if there is no
|
* Inserts an element into the array at the specified index, growing the array if there is no
|
||||||
* more room.
|
* more room.
|
||||||
@@ -104,14 +124,16 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static <T> T[] insert(T[] array, int currentSize, int index, T element) {
|
public static <T> T[] insert(T[] array, int currentSize, int index, T element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 <= array.length) {
|
if (currentSize + 1 <= array.length) {
|
||||||
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
||||||
array[index] = element;
|
array[index] = element;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T[] newArray = ArrayUtils.newUnpaddedArray((Class<T>)array.getClass().getComponentType(),
|
T[] newArray = ArrayUtils.newUnpaddedArray((Class<T>)array.getClass().getComponentType(),
|
||||||
growSize(currentSize));
|
growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, index);
|
System.arraycopy(array, 0, newArray, 0, index);
|
||||||
newArray[index] = element;
|
newArray[index] = element;
|
||||||
System.arraycopy(array, index, newArray, index + 1, array.length - index);
|
System.arraycopy(array, index, newArray, index + 1, array.length - index);
|
||||||
@@ -123,11 +145,13 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static int[] insert(int[] array, int currentSize, int index, int element) {
|
public static int[] insert(int[] array, int currentSize, int index, int element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 <= array.length) {
|
if (currentSize + 1 <= array.length) {
|
||||||
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
||||||
array[index] = element;
|
array[index] = element;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
|
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, index);
|
System.arraycopy(array, 0, newArray, 0, index);
|
||||||
newArray[index] = element;
|
newArray[index] = element;
|
||||||
@@ -140,11 +164,13 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static long[] insert(long[] array, int currentSize, int index, long element) {
|
public static long[] insert(long[] array, int currentSize, int index, long element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 <= array.length) {
|
if (currentSize + 1 <= array.length) {
|
||||||
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
||||||
array[index] = element;
|
array[index] = element;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
|
long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, index);
|
System.arraycopy(array, 0, newArray, 0, index);
|
||||||
newArray[index] = element;
|
newArray[index] = element;
|
||||||
@@ -157,11 +183,13 @@ public final class GrowingArrayUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean[] insert(boolean[] array, int currentSize, int index, boolean element) {
|
public static boolean[] insert(boolean[] array, int currentSize, int index, boolean element) {
|
||||||
assert currentSize <= array.length;
|
assert currentSize <= array.length;
|
||||||
|
|
||||||
if (currentSize + 1 <= array.length) {
|
if (currentSize + 1 <= array.length) {
|
||||||
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
System.arraycopy(array, index, array, index + 1, currentSize - index);
|
||||||
array[index] = element;
|
array[index] = element;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
|
boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
|
||||||
System.arraycopy(array, 0, newArray, 0, index);
|
System.arraycopy(array, 0, newArray, 0, index);
|
||||||
newArray[index] = element;
|
newArray[index] = element;
|
||||||
@@ -177,6 +205,7 @@ public final class GrowingArrayUtils {
|
|||||||
public static int growSize(int currentSize) {
|
public static int growSize(int currentSize) {
|
||||||
return currentSize <= 4 ? 8 : currentSize * 2;
|
return currentSize <= 4 ? 8 : currentSize * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uninstantiable
|
// Uninstantiable
|
||||||
private GrowingArrayUtils() {}
|
private GrowingArrayUtils() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,9 +118,13 @@ srcs = [
|
|||||||
'android/content/res/AssetManager.java',
|
'android/content/res/AssetManager.java',
|
||||||
'android/content/res/ColorStateList.java',
|
'android/content/res/ColorStateList.java',
|
||||||
'android/content/res/CompatibilityInfo.java',
|
'android/content/res/CompatibilityInfo.java',
|
||||||
|
'android/content/res/ComplexColor.java',
|
||||||
'android/content/res/Configuration.java',
|
'android/content/res/Configuration.java',
|
||||||
|
'android/content/res/ConfigurationBoundResourceCache.java',
|
||||||
|
'android/content/res/GradientColor.java',
|
||||||
'android/content/res/Resources.java',
|
'android/content/res/Resources.java',
|
||||||
'android/content/res/StringBlock.java',
|
'android/content/res/StringBlock.java',
|
||||||
|
'android/content/res/ThemedResourceCache.java',
|
||||||
'android/content/res/TypedArray.java',
|
'android/content/res/TypedArray.java',
|
||||||
'android/content/res/XmlBlock.java',
|
'android/content/res/XmlBlock.java',
|
||||||
'android/content/res/XmlResourceParser.java',
|
'android/content/res/XmlResourceParser.java',
|
||||||
@@ -210,6 +214,7 @@ srcs = [
|
|||||||
'android/graphics/RectF.java',
|
'android/graphics/RectF.java',
|
||||||
'android/graphics/Region.java',
|
'android/graphics/Region.java',
|
||||||
'android/graphics/Shader.java',
|
'android/graphics/Shader.java',
|
||||||
|
'android/graphics/SweepGradient.java',
|
||||||
'android/graphics/Typeface.java',
|
'android/graphics/Typeface.java',
|
||||||
'android/graphics/Xfermode.java',
|
'android/graphics/Xfermode.java',
|
||||||
'android/graphics/drawable/Animatable.java',
|
'android/graphics/drawable/Animatable.java',
|
||||||
@@ -426,6 +431,7 @@ srcs = [
|
|||||||
'android/util/JsonScope.java',
|
'android/util/JsonScope.java',
|
||||||
'android/util/JsonToken.java',
|
'android/util/JsonToken.java',
|
||||||
'android/util/JsonWriter.java',
|
'android/util/JsonWriter.java',
|
||||||
|
'android/util/MathUtils.java',
|
||||||
'android/util/LayoutDirection.java',
|
'android/util/LayoutDirection.java',
|
||||||
'android/util/Log.java',
|
'android/util/Log.java',
|
||||||
'android/util/LongSparseArray.java',
|
'android/util/LongSparseArray.java',
|
||||||
|
|||||||
Reference in New Issue
Block a user