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
refactor source tree organization, switch to meson
This commit is contained in:
38
src/api-impl/android/util/AndroidException.java
Normal file
38
src/api-impl/android/util/AndroidException.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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;
|
||||
|
||||
/**
|
||||
* Base class for all checked exceptions thrown by the Android frameworks.
|
||||
*/
|
||||
public class AndroidException extends Exception {
|
||||
public AndroidException() {
|
||||
}
|
||||
|
||||
public AndroidException(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public AndroidException(String name, Throwable cause) {
|
||||
super(name, cause);
|
||||
}
|
||||
|
||||
public AndroidException(Exception cause) {
|
||||
super(cause);
|
||||
}
|
||||
};
|
||||
|
||||
38
src/api-impl/android/util/AndroidRuntimeException.java
Normal file
38
src/api-impl/android/util/AndroidRuntimeException.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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;
|
||||
|
||||
/**
|
||||
* Base class for all unchecked exceptions thrown by the Android frameworks.
|
||||
*/
|
||||
public class AndroidRuntimeException extends RuntimeException {
|
||||
public AndroidRuntimeException() {
|
||||
}
|
||||
|
||||
public AndroidRuntimeException(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public AndroidRuntimeException(String name, Throwable cause) {
|
||||
super(name, cause);
|
||||
}
|
||||
|
||||
public AndroidRuntimeException(Exception cause) {
|
||||
super(cause);
|
||||
}
|
||||
};
|
||||
|
||||
829
src/api-impl/android/util/ArrayMap.java
Normal file
829
src/api-impl/android/util/ArrayMap.java
Normal file
File diff suppressed because it is too large
Load Diff
338
src/api-impl/android/util/AttributeSet.java
Normal file
338
src/api-impl/android/util/AttributeSet.java
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* A collection of attributes, as found associated with a tag in an XML
|
||||
* document. Often you will not want to use this interface directly, instead
|
||||
* passing it to {@link android.content.res.Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
|
||||
* Resources.Theme.obtainStyledAttributes()}
|
||||
* which will take care of parsing the attributes for you. In particular,
|
||||
* the Resources API will convert resource references (attribute values such as
|
||||
* "@string/my_label" in the original XML) to the desired type
|
||||
* for you; if you use AttributeSet directly then you will need to manually
|
||||
* check for resource references
|
||||
* (with {@link #getAttributeResourceValue(int, int)}) and do the resource
|
||||
* lookup yourself if needed. Direct use of AttributeSet also prevents the
|
||||
* application of themes and styles when retrieving attribute values.
|
||||
*
|
||||
* <p>This interface provides an efficient mechanism for retrieving
|
||||
* data from compiled XML files, which can be retrieved for a particular
|
||||
* XmlPullParser through {@link Xml#asAttributeSet
|
||||
* Xml.asAttributeSet()}. Normally this will return an implementation
|
||||
* of the interface that works on top of a generic XmlPullParser, however it
|
||||
* is more useful in conjunction with compiled XML resources:
|
||||
*
|
||||
* <pre>
|
||||
* XmlPullParser parser = resources.getXml(myResource);
|
||||
* AttributeSet attributes = Xml.asAttributeSet(parser);</pre>
|
||||
*
|
||||
* <p>The implementation returned here, unlike using
|
||||
* the implementation on top of a generic XmlPullParser,
|
||||
* is highly optimized by retrieving pre-computed information that was
|
||||
* generated by aapt when compiling your resources. For example,
|
||||
* the {@link #getAttributeFloatValue(int, float)} method returns a floating
|
||||
* point number previous stored in the compiled resource instead of parsing
|
||||
* at runtime the string originally in the XML file.
|
||||
*
|
||||
* <p>This interface also provides additional information contained in the
|
||||
* compiled XML resource that is not available in a normal XML file, such
|
||||
* as {@link #getAttributeNameResource(int)} which returns the resource
|
||||
* identifier associated with a particular XML attribute name.
|
||||
*
|
||||
* @see XmlPullParser
|
||||
*/
|
||||
public interface AttributeSet {
|
||||
/**
|
||||
* Returns the number of attributes available in the set.
|
||||
*
|
||||
* <p>See also {@link XmlPullParser#getAttributeCount XmlPullParser.getAttributeCount()},
|
||||
* which this method corresponds to when parsing a compiled XML file.</p>
|
||||
*
|
||||
* @return A positive integer, or 0 if the set is empty.
|
||||
*/
|
||||
public int getAttributeCount();
|
||||
|
||||
/**
|
||||
* Returns the namespace of the specified attribute.
|
||||
*
|
||||
* <p>See also {@link XmlPullParser#getAttributeNamespace XmlPullParser.getAttributeNamespace()},
|
||||
* which this method corresponds to when parsing a compiled XML file.</p>
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
*
|
||||
* @return A String containing the namespace of the attribute, or null if th
|
||||
* attribute cannot be found.
|
||||
*/
|
||||
/* default */ String getAttributeNamespace (int index);/* {
|
||||
// This is a new method since the first interface definition, so add stub impl.
|
||||
return null;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Returns the name of the specified attribute.
|
||||
*
|
||||
* <p>See also {@link XmlPullParser#getAttributeName XmlPullParser.getAttributeName()},
|
||||
* which this method corresponds to when parsing a compiled XML file.</p>
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
*
|
||||
* @return A String containing the name of the attribute, or null if the
|
||||
* attribute cannot be found.
|
||||
*/
|
||||
public String getAttributeName(int index);
|
||||
|
||||
/**
|
||||
* Returns the value of the specified attribute as a string representation.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
*
|
||||
* @return A String containing the value of the attribute, or null if the
|
||||
* attribute cannot be found.
|
||||
*/
|
||||
public String getAttributeValue(int index);
|
||||
|
||||
/**
|
||||
* Returns the value of the specified attribute as a string representation.
|
||||
* The lookup is performed using the attribute name.
|
||||
*
|
||||
* @param namespace The namespace of the attribute to get the value from.
|
||||
* @param name The name of the attribute to get the value from.
|
||||
*
|
||||
* @return A String containing the value of the attribute, or null if the
|
||||
* attribute cannot be found.
|
||||
*/
|
||||
public String getAttributeValue(String namespace, String name);
|
||||
|
||||
/**
|
||||
* Returns a description of the current position of the attribute set.
|
||||
* For instance, if the attribute set is loaded from an XML document,
|
||||
* the position description could indicate the current line number.
|
||||
*
|
||||
* @return A string representation of the current position in the set,
|
||||
* may be null.
|
||||
*/
|
||||
public String getPositionDescription();
|
||||
|
||||
/**
|
||||
* Return the resource ID associated with the given attribute name. This
|
||||
* will be the identifier for an attribute resource, which can be used by
|
||||
* styles. Returns 0 if there is no resource associated with this
|
||||
* attribute.
|
||||
*
|
||||
* <p>Note that this is different than {@link #getAttributeResourceValue}
|
||||
* in that it returns a resource identifier for the attribute name; the
|
||||
* other method returns this attribute's value as a resource identifier.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
*
|
||||
* @return The resource identifier, 0 if none.
|
||||
*/
|
||||
public int getAttributeNameResource(int index);
|
||||
|
||||
/**
|
||||
* Return the index of the value of 'attribute' in the list 'options'.
|
||||
*
|
||||
* @param namespace Namespace of attribute to retrieve.
|
||||
* @param attribute Name of attribute to retrieve.
|
||||
* @param options List of strings whose values we are checking against.
|
||||
* @param defaultValue Value returned if attribute doesn't exist or no
|
||||
* match is found.
|
||||
*
|
||||
* @return Index in to 'options' or defaultValue.
|
||||
*/
|
||||
public int getAttributeListValue(String namespace, String attribute,
|
||||
String[] options, int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the boolean value of 'attribute'.
|
||||
*
|
||||
* @param namespace Namespace of attribute to retrieve.
|
||||
* @param attribute The attribute to retrieve.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public boolean getAttributeBooleanValue(String namespace, String attribute,
|
||||
boolean defaultValue);
|
||||
|
||||
/**
|
||||
* Return the value of 'attribute' as a resource identifier.
|
||||
*
|
||||
* <p>Note that this is different than {@link #getAttributeNameResource}
|
||||
* in that it returns the value contained in this attribute as a
|
||||
* resource identifier (i.e., a value originally of the form
|
||||
* "@package:type/resource"); the other method returns a resource
|
||||
* identifier that identifies the name of the attribute.
|
||||
*
|
||||
* @param namespace Namespace of attribute to retrieve.
|
||||
* @param attribute The attribute to retrieve.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public int getAttributeResourceValue(String namespace, String attribute,
|
||||
int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the integer value of 'attribute'.
|
||||
*
|
||||
* @param namespace Namespace of attribute to retrieve.
|
||||
* @param attribute The attribute to retrieve.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public int getAttributeIntValue(String namespace, String attribute,
|
||||
int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the boolean value of 'attribute' that is formatted as an
|
||||
* unsigned value. In particular, the formats 0xn...n and #n...n are
|
||||
* handled.
|
||||
*
|
||||
* @param namespace Namespace of attribute to retrieve.
|
||||
* @param attribute The attribute to retrieve.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public int getAttributeUnsignedIntValue(String namespace, String attribute,
|
||||
int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the float value of 'attribute'.
|
||||
*
|
||||
* @param namespace Namespace of attribute to retrieve.
|
||||
* @param attribute The attribute to retrieve.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public float getAttributeFloatValue(String namespace, String attribute,
|
||||
float defaultValue);
|
||||
|
||||
/**
|
||||
* Return the index of the value of attribute at 'index' in the list
|
||||
* 'options'.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
* @param options List of strings whose values we are checking against.
|
||||
* @param defaultValue Value returned if attribute doesn't exist or no
|
||||
* match is found.
|
||||
*
|
||||
* @return Index in to 'options' or defaultValue.
|
||||
*/
|
||||
public int getAttributeListValue(int index, String[] options, int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the boolean value of attribute at 'index'.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public boolean getAttributeBooleanValue(int index, boolean defaultValue);
|
||||
|
||||
/**
|
||||
* Return the value of attribute at 'index' as a resource identifier.
|
||||
*
|
||||
* <p>Note that this is different than {@link #getAttributeNameResource}
|
||||
* in that it returns the value contained in this attribute as a
|
||||
* resource identifier (i.e., a value originally of the form
|
||||
* "@package:type/resource"); the other method returns a resource
|
||||
* identifier that identifies the name of the attribute.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public int getAttributeResourceValue(int index, int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the integer value of attribute at 'index'.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public int getAttributeIntValue(int index, int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the integer value of attribute at 'index' that is formatted as an
|
||||
* unsigned value. In particular, the formats 0xn...n and #n...n are
|
||||
* handled.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public int getAttributeUnsignedIntValue(int index, int defaultValue);
|
||||
|
||||
/**
|
||||
* Return the float value of attribute at 'index'.
|
||||
*
|
||||
* @param index Index of the desired attribute, 0...count-1.
|
||||
* @param defaultValue What to return if the attribute isn't found.
|
||||
*
|
||||
* @return Resulting value.
|
||||
*/
|
||||
public float getAttributeFloatValue(int index, float defaultValue);
|
||||
|
||||
/**
|
||||
* Return the value of the "id" attribute or null if there is not one.
|
||||
* Equivalent to getAttributeValue(null, "id").
|
||||
*
|
||||
* @return The id attribute's value or null.
|
||||
*/
|
||||
public String getIdAttribute();
|
||||
|
||||
/**
|
||||
* Return the value of the "class" attribute or null if there is not one.
|
||||
* Equivalent to getAttributeValue(null, "class").
|
||||
*
|
||||
* @return The class attribute's value or null.
|
||||
*/
|
||||
public String getClassAttribute();
|
||||
|
||||
/**
|
||||
* Return the integer value of the "id" attribute or defaultValue if there
|
||||
* is none.
|
||||
* Equivalent to getAttributeResourceValue(null, "id", defaultValue);
|
||||
*
|
||||
* @param defaultValue What to return if the "id" attribute isn't found.
|
||||
* @return int Resulting value.
|
||||
*/
|
||||
public int getIdAttributeResourceValue(int defaultValue);
|
||||
|
||||
/**
|
||||
|
||||
* Return the value of the "style" attribute or 0 if there is not one.
|
||||
* Equivalent to getAttributeResourceValue(null, "style").
|
||||
*
|
||||
* @return The style attribute's resource identifier or 0.
|
||||
*/
|
||||
public int getStyleAttribute();
|
||||
}
|
||||
|
||||
741
src/api-impl/android/util/Base64.java
Normal file
741
src/api-impl/android/util/Base64.java
Normal file
File diff suppressed because it is too large
Load Diff
30
src/api-impl/android/util/Base64DataException.java
Normal file
30
src/api-impl/android/util/Base64DataException.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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 java.io.IOException;
|
||||
|
||||
/**
|
||||
* This exception is thrown by {@link Base64InputStream} or {@link Base64OutputStream}
|
||||
* when an error is detected in the data being decoded. This allows problems with the base64 data
|
||||
* to be disambiguated from errors in the underlying streams (e.g. actual connection errors.)
|
||||
*/
|
||||
public class Base64DataException extends IOException {
|
||||
public Base64DataException(String detailMessage) {
|
||||
super(detailMessage);
|
||||
}
|
||||
}
|
||||
153
src/api-impl/android/util/Base64InputStream.java
Normal file
153
src/api-impl/android/util/Base64InputStream.java
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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 java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* An InputStream that does Base64 decoding on the data read through
|
||||
* it.
|
||||
*/
|
||||
public class Base64InputStream extends FilterInputStream {
|
||||
private final Base64.Coder coder;
|
||||
|
||||
private static byte[] EMPTY = new byte[0];
|
||||
|
||||
private static final int BUFFER_SIZE = 2048;
|
||||
private boolean eof;
|
||||
private byte[] inputBuffer;
|
||||
private int outputStart;
|
||||
private int outputEnd;
|
||||
|
||||
/**
|
||||
* An InputStream that performs Base64 decoding on the data read
|
||||
* from the wrapped stream.
|
||||
*
|
||||
* @param in the InputStream to read the source data from
|
||||
* @param flags bit flags for controlling the decoder; see the
|
||||
* constants in {@link Base64}
|
||||
*/
|
||||
public Base64InputStream(InputStream in, int flags) {
|
||||
this(in, flags, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs Base64 encoding or decoding on the data read from the
|
||||
* wrapped InputStream.
|
||||
*
|
||||
* @param in the InputStream to read the source data from
|
||||
* @param flags bit flags for controlling the decoder; see the
|
||||
* constants in {@link Base64}
|
||||
* @param encode true to encode, false to decode
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Base64InputStream(InputStream in, int flags, boolean encode) {
|
||||
super(in);
|
||||
eof = false;
|
||||
inputBuffer = new byte[BUFFER_SIZE];
|
||||
if (encode) {
|
||||
coder = new Base64.Encoder(flags, null);
|
||||
} else {
|
||||
coder = new Base64.Decoder(flags, null);
|
||||
}
|
||||
coder.output = new byte[coder.maxOutputSize(BUFFER_SIZE)];
|
||||
outputStart = 0;
|
||||
outputEnd = 0;
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void mark(int readlimit) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
inputBuffer = null;
|
||||
}
|
||||
|
||||
public int available() {
|
||||
return outputEnd - outputStart;
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException {
|
||||
if (outputStart >= outputEnd) {
|
||||
refill();
|
||||
}
|
||||
if (outputStart >= outputEnd) {
|
||||
return 0;
|
||||
}
|
||||
long bytes = Math.min(n, outputEnd-outputStart);
|
||||
outputStart += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (outputStart >= outputEnd) {
|
||||
refill();
|
||||
}
|
||||
if (outputStart >= outputEnd) {
|
||||
return -1;
|
||||
} else {
|
||||
return coder.output[outputStart++] & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (outputStart >= outputEnd) {
|
||||
refill();
|
||||
}
|
||||
if (outputStart >= outputEnd) {
|
||||
return -1;
|
||||
}
|
||||
int bytes = Math.min(len, outputEnd-outputStart);
|
||||
System.arraycopy(coder.output, outputStart, b, off, bytes);
|
||||
outputStart += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from the input stream into inputBuffer, then
|
||||
* decode/encode it into the empty coder.output, and reset the
|
||||
* outputStart and outputEnd pointers.
|
||||
*/
|
||||
private void refill() throws IOException {
|
||||
if (eof) return;
|
||||
int bytesRead = in.read(inputBuffer);
|
||||
boolean success;
|
||||
if (bytesRead == -1) {
|
||||
eof = true;
|
||||
success = coder.process(EMPTY, 0, 0, true);
|
||||
} else {
|
||||
success = coder.process(inputBuffer, 0, bytesRead, false);
|
||||
}
|
||||
if (!success) {
|
||||
throw new Base64DataException("bad base-64");
|
||||
}
|
||||
outputEnd = coder.op;
|
||||
outputStart = 0;
|
||||
}
|
||||
}
|
||||
155
src/api-impl/android/util/Base64OutputStream.java
Normal file
155
src/api-impl/android/util/Base64OutputStream.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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 java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An OutputStream that does Base64 encoding on the data written to
|
||||
* it, writing the resulting data to another OutputStream.
|
||||
*/
|
||||
public class Base64OutputStream extends FilterOutputStream {
|
||||
private final Base64.Coder coder;
|
||||
private final int flags;
|
||||
|
||||
private byte[] buffer = null;
|
||||
private int bpos = 0;
|
||||
|
||||
private static byte[] EMPTY = new byte[0];
|
||||
|
||||
/**
|
||||
* Performs Base64 encoding on the data written to the stream,
|
||||
* writing the encoded data to another OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the encoded data to
|
||||
* @param flags bit flags for controlling the encoder; see the
|
||||
* constants in {@link Base64}
|
||||
*/
|
||||
public Base64OutputStream(OutputStream out, int flags) {
|
||||
this(out, flags, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs Base64 encoding or decoding on the data written to the
|
||||
* stream, writing the encoded/decoded data to another
|
||||
* OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the encoded data to
|
||||
* @param flags bit flags for controlling the encoder; see the
|
||||
* constants in {@link Base64}
|
||||
* @param encode true to encode, false to decode
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Base64OutputStream(OutputStream out, int flags, boolean encode) {
|
||||
super(out);
|
||||
this.flags = flags;
|
||||
if (encode) {
|
||||
coder = new Base64.Encoder(flags, null);
|
||||
} else {
|
||||
coder = new Base64.Decoder(flags, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
// To avoid invoking the encoder/decoder routines for single
|
||||
// bytes, we buffer up calls to write(int) in an internal
|
||||
// byte array to transform them into writes of decently-sized
|
||||
// arrays.
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new byte[1024];
|
||||
}
|
||||
if (bpos >= buffer.length) {
|
||||
// internal buffer full; write it out.
|
||||
internalWrite(buffer, 0, bpos, false);
|
||||
bpos = 0;
|
||||
}
|
||||
buffer[bpos++] = (byte) b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush any buffered data from calls to write(int). Needed
|
||||
* before doing a write(byte[], int, int) or a close().
|
||||
*/
|
||||
private void flushBuffer() throws IOException {
|
||||
if (bpos > 0) {
|
||||
internalWrite(buffer, 0, bpos, false);
|
||||
bpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
if (len <= 0) return;
|
||||
flushBuffer();
|
||||
internalWrite(b, off, len, false);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
IOException thrown = null;
|
||||
try {
|
||||
flushBuffer();
|
||||
internalWrite(EMPTY, 0, 0, true);
|
||||
} catch (IOException e) {
|
||||
thrown = e;
|
||||
}
|
||||
|
||||
try {
|
||||
if ((flags & Base64.NO_CLOSE) == 0) {
|
||||
out.close();
|
||||
} else {
|
||||
out.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (thrown != null) {
|
||||
thrown = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (thrown != null) {
|
||||
throw thrown;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given bytes to the encoder/decoder.
|
||||
*
|
||||
* @param finish true if this is the last batch of input, to cause
|
||||
* encoder/decoder state to be finalized.
|
||||
*/
|
||||
private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException {
|
||||
coder.output = embiggen(coder.output, coder.maxOutputSize(len));
|
||||
if (!coder.process(b, off, len, finish)) {
|
||||
throw new Base64DataException("bad base-64");
|
||||
}
|
||||
out.write(coder.output, 0, coder.op);
|
||||
}
|
||||
|
||||
/**
|
||||
* If b.length is at least len, return b. Otherwise return a new
|
||||
* byte array of length len.
|
||||
*/
|
||||
private byte[] embiggen(byte[] b, int len) {
|
||||
if (b == null || b.length < len) {
|
||||
return new byte[len];
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/api-impl/android/util/ContainerHelpers.java
Normal file
63
src/api-impl/android/util/ContainerHelpers.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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;
|
||||
|
||||
class ContainerHelpers {
|
||||
static final boolean[] EMPTY_BOOLEANS = new boolean[0];
|
||||
static final int[] EMPTY_INTS = new int[0];
|
||||
static final long[] EMPTY_LONGS = new long[0];
|
||||
static final Object[] EMPTY_OBJECTS = new Object[0];
|
||||
|
||||
// This is Arrays.binarySearch(), but doesn't do any argument validation.
|
||||
static int binarySearch(int[] array, int size, int value) {
|
||||
int lo = 0;
|
||||
int hi = size - 1;
|
||||
|
||||
while (lo <= hi) {
|
||||
final int mid = (lo + hi) >>> 1;
|
||||
final int midVal = array[mid];
|
||||
|
||||
if (midVal < value) {
|
||||
lo = mid + 1;
|
||||
} else if (midVal > value) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
return mid; // value found
|
||||
}
|
||||
}
|
||||
return ~lo; // value not present
|
||||
}
|
||||
|
||||
static int binarySearch(long[] array, int size, long value) {
|
||||
int lo = 0;
|
||||
int hi = size - 1;
|
||||
|
||||
while (lo <= hi) {
|
||||
final int mid = (lo + hi) >>> 1;
|
||||
final long midVal = array[mid];
|
||||
|
||||
if (midVal < value) {
|
||||
lo = mid + 1;
|
||||
} else if (midVal > value) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
return mid; // value found
|
||||
}
|
||||
}
|
||||
return ~lo; // value not present
|
||||
}
|
||||
}
|
||||
127
src/api-impl/android/util/DecompiledXmlResourceParser.java
Normal file
127
src/api-impl/android/util/DecompiledXmlResourceParser.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package android.util;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.kxml2.io.KXmlParser;
|
||||
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import android.util.AttributeSet;
|
||||
|
||||
public class DecompiledXmlResourceParser extends KXmlParser implements AttributeSet, AutoCloseable {
|
||||
public int getAttributeCount() {
|
||||
return this.getAttributeCount();
|
||||
}
|
||||
|
||||
public String getAttributeNamespace (int index) {
|
||||
return this.getAttributeNamespace(index);
|
||||
}
|
||||
|
||||
public String getAttributeName(int index) {
|
||||
return this.getAttributeName(index);
|
||||
}
|
||||
|
||||
public String getAttributeValue(int index) {
|
||||
return this.getAttributeValue(index);
|
||||
}
|
||||
|
||||
public String getAttributeValue(String namespace, String name) {
|
||||
return this.getAttributeValue(namespace, name);
|
||||
}
|
||||
|
||||
public String getPositionDescription() {
|
||||
return this.getPositionDescription();
|
||||
}
|
||||
|
||||
public int getAttributeNameResource(int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getAttributeListValue(String namespace, String attribute,
|
||||
String[] options, int defaultValue) {
|
||||
return XmlUtils.convertValueToList(
|
||||
getAttributeValue(namespace, attribute), options, defaultValue);
|
||||
}
|
||||
|
||||
public boolean getAttributeBooleanValue(String namespace, String attribute,
|
||||
boolean defaultValue) {
|
||||
return XmlUtils.convertValueToBoolean(
|
||||
getAttributeValue(namespace, attribute), defaultValue);
|
||||
}
|
||||
|
||||
public int getAttributeResourceValue(String namespace, String attribute,
|
||||
int defaultValue) {
|
||||
return XmlUtils.convertValueToInt(
|
||||
getAttributeValue(namespace, attribute), defaultValue);
|
||||
}
|
||||
|
||||
public int getAttributeIntValue(String namespace, String attribute,
|
||||
int defaultValue) {
|
||||
return XmlUtils.convertValueToInt(
|
||||
getAttributeValue(namespace, attribute), defaultValue);
|
||||
}
|
||||
|
||||
public int getAttributeUnsignedIntValue(String namespace, String attribute,
|
||||
int defaultValue) {
|
||||
return XmlUtils.convertValueToUnsignedInt(
|
||||
getAttributeValue(namespace, attribute), defaultValue);
|
||||
}
|
||||
|
||||
public float getAttributeFloatValue(String namespace, String attribute,
|
||||
float defaultValue) {
|
||||
String s = getAttributeValue(namespace, attribute);
|
||||
if (s != null) {
|
||||
return Float.parseFloat(s);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public int getAttributeListValue(int index,
|
||||
String[] options, int defaultValue) {
|
||||
return XmlUtils.convertValueToList(
|
||||
getAttributeValue(index), options, defaultValue);
|
||||
}
|
||||
|
||||
public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
|
||||
return XmlUtils.convertValueToBoolean(
|
||||
getAttributeValue(index), defaultValue);
|
||||
}
|
||||
|
||||
public int getAttributeResourceValue(int index, int defaultValue) {
|
||||
return XmlUtils.convertValueToInt(
|
||||
getAttributeValue(index), defaultValue);
|
||||
}
|
||||
|
||||
public int getAttributeIntValue(int index, int defaultValue) {
|
||||
return XmlUtils.convertValueToInt(
|
||||
getAttributeValue(index), defaultValue);
|
||||
}
|
||||
|
||||
public int getAttributeUnsignedIntValue(int index, int defaultValue) {
|
||||
return XmlUtils.convertValueToUnsignedInt(
|
||||
getAttributeValue(index), defaultValue);
|
||||
}
|
||||
|
||||
public float getAttributeFloatValue(int index, float defaultValue) {
|
||||
String s = getAttributeValue(index);
|
||||
if (s != null) {
|
||||
return Float.parseFloat(s);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public String getIdAttribute() {
|
||||
return getAttributeValue(null, "id");
|
||||
}
|
||||
|
||||
public String getClassAttribute() {
|
||||
return getAttributeValue(null, "class");
|
||||
}
|
||||
|
||||
public int getIdAttributeResourceValue(int defaultValue) {
|
||||
return getAttributeResourceValue(null, "id", defaultValue);
|
||||
}
|
||||
|
||||
public int getStyleAttribute() {
|
||||
return getAttributeResourceValue(null, "style", 0);
|
||||
}
|
||||
}
|
||||
299
src/api-impl/android/util/DisplayMetrics.java
Normal file
299
src/api-impl/android/util/DisplayMetrics.java
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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;
|
||||
|
||||
/**
|
||||
* A structure describing general information about a display, such as its
|
||||
* size, density, and font scaling.
|
||||
* <p>To access the DisplayMetrics members, initialize an object like this:</p>
|
||||
* <pre> DisplayMetrics metrics = new DisplayMetrics();
|
||||
* getWindowManager().getDefaultDisplay().getMetrics(metrics);</pre>
|
||||
*/
|
||||
public class DisplayMetrics {
|
||||
/**
|
||||
* Standard quantized DPI for low-density screens.
|
||||
*/
|
||||
public static final int DENSITY_LOW = 120;
|
||||
|
||||
/**
|
||||
* Standard quantized DPI for medium-density screens.
|
||||
*/
|
||||
public static final int DENSITY_MEDIUM = 160;
|
||||
|
||||
/**
|
||||
* This is a secondary density, added for some common screen configurations.
|
||||
* It is recommended that applications not generally target this as a first
|
||||
* class density -- that is, don't supply specific graphics for this
|
||||
* density, instead allow the platform to scale from other densities
|
||||
* (typically {@link #DENSITY_HIGH}) as
|
||||
* appropriate. In most cases (such as using bitmaps in
|
||||
* {@link android.graphics.drawable.Drawable}) the platform
|
||||
* can perform this scaling at load time, so the only cost is some slight
|
||||
* startup runtime overhead.
|
||||
*
|
||||
* <p>This density was original introduced to correspond with a
|
||||
* 720p TV screen: the density for 1080p televisions is
|
||||
* {@link #DENSITY_XHIGH}, and the value here provides the same UI
|
||||
* size for a TV running at 720p. It has also found use in 7" tablets,
|
||||
* when these devices have 1280x720 displays.
|
||||
*/
|
||||
public static final int DENSITY_TV = 213;
|
||||
|
||||
/**
|
||||
* Standard quantized DPI for high-density screens.
|
||||
*/
|
||||
public static final int DENSITY_HIGH = 240;
|
||||
|
||||
/**
|
||||
* Standard quantized DPI for extra-high-density screens.
|
||||
*/
|
||||
public static final int DENSITY_XHIGH = 320;
|
||||
|
||||
/**
|
||||
* Intermediate density for screens that sit somewhere between
|
||||
* {@link #DENSITY_XHIGH} (320dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
|
||||
* This is not a density that applications should target, instead relying
|
||||
* on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
|
||||
*/
|
||||
public static final int DENSITY_400 = 400;
|
||||
|
||||
/**
|
||||
* Standard quantized DPI for extra-extra-high-density screens. Applications
|
||||
* should not generally worry about this density; relying on XHIGH graphics
|
||||
* being scaled up to it should be sufficient for almost all cases.
|
||||
*/
|
||||
public static final int DENSITY_XXHIGH = 480;
|
||||
|
||||
/**
|
||||
* Standard quantized DPI for extra-extra-extra-high-density screens. Applications
|
||||
* should not generally worry about this density; relying on XHIGH graphics
|
||||
* being scaled up to it should be sufficient for almost all cases. A typical
|
||||
* use of this density would be 4K television screens -- 3840x2160, which
|
||||
* is 2x a traditional HD 1920x1080 screen which runs at DENSITY_XHIGH.
|
||||
*/
|
||||
public static final int DENSITY_XXXHIGH = 640;
|
||||
|
||||
/**
|
||||
* The reference density used throughout the system.
|
||||
*/
|
||||
public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
|
||||
|
||||
/**
|
||||
* Scaling factor to convert a density in DPI units to the density scale.
|
||||
* @hide
|
||||
*/
|
||||
public static final float DENSITY_DEFAULT_SCALE = 1.0f / DENSITY_DEFAULT;
|
||||
|
||||
/**
|
||||
* The device's density.
|
||||
* @hide because eventually this should be able to change while
|
||||
* running, so shouldn't be a constant.
|
||||
* @deprecated There is no longer a static density; you can find the
|
||||
* density for a display in {@link #densityDpi}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int DENSITY_DEVICE = getDeviceDensity();
|
||||
|
||||
/**
|
||||
* The absolute width of the display in pixels.
|
||||
*/
|
||||
public int widthPixels;
|
||||
/**
|
||||
* The absolute height of the display in pixels.
|
||||
*/
|
||||
public int heightPixels;
|
||||
/**
|
||||
* The logical density of the display. This is a scaling factor for the
|
||||
* Density Independent Pixel unit, where one DIP is one pixel on an
|
||||
* approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
|
||||
* providing the baseline of the system's display. Thus on a 160dpi screen
|
||||
* this density value will be 1; on a 120 dpi screen it would be .75; etc.
|
||||
*
|
||||
* <p>This value does not exactly follow the real screen size (as given by
|
||||
* {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
|
||||
* the overall UI in steps based on gross changes in the display dpi. For
|
||||
* example, a 240x320 screen will have a density of 1 even if its width is
|
||||
* 1.8", 1.3", etc. However, if the screen resolution is increased to
|
||||
* 320x480 but the screen size remained 1.5"x2" then the density would be
|
||||
* increased (probably to 1.5).
|
||||
*
|
||||
* @see #DENSITY_DEFAULT
|
||||
*/
|
||||
public float density;
|
||||
/**
|
||||
* The screen density expressed as dots-per-inch. May be either
|
||||
* {@link #DENSITY_LOW}, {@link #DENSITY_MEDIUM}, or {@link #DENSITY_HIGH}.
|
||||
*/
|
||||
public int densityDpi;
|
||||
/**
|
||||
* A scaling factor for fonts displayed on the display. This is the same
|
||||
* as {@link #density}, except that it may be adjusted in smaller
|
||||
* increments at runtime based on a user preference for the font size.
|
||||
*/
|
||||
public float scaledDensity;
|
||||
/**
|
||||
* The exact physical pixels per inch of the screen in the X dimension.
|
||||
*/
|
||||
public float xdpi;
|
||||
/**
|
||||
* The exact physical pixels per inch of the screen in the Y dimension.
|
||||
*/
|
||||
public float ydpi;
|
||||
|
||||
/**
|
||||
* The reported display width prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public int noncompatWidthPixels;
|
||||
/**
|
||||
* The reported display height prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public int noncompatHeightPixels;
|
||||
/**
|
||||
* The reported display density prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public float noncompatDensity;
|
||||
/**
|
||||
* The reported display density prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public int noncompatDensityDpi;
|
||||
/**
|
||||
* The reported scaled density prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public float noncompatScaledDensity;
|
||||
/**
|
||||
* The reported display xdpi prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public float noncompatXdpi;
|
||||
/**
|
||||
* The reported display ydpi prior to any compatibility mode scaling
|
||||
* being applied.
|
||||
* @hide
|
||||
*/
|
||||
public float noncompatYdpi;
|
||||
|
||||
public DisplayMetrics() {
|
||||
setToDefaults();
|
||||
}
|
||||
|
||||
public void setTo(DisplayMetrics o) {
|
||||
widthPixels = o.widthPixels;
|
||||
heightPixels = o.heightPixels;
|
||||
density = o.density;
|
||||
densityDpi = o.densityDpi;
|
||||
scaledDensity = o.scaledDensity;
|
||||
xdpi = o.xdpi;
|
||||
ydpi = o.ydpi;
|
||||
noncompatWidthPixels = o.noncompatWidthPixels;
|
||||
noncompatHeightPixels = o.noncompatHeightPixels;
|
||||
noncompatDensity = o.noncompatDensity;
|
||||
noncompatDensityDpi = o.noncompatDensityDpi;
|
||||
noncompatScaledDensity = o.noncompatScaledDensity;
|
||||
noncompatXdpi = o.noncompatXdpi;
|
||||
noncompatYdpi = o.noncompatYdpi;
|
||||
}
|
||||
|
||||
public void setToDefaults() {
|
||||
widthPixels = 0;
|
||||
heightPixels = 0;
|
||||
density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
|
||||
densityDpi = DENSITY_DEVICE;
|
||||
scaledDensity = density;
|
||||
xdpi = DENSITY_DEVICE;
|
||||
ydpi = DENSITY_DEVICE;
|
||||
noncompatWidthPixels = widthPixels;
|
||||
noncompatHeightPixels = heightPixels;
|
||||
noncompatDensity = density;
|
||||
noncompatDensityDpi = densityDpi;
|
||||
noncompatScaledDensity = scaledDensity;
|
||||
noncompatXdpi = xdpi;
|
||||
noncompatYdpi = ydpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof DisplayMetrics && equals((DisplayMetrics)o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if these display metrics equal the other display metrics.
|
||||
*
|
||||
* @param other The display metrics with which to compare.
|
||||
* @return True if the display metrics are equal.
|
||||
*/
|
||||
public boolean equals(DisplayMetrics other) {
|
||||
return equalsPhysical(other)
|
||||
&& scaledDensity == other.scaledDensity
|
||||
&& noncompatScaledDensity == other.noncompatScaledDensity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the physical aspects of the two display metrics
|
||||
* are equal. This ignores the scaled density, which is a logical
|
||||
* attribute based on the current desired font size.
|
||||
*
|
||||
* @param other The display metrics with which to compare.
|
||||
* @return True if the display metrics are equal.
|
||||
* @hide
|
||||
*/
|
||||
public boolean equalsPhysical(DisplayMetrics other) {
|
||||
return other != null
|
||||
&& widthPixels == other.widthPixels
|
||||
&& heightPixels == other.heightPixels
|
||||
&& density == other.density
|
||||
&& densityDpi == other.densityDpi
|
||||
&& xdpi == other.xdpi
|
||||
&& ydpi == other.ydpi
|
||||
&& noncompatWidthPixels == other.noncompatWidthPixels
|
||||
&& noncompatHeightPixels == other.noncompatHeightPixels
|
||||
&& noncompatDensity == other.noncompatDensity
|
||||
&& noncompatDensityDpi == other.noncompatDensityDpi
|
||||
&& noncompatXdpi == other.noncompatXdpi
|
||||
&& noncompatYdpi == other.noncompatYdpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return widthPixels * heightPixels * densityDpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DisplayMetrics{density=" + density + ", width=" + widthPixels +
|
||||
", height=" + heightPixels + ", scaledDensity=" + scaledDensity +
|
||||
", xdpi=" + xdpi + ", ydpi=" + ydpi + "}";
|
||||
}
|
||||
|
||||
private static int getDeviceDensity() {
|
||||
// qemu.sf.lcd_density can be used to override ro.sf.lcd_density
|
||||
// when running in the emulator, allowing for dynamic configurations.
|
||||
// The reason for this is that ro.sf.lcd_density is write-once and is
|
||||
// set by the init process when it parses build.prop before anything else.
|
||||
return DENSITY_DEFAULT;
|
||||
}
|
||||
}
|
||||
48
src/api-impl/android/util/LayoutDirection.java
Normal file
48
src/api-impl/android/util/LayoutDirection.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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;
|
||||
|
||||
/**
|
||||
* A class for defining layout directions. A layout direction can be left-to-right (LTR)
|
||||
* or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default
|
||||
* language script of a locale.
|
||||
*/
|
||||
public final class LayoutDirection {
|
||||
|
||||
// No instantiation
|
||||
private LayoutDirection() {}
|
||||
|
||||
/**
|
||||
* Horizontal layout direction is from Left to Right.
|
||||
*/
|
||||
public static final int LTR = 0;
|
||||
|
||||
/**
|
||||
* Horizontal layout direction is from Right to Left.
|
||||
*/
|
||||
public static final int RTL = 1;
|
||||
|
||||
/**
|
||||
* Horizontal layout direction is inherited.
|
||||
*/
|
||||
public static final int INHERIT = 2;
|
||||
|
||||
/**
|
||||
* Horizontal layout direction is deduced from the default language script for the locale.
|
||||
*/
|
||||
public static final int LOCALE = 3;
|
||||
}
|
||||
359
src/api-impl/android/util/Log.java
Normal file
359
src/api-impl/android/util/Log.java
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* API for sending log output.
|
||||
*
|
||||
* <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()
|
||||
* methods.
|
||||
*
|
||||
* <p>The order in terms of verbosity, from least to most is
|
||||
* ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled
|
||||
* into an application except during development. Debug logs are compiled
|
||||
* in but stripped at runtime. Error, warning and info logs are always kept.
|
||||
*
|
||||
* <p><b>Tip:</b> A good convention is to declare a <code>TAG</code> constant
|
||||
* in your class:
|
||||
*
|
||||
* <pre>private static final String TAG = "MyActivity";</pre>
|
||||
*
|
||||
* and use that in subsequent calls to the log methods.
|
||||
* </p>
|
||||
*
|
||||
* <p><b>Tip:</b> Don't forget that when you make a call like
|
||||
* <pre>Log.v(TAG, "index=" + i);</pre>
|
||||
* that when you're building the string to pass into Log.d, the compiler uses a
|
||||
* StringBuilder and at least three allocations occur: the StringBuilder
|
||||
* itself, the buffer, and the String object. Realistically, there is also
|
||||
* another buffer allocation and copy, and even more pressure on the gc.
|
||||
* That means that if your log message is filtered out, you might be doing
|
||||
* significant work and incurring significant overhead.
|
||||
*/
|
||||
public final class Log {
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.v.
|
||||
*/
|
||||
public static final int VERBOSE = 2;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.d.
|
||||
*/
|
||||
public static final int DEBUG = 3;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.i.
|
||||
*/
|
||||
public static final int INFO = 4;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.w.
|
||||
*/
|
||||
public static final int WARN = 5;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.e.
|
||||
*/
|
||||
public static final int ERROR = 6;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method.
|
||||
*/
|
||||
public static final int ASSERT = 7;
|
||||
|
||||
/**
|
||||
* Exception class used to capture a stack trace in {@link #wtf}.
|
||||
*/
|
||||
private static class TerribleFailure extends Exception {
|
||||
TerribleFailure(String msg, Throwable cause) { super(msg, cause); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface to handle terrible failures from {@link #wtf}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public interface TerribleFailureHandler {
|
||||
void onTerribleFailure(String tag, TerribleFailure what);
|
||||
}
|
||||
|
||||
private static TerribleFailureHandler sWtfHandler = new TerribleFailureHandler() {
|
||||
public void onTerribleFailure(String tag, TerribleFailure what) {
|
||||
// TODO
|
||||
}
|
||||
};
|
||||
|
||||
private Log() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #VERBOSE} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int v(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #VERBOSE} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int v(String tag, String msg, Throwable tr) {
|
||||
return println_native(LOG_ID_MAIN, VERBOSE, tag, msg + '\n' + getStackTraceString(tr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #DEBUG} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int d(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #DEBUG} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int d(String tag, String msg, Throwable tr) {
|
||||
return println_native(LOG_ID_MAIN, DEBUG, tag, msg + '\n' + getStackTraceString(tr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an {@link #INFO} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int i(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, INFO, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #INFO} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int i(String tag, String msg, Throwable tr) {
|
||||
return println_native(LOG_ID_MAIN, INFO, tag, msg + '\n' + getStackTraceString(tr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #WARN} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int w(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, WARN, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #WARN} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int w(String tag, String msg, Throwable tr) {
|
||||
return println_native(LOG_ID_MAIN, WARN, tag, msg + '\n' + getStackTraceString(tr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see whether or not a log for the specified tag is loggable at the specified level.
|
||||
*
|
||||
* The default level of any tag is set to INFO. This means that any level above and including
|
||||
* INFO will be logged. Before you make any calls to a logging method you should check to see
|
||||
* if your tag should be logged. You can change the default level by setting a system property:
|
||||
* 'setprop log.tag.<YOUR_LOG_TAG> <LEVEL>'
|
||||
* Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will
|
||||
* turn off all logging for your tag. You can also create a local.prop file that with the
|
||||
* following in it:
|
||||
* 'log.tag.<YOUR_LOG_TAG>=<LEVEL>'
|
||||
* and place that in /data/local.prop.
|
||||
*
|
||||
* @param tag The tag to check.
|
||||
* @param level The level to check.
|
||||
* @return Whether or not that this is allowed to be logged.
|
||||
* @throws IllegalArgumentException is thrown if the tag.length() > 23.
|
||||
*/
|
||||
public static native boolean isLoggable(String tag, int level);
|
||||
|
||||
/*
|
||||
* Send a {@link #WARN} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int w(String tag, Throwable tr) {
|
||||
return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an {@link #ERROR} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int e(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, ERROR, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #ERROR} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int e(String tag, String msg, Throwable tr) {
|
||||
return println_native(LOG_ID_MAIN, ERROR, tag, msg + '\n' + getStackTraceString(tr));
|
||||
}
|
||||
|
||||
/**
|
||||
* What a Terrible Failure: Report a condition that should never happen.
|
||||
* The error will always be logged at level ASSERT with the call stack.
|
||||
* Depending on system configuration, a report may be added to the
|
||||
* {@link android.os.DropBoxManager} and/or the process may be terminated
|
||||
* immediately with an error dialog.
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int wtf(String tag, String msg) {
|
||||
return wtf(LOG_ID_MAIN, tag, msg, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #wtf(String, String)}, but also writes to the log the full
|
||||
* call stack.
|
||||
* @hide
|
||||
*/
|
||||
public static int wtfStack(String tag, String msg) {
|
||||
return wtf(LOG_ID_MAIN, tag, msg, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* What a Terrible Failure: Report an exception that should never happen.
|
||||
* Similar to {@link #wtf(String, String)}, with an exception to log.
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tr An exception to log.
|
||||
*/
|
||||
public static int wtf(String tag, Throwable tr) {
|
||||
return wtf(LOG_ID_MAIN, tag, tr.getMessage(), tr, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* What a Terrible Failure: Report an exception that should never happen.
|
||||
* Similar to {@link #wtf(String, Throwable)}, with a message as well.
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log. May be null.
|
||||
*/
|
||||
public static int wtf(String tag, String msg, Throwable tr) {
|
||||
return wtf(LOG_ID_MAIN, tag, msg, tr, false);
|
||||
}
|
||||
|
||||
static int wtf(int logId, String tag, String msg, Throwable tr, boolean localStack) {
|
||||
TerribleFailure what = new TerribleFailure(msg, tr);
|
||||
int bytes = println_native(logId, ASSERT, tag, msg + '\n'
|
||||
+ getStackTraceString(localStack ? what : tr));
|
||||
sWtfHandler.onTerribleFailure(tag, what);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the terrible failure handler, for testing.
|
||||
*
|
||||
* @return the old handler
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static TerribleFailureHandler setWtfHandler(TerribleFailureHandler handler) {
|
||||
if (handler == null) {
|
||||
throw new NullPointerException("handler == null");
|
||||
}
|
||||
TerribleFailureHandler oldHandler = sWtfHandler;
|
||||
sWtfHandler = handler;
|
||||
return oldHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handy function to get a loggable stack trace from a Throwable
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static String getStackTraceString(Throwable tr) {
|
||||
if (tr == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// This is to reduce the amount of log spew that apps do in the non-error
|
||||
// condition of the network being unavailable.
|
||||
Throwable t = tr;
|
||||
while (t != null) {
|
||||
if (t instanceof UnknownHostException) {
|
||||
return "";
|
||||
}
|
||||
t = t.getCause();
|
||||
}
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw, false);
|
||||
tr.printStackTrace(pw);
|
||||
pw.flush();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Low-level logging call.
|
||||
* @param priority The priority/type of this log message
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @return The number of bytes written.
|
||||
*/
|
||||
public static int println(int priority, String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, priority, tag, msg);
|
||||
}
|
||||
|
||||
/** @hide */ public static final int LOG_ID_MAIN = 0;
|
||||
/** @hide */ public static final int LOG_ID_RADIO = 1;
|
||||
/** @hide */ public static final int LOG_ID_EVENTS = 2;
|
||||
/** @hide */ public static final int LOG_ID_SYSTEM = 3;
|
||||
|
||||
/** @hide */ public static /*native*/ int println_native(int bufID,
|
||||
int priority, String tag, String msg) {
|
||||
String out = String.format("`¯´[%d][%d] [%s] : %s", bufID, priority, tag, msg);
|
||||
System.out.println(out);
|
||||
return out.getBytes().length;
|
||||
}
|
||||
}
|
||||
408
src/api-impl/android/util/LongSparseArray.java
Normal file
408
src/api-impl/android/util/LongSparseArray.java
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* 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 com.android.internal.util.ArrayUtils;
|
||||
|
||||
/**
|
||||
* SparseArray mapping longs to Objects. Unlike a normal array of Objects,
|
||||
* there can be gaps in the indices. It is intended to be more memory efficient
|
||||
* than using a HashMap to map Longs to Objects, both because it avoids
|
||||
* auto-boxing keys and its data structure doesn't rely on an extra entry object
|
||||
* for each mapping.
|
||||
*
|
||||
* <p>Note that this container keeps its mappings in an array data structure,
|
||||
* using a binary search to find keys. The implementation is not intended to be appropriate for
|
||||
* data structures
|
||||
* that may contain large numbers of items. It is generally slower than a traditional
|
||||
* HashMap, since lookups require a binary search and adds and removes require inserting
|
||||
* and deleting entries in the array. For containers holding up to hundreds of items,
|
||||
* the performance difference is not significant, less than 50%.</p>
|
||||
*
|
||||
* <p>To help with performance, the container includes an optimization when removing
|
||||
* keys: instead of compacting its array immediately, it leaves the removed entry marked
|
||||
* as deleted. The entry can then be re-used for the same key, or compacted later in
|
||||
* a single garbage collection step of all removed entries. This garbage collection will
|
||||
* need to be performed at any time the array needs to be grown or the the map size or
|
||||
* entry values are retrieved.</p>
|
||||
*
|
||||
* <p>It is possible to iterate over the items in this container using
|
||||
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
|
||||
* <code>keyAt(int)</code> with ascending values of the index will return the
|
||||
* keys in ascending order, or the values corresponding to the keys in ascending
|
||||
* order in the case of <code>valueAt(int)<code>.</p>
|
||||
*/
|
||||
public class LongSparseArray<E> implements Cloneable {
|
||||
private static final Object DELETED = new Object();
|
||||
private boolean mGarbage = false;
|
||||
|
||||
private long[] mKeys;
|
||||
private Object[] mValues;
|
||||
private int mSize;
|
||||
|
||||
/**
|
||||
* Creates a new LongSparseArray containing no mappings.
|
||||
*/
|
||||
public LongSparseArray() {
|
||||
this(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new LongSparseArray containing no mappings that will not
|
||||
* require any additional memory allocation to store the specified
|
||||
* number of mappings. If you supply an initial capacity of 0, the
|
||||
* sparse array will be initialized with a light-weight representation
|
||||
* not requiring any additional array allocations.
|
||||
*/
|
||||
public LongSparseArray(int initialCapacity) {
|
||||
if (initialCapacity == 0) {
|
||||
mKeys = ContainerHelpers.EMPTY_LONGS;
|
||||
mValues = ContainerHelpers.EMPTY_OBJECTS;
|
||||
} else {
|
||||
initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
|
||||
mKeys = new long[initialCapacity];
|
||||
mValues = new Object[initialCapacity];
|
||||
}
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public LongSparseArray<E> clone() {
|
||||
LongSparseArray<E> clone = null;
|
||||
try {
|
||||
clone = (LongSparseArray<E>) super.clone();
|
||||
clone.mKeys = mKeys.clone();
|
||||
clone.mValues = mValues.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
/* ignore */
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object mapped from the specified key, or <code>null</code>
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
public E get(long key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object mapped from the specified key, or the specified Object
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public E get(long key, E valueIfKeyNotFound) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i < 0 || mValues[i] == DELETED) {
|
||||
return valueIfKeyNotFound;
|
||||
} else {
|
||||
return (E) mValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping from the specified key, if there was any.
|
||||
*/
|
||||
public void delete(long key) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
if (mValues[i] != DELETED) {
|
||||
mValues[i] = DELETED;
|
||||
mGarbage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link #delete(long)}.
|
||||
*/
|
||||
public void remove(long key) {
|
||||
delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping at the specified index.
|
||||
*/
|
||||
public void removeAt(int index) {
|
||||
if (mValues[index] != DELETED) {
|
||||
mValues[index] = DELETED;
|
||||
mGarbage = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void gc() {
|
||||
// Log.e("SparseArray", "gc start with " + mSize);
|
||||
|
||||
int n = mSize;
|
||||
int o = 0;
|
||||
long[] keys = mKeys;
|
||||
Object[] values = mValues;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Object val = values[i];
|
||||
|
||||
if (val != DELETED) {
|
||||
if (i != o) {
|
||||
keys[o] = keys[i];
|
||||
values[o] = val;
|
||||
values[i] = null;
|
||||
}
|
||||
|
||||
o++;
|
||||
}
|
||||
}
|
||||
|
||||
mGarbage = false;
|
||||
mSize = o;
|
||||
|
||||
// Log.e("SparseArray", "gc end with " + mSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from the specified key to the specified value,
|
||||
* replacing the previous mapping from the specified key if there
|
||||
* was one.
|
||||
*/
|
||||
public void put(long key, E value) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
mValues[i] = value;
|
||||
} else {
|
||||
i = ~i;
|
||||
|
||||
if (i < mSize && mValues[i] == DELETED) {
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGarbage && mSize >= mKeys.length) {
|
||||
gc();
|
||||
|
||||
// Search again because indices may have changed.
|
||||
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
if (mSize >= mKeys.length) {
|
||||
int n = ArrayUtils.idealLongArraySize(mSize + 1);
|
||||
|
||||
long[] nkeys = new long[n];
|
||||
Object[] nvalues = new Object[n];
|
||||
|
||||
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
if (mSize - i != 0) {
|
||||
// Log.e("SparseArray", "move " + (mSize - i));
|
||||
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
|
||||
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
|
||||
}
|
||||
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
mSize++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings that this LongSparseArray
|
||||
* currently stores.
|
||||
*/
|
||||
public int size() {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the key from the <code>index</code>th key-value mapping that this
|
||||
* LongSparseArray stores.
|
||||
*
|
||||
* <p>The keys corresponding to indices in ascending order are guaranteed to
|
||||
* be in ascending order, e.g., <code>keyAt(0)</code> will return the
|
||||
* smallest key and <code>keyAt(size()-1)</code> will return the largest
|
||||
* key.</p>
|
||||
*/
|
||||
public long keyAt(int index) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return mKeys[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the value from the <code>index</code>th key-value mapping that this
|
||||
* LongSparseArray stores.
|
||||
*
|
||||
* <p>The values corresponding to indices in ascending order are guaranteed
|
||||
* to be associated with keys in ascending order, e.g.,
|
||||
* <code>valueAt(0)</code> will return the value associated with the
|
||||
* smallest key and <code>valueAt(size()-1)</code> will return the value
|
||||
* associated with the largest key.</p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public E valueAt(int index) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return (E) mValues[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, sets a new
|
||||
* value for the <code>index</code>th key-value mapping that this
|
||||
* LongSparseArray stores.
|
||||
*/
|
||||
public void setValueAt(int index, E value) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
mValues[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for which {@link #keyAt} would return the
|
||||
* specified key, or a negative number if the specified
|
||||
* key is not mapped.
|
||||
*/
|
||||
public int indexOfKey(long key) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index for which {@link #valueAt} would return the
|
||||
* specified key, or a negative number if no keys map to the
|
||||
* specified value.
|
||||
* Beware that this is a linear search, unlike lookups by key,
|
||||
* and that multiple keys can map to the same value and this will
|
||||
* find only one of them.
|
||||
*/
|
||||
public int indexOfValue(E value) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mValues[i] == value)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value mappings from this LongSparseArray.
|
||||
*/
|
||||
public void clear() {
|
||||
int n = mSize;
|
||||
Object[] values = mValues;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
values[i] = null;
|
||||
}
|
||||
|
||||
mSize = 0;
|
||||
mGarbage = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a key/value pair into the array, optimizing for the case where
|
||||
* the key is greater than all existing keys in the array.
|
||||
*/
|
||||
public void append(long key, E value) {
|
||||
if (mSize != 0 && key <= mKeys[mSize - 1]) {
|
||||
put(key, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGarbage && mSize >= mKeys.length) {
|
||||
gc();
|
||||
}
|
||||
|
||||
int pos = mSize;
|
||||
if (pos >= mKeys.length) {
|
||||
int n = ArrayUtils.idealLongArraySize(pos + 1);
|
||||
|
||||
long[] nkeys = new long[n];
|
||||
Object[] nvalues = new Object[n];
|
||||
|
||||
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
mKeys[pos] = key;
|
||||
mValues[pos] = value;
|
||||
mSize = pos + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation composes a string by iterating over its mappings. If
|
||||
* this map contains itself as a value, the string "(this Map)"
|
||||
* will appear in its place.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (size() <= 0) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(mSize * 28);
|
||||
buffer.append('{');
|
||||
for (int i=0; i<mSize; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
long key = keyAt(i);
|
||||
buffer.append(key);
|
||||
buffer.append('=');
|
||||
Object value = valueAt(i);
|
||||
if (value != this) {
|
||||
buffer.append(value);
|
||||
} else {
|
||||
buffer.append("(this Map)");
|
||||
}
|
||||
}
|
||||
buffer.append('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
559
src/api-impl/android/util/MapCollections.java
Normal file
559
src/api-impl/android/util/MapCollections.java
Normal file
File diff suppressed because it is too large
Load Diff
50
src/api-impl/android/util/PrefixPrinter.java
Normal file
50
src/api-impl/android/util/PrefixPrinter.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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;
|
||||
|
||||
/**
|
||||
* PrefixPrinter is a Printer which prefixes all lines with a given
|
||||
* prefix.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class PrefixPrinter implements Printer {
|
||||
private final Printer mPrinter;
|
||||
private final String mPrefix;
|
||||
|
||||
/**
|
||||
* Creates a new PrefixPrinter.
|
||||
*
|
||||
* <p>If prefix is null or empty, the provided printer is returned, rather
|
||||
* than making a prefixing printer.
|
||||
*/
|
||||
public static Printer create(Printer printer, String prefix) {
|
||||
if (prefix == null || prefix.equals("")) {
|
||||
return printer;
|
||||
}
|
||||
return new PrefixPrinter(printer, prefix);
|
||||
}
|
||||
|
||||
private PrefixPrinter(Printer printer, String prefix) {
|
||||
mPrinter = printer;
|
||||
mPrefix = prefix;
|
||||
}
|
||||
|
||||
public void println(String str) {
|
||||
mPrinter.println(mPrefix + str);
|
||||
}
|
||||
}
|
||||
31
src/api-impl/android/util/Printer.java
Normal file
31
src/api-impl/android/util/Printer.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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;
|
||||
|
||||
/**
|
||||
* Simple interface for printing text, allowing redirection to various
|
||||
* targets. Standard implementations are {@link android.util.LogPrinter},
|
||||
* {@link android.util.StringBuilderPrinter}, and
|
||||
* {@link android.util.PrintWriterPrinter}.
|
||||
*/
|
||||
public interface Printer {
|
||||
/**
|
||||
* Write a line of text to the output. There is no need to terminate
|
||||
* the given string with a newline.
|
||||
*/
|
||||
void println(String x);
|
||||
}
|
||||
99
src/api-impl/android/util/Slog.java
Normal file
99
src/api-impl/android/util/Slog.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final class Slog {
|
||||
|
||||
private Slog() {
|
||||
}
|
||||
|
||||
public static int v(String tag, String msg) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.VERBOSE, tag, msg);
|
||||
}
|
||||
|
||||
public static int v(String tag, String msg, Throwable tr) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.VERBOSE, tag,
|
||||
msg + '\n' + Log.getStackTraceString(tr));
|
||||
}
|
||||
|
||||
public static int d(String tag, String msg) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.DEBUG, tag, msg);
|
||||
}
|
||||
|
||||
public static int d(String tag, String msg, Throwable tr) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.DEBUG, tag,
|
||||
msg + '\n' + Log.getStackTraceString(tr));
|
||||
}
|
||||
|
||||
public static int i(String tag, String msg) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.INFO, tag, msg);
|
||||
}
|
||||
|
||||
public static int i(String tag, String msg, Throwable tr) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.INFO, tag,
|
||||
msg + '\n' + Log.getStackTraceString(tr));
|
||||
}
|
||||
|
||||
public static int w(String tag, String msg) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.WARN, tag, msg);
|
||||
}
|
||||
|
||||
public static int w(String tag, String msg, Throwable tr) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.WARN, tag,
|
||||
msg + '\n' + Log.getStackTraceString(tr));
|
||||
}
|
||||
|
||||
public static int w(String tag, Throwable tr) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.WARN, tag, Log.getStackTraceString(tr));
|
||||
}
|
||||
|
||||
public static int e(String tag, String msg) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.ERROR, tag, msg);
|
||||
}
|
||||
|
||||
public static int e(String tag, String msg, Throwable tr) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, Log.ERROR, tag,
|
||||
msg + '\n' + Log.getStackTraceString(tr));
|
||||
}
|
||||
|
||||
public static int wtf(String tag, String msg) {
|
||||
return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, false);
|
||||
}
|
||||
|
||||
public static int wtfStack(String tag, String msg) {
|
||||
return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, true);
|
||||
}
|
||||
|
||||
public static int wtf(String tag, Throwable tr) {
|
||||
return Log.wtf(Log.LOG_ID_SYSTEM, tag, tr.getMessage(), tr, false);
|
||||
}
|
||||
|
||||
public static int wtf(String tag, String msg, Throwable tr) {
|
||||
return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, tr, false);
|
||||
}
|
||||
|
||||
public static int println(int priority, String tag, String msg) {
|
||||
return Log.println_native(Log.LOG_ID_SYSTEM, priority, tag, msg);
|
||||
}
|
||||
}
|
||||
|
||||
423
src/api-impl/android/util/SparseArray.java
Normal file
423
src/api-impl/android/util/SparseArray.java
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 com.android.internal.util.ArrayUtils;
|
||||
|
||||
/**
|
||||
* SparseArrays map integers to Objects. Unlike a normal array of Objects,
|
||||
* there can be gaps in the indices. It is intended to be more memory efficient
|
||||
* than using a HashMap to map Integers to Objects, both because it avoids
|
||||
* auto-boxing keys and its data structure doesn't rely on an extra entry object
|
||||
* for each mapping.
|
||||
*
|
||||
* <p>Note that this container keeps its mappings in an array data structure,
|
||||
* using a binary search to find keys. The implementation is not intended to be appropriate for
|
||||
* data structures
|
||||
* that may contain large numbers of items. It is generally slower than a traditional
|
||||
* HashMap, since lookups require a binary search and adds and removes require inserting
|
||||
* and deleting entries in the array. For containers holding up to hundreds of items,
|
||||
* the performance difference is not significant, less than 50%.</p>
|
||||
*
|
||||
* <p>To help with performance, the container includes an optimization when removing
|
||||
* keys: instead of compacting its array immediately, it leaves the removed entry marked
|
||||
* as deleted. The entry can then be re-used for the same key, or compacted later in
|
||||
* a single garbage collection step of all removed entries. This garbage collection will
|
||||
* need to be performed at any time the array needs to be grown or the the map size or
|
||||
* entry values are retrieved.</p>
|
||||
*
|
||||
* <p>It is possible to iterate over the items in this container using
|
||||
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
|
||||
* <code>keyAt(int)</code> with ascending values of the index will return the
|
||||
* keys in ascending order, or the values corresponding to the keys in ascending
|
||||
* order in the case of <code>valueAt(int)<code>.</p>
|
||||
*/
|
||||
public class SparseArray<E> implements Cloneable {
|
||||
private static final Object DELETED = new Object();
|
||||
private boolean mGarbage = false;
|
||||
|
||||
private int[] mKeys;
|
||||
private Object[] mValues;
|
||||
private int mSize;
|
||||
|
||||
/**
|
||||
* Creates a new SparseArray containing no mappings.
|
||||
*/
|
||||
public SparseArray() {
|
||||
this(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SparseArray containing no mappings that will not
|
||||
* require any additional memory allocation to store the specified
|
||||
* number of mappings. If you supply an initial capacity of 0, the
|
||||
* sparse array will be initialized with a light-weight representation
|
||||
* not requiring any additional array allocations.
|
||||
*/
|
||||
public SparseArray(int initialCapacity) {
|
||||
if (initialCapacity == 0) {
|
||||
mKeys = ContainerHelpers.EMPTY_INTS;
|
||||
mValues = ContainerHelpers.EMPTY_OBJECTS;
|
||||
} else {
|
||||
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
|
||||
mKeys = new int[initialCapacity];
|
||||
mValues = new Object[initialCapacity];
|
||||
}
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public SparseArray<E> clone() {
|
||||
SparseArray<E> clone = null;
|
||||
try {
|
||||
clone = (SparseArray<E>) super.clone();
|
||||
clone.mKeys = mKeys.clone();
|
||||
clone.mValues = mValues.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
/* ignore */
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object mapped from the specified key, or <code>null</code>
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
public E get(int key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object mapped from the specified key, or the specified Object
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public E get(int key, E valueIfKeyNotFound) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i < 0 || mValues[i] == DELETED) {
|
||||
return valueIfKeyNotFound;
|
||||
} else {
|
||||
return (E) mValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping from the specified key, if there was any.
|
||||
*/
|
||||
public void delete(int key) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
if (mValues[i] != DELETED) {
|
||||
mValues[i] = DELETED;
|
||||
mGarbage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link #delete(int)}.
|
||||
*/
|
||||
public void remove(int key) {
|
||||
delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping at the specified index.
|
||||
*/
|
||||
public void removeAt(int index) {
|
||||
if (mValues[index] != DELETED) {
|
||||
mValues[index] = DELETED;
|
||||
mGarbage = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a range of mappings as a batch.
|
||||
*
|
||||
* @param index Index to begin at
|
||||
* @param size Number of mappings to remove
|
||||
*/
|
||||
public void removeAtRange(int index, int size) {
|
||||
final int end = Math.min(mSize, index + size);
|
||||
for (int i = index; i < end; i++) {
|
||||
removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
private void gc() {
|
||||
// Log.e("SparseArray", "gc start with " + mSize);
|
||||
|
||||
int n = mSize;
|
||||
int o = 0;
|
||||
int[] keys = mKeys;
|
||||
Object[] values = mValues;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Object val = values[i];
|
||||
|
||||
if (val != DELETED) {
|
||||
if (i != o) {
|
||||
keys[o] = keys[i];
|
||||
values[o] = val;
|
||||
values[i] = null;
|
||||
}
|
||||
|
||||
o++;
|
||||
}
|
||||
}
|
||||
|
||||
mGarbage = false;
|
||||
mSize = o;
|
||||
|
||||
// Log.e("SparseArray", "gc end with " + mSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from the specified key to the specified value,
|
||||
* replacing the previous mapping from the specified key if there
|
||||
* was one.
|
||||
*/
|
||||
public void put(int key, E value) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
mValues[i] = value;
|
||||
} else {
|
||||
i = ~i;
|
||||
|
||||
if (i < mSize && mValues[i] == DELETED) {
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGarbage && mSize >= mKeys.length) {
|
||||
gc();
|
||||
|
||||
// Search again because indices may have changed.
|
||||
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
if (mSize >= mKeys.length) {
|
||||
int n = ArrayUtils.idealIntArraySize(mSize + 1);
|
||||
|
||||
int[] nkeys = new int[n];
|
||||
Object[] nvalues = new Object[n];
|
||||
|
||||
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
if (mSize - i != 0) {
|
||||
// Log.e("SparseArray", "move " + (mSize - i));
|
||||
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
|
||||
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
|
||||
}
|
||||
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
mSize++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings that this SparseArray
|
||||
* currently stores.
|
||||
*/
|
||||
public int size() {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the key from the <code>index</code>th key-value mapping that this
|
||||
* SparseArray stores.
|
||||
*
|
||||
* <p>The keys corresponding to indices in ascending order are guaranteed to
|
||||
* be in ascending order, e.g., <code>keyAt(0)</code> will return the
|
||||
* smallest key and <code>keyAt(size()-1)</code> will return the largest
|
||||
* key.</p>
|
||||
*/
|
||||
public int keyAt(int index) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return mKeys[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the value from the <code>index</code>th key-value mapping that this
|
||||
* SparseArray stores.
|
||||
*
|
||||
* <p>The values corresponding to indices in ascending order are guaranteed
|
||||
* to be associated with keys in ascending order, e.g.,
|
||||
* <code>valueAt(0)</code> will return the value associated with the
|
||||
* smallest key and <code>valueAt(size()-1)</code> will return the value
|
||||
* associated with the largest key.</p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public E valueAt(int index) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return (E) mValues[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, sets a new
|
||||
* value for the <code>index</code>th key-value mapping that this
|
||||
* SparseArray stores.
|
||||
*/
|
||||
public void setValueAt(int index, E value) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
mValues[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for which {@link #keyAt} would return the
|
||||
* specified key, or a negative number if the specified
|
||||
* key is not mapped.
|
||||
*/
|
||||
public int indexOfKey(int key) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index for which {@link #valueAt} would return the
|
||||
* specified key, or a negative number if no keys map to the
|
||||
* specified value.
|
||||
* <p>Beware that this is a linear search, unlike lookups by key,
|
||||
* and that multiple keys can map to the same value and this will
|
||||
* find only one of them.
|
||||
* <p>Note also that unlike most collections' {@code indexOf} methods,
|
||||
* this method compares values using {@code ==} rather than {@code equals}.
|
||||
*/
|
||||
public int indexOfValue(E value) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mValues[i] == value)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value mappings from this SparseArray.
|
||||
*/
|
||||
public void clear() {
|
||||
int n = mSize;
|
||||
Object[] values = mValues;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
values[i] = null;
|
||||
}
|
||||
|
||||
mSize = 0;
|
||||
mGarbage = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a key/value pair into the array, optimizing for the case where
|
||||
* the key is greater than all existing keys in the array.
|
||||
*/
|
||||
public void append(int key, E value) {
|
||||
if (mSize != 0 && key <= mKeys[mSize - 1]) {
|
||||
put(key, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGarbage && mSize >= mKeys.length) {
|
||||
gc();
|
||||
}
|
||||
|
||||
int pos = mSize;
|
||||
if (pos >= mKeys.length) {
|
||||
int n = ArrayUtils.idealIntArraySize(pos + 1);
|
||||
|
||||
int[] nkeys = new int[n];
|
||||
Object[] nvalues = new Object[n];
|
||||
|
||||
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
mKeys[pos] = key;
|
||||
mValues[pos] = value;
|
||||
mSize = pos + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation composes a string by iterating over its mappings. If
|
||||
* this map contains itself as a value, the string "(this Map)"
|
||||
* will appear in its place.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (size() <= 0) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(mSize * 28);
|
||||
buffer.append('{');
|
||||
for (int i=0; i<mSize; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
int key = keyAt(i);
|
||||
buffer.append(key);
|
||||
buffer.append('=');
|
||||
Object value = valueAt(i);
|
||||
if (value != this) {
|
||||
buffer.append(value);
|
||||
} else {
|
||||
buffer.append("(this Map)");
|
||||
}
|
||||
}
|
||||
buffer.append('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
292
src/api-impl/android/util/SparseIntArray.java
Normal file
292
src/api-impl/android/util/SparseIntArray.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 com.android.internal.util.ArrayUtils;
|
||||
|
||||
/**
|
||||
* SparseIntArrays map integers to integers. Unlike a normal array of integers,
|
||||
* there can be gaps in the indices. It is intended to be more memory efficient
|
||||
* than using a HashMap to map Integers to Integers, both because it avoids
|
||||
* auto-boxing keys and values and its data structure doesn't rely on an extra entry object
|
||||
* for each mapping.
|
||||
*
|
||||
* <p>Note that this container keeps its mappings in an array data structure,
|
||||
* using a binary search to find keys. The implementation is not intended to be appropriate for
|
||||
* data structures
|
||||
* that may contain large numbers of items. It is generally slower than a traditional
|
||||
* HashMap, since lookups require a binary search and adds and removes require inserting
|
||||
* and deleting entries in the array. For containers holding up to hundreds of items,
|
||||
* the performance difference is not significant, less than 50%.</p>
|
||||
*
|
||||
* <p>It is possible to iterate over the items in this container using
|
||||
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
|
||||
* <code>keyAt(int)</code> with ascending values of the index will return the
|
||||
* keys in ascending order, or the values corresponding to the keys in ascending
|
||||
* order in the case of <code>valueAt(int)<code>.</p>
|
||||
*/
|
||||
public class SparseIntArray implements Cloneable {
|
||||
private int[] mKeys;
|
||||
private int[] mValues;
|
||||
private int mSize;
|
||||
|
||||
/**
|
||||
* Creates a new SparseIntArray containing no mappings.
|
||||
*/
|
||||
public SparseIntArray() {
|
||||
this(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SparseIntArray containing no mappings that will not
|
||||
* require any additional memory allocation to store the specified
|
||||
* number of mappings. If you supply an initial capacity of 0, the
|
||||
* sparse array will be initialized with a light-weight representation
|
||||
* not requiring any additional array allocations.
|
||||
*/
|
||||
public SparseIntArray(int initialCapacity) {
|
||||
if (initialCapacity == 0) {
|
||||
mKeys = ContainerHelpers.EMPTY_INTS;
|
||||
mValues = ContainerHelpers.EMPTY_INTS;
|
||||
} else {
|
||||
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
|
||||
mKeys = new int[initialCapacity];
|
||||
mValues = new int[initialCapacity];
|
||||
}
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SparseIntArray clone() {
|
||||
SparseIntArray clone = null;
|
||||
try {
|
||||
clone = (SparseIntArray) super.clone();
|
||||
clone.mKeys = mKeys.clone();
|
||||
clone.mValues = mValues.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
/* ignore */
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the int mapped from the specified key, or <code>0</code>
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
public int get(int key) {
|
||||
return get(key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the int mapped from the specified key, or the specified value
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
public int get(int key, int valueIfKeyNotFound) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i < 0) {
|
||||
return valueIfKeyNotFound;
|
||||
} else {
|
||||
return mValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping from the specified key, if there was any.
|
||||
*/
|
||||
public void delete(int key) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping at the given index.
|
||||
*/
|
||||
public void removeAt(int index) {
|
||||
System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
|
||||
System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
|
||||
mSize--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from the specified key to the specified value,
|
||||
* replacing the previous mapping from the specified key if there
|
||||
* was one.
|
||||
*/
|
||||
public void put(int key, int value) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
mValues[i] = value;
|
||||
} else {
|
||||
i = ~i;
|
||||
|
||||
if (mSize >= mKeys.length) {
|
||||
int n = ArrayUtils.idealIntArraySize(mSize + 1);
|
||||
|
||||
int[] nkeys = new int[n];
|
||||
int[] nvalues = new int[n];
|
||||
|
||||
// Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
if (mSize - i != 0) {
|
||||
// Log.e("SparseIntArray", "move " + (mSize - i));
|
||||
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
|
||||
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
|
||||
}
|
||||
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
mSize++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings that this SparseIntArray
|
||||
* currently stores.
|
||||
*/
|
||||
public int size() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the key from the <code>index</code>th key-value mapping that this
|
||||
* SparseIntArray stores.
|
||||
*
|
||||
* <p>The keys corresponding to indices in ascending order are guaranteed to
|
||||
* be in ascending order, e.g., <code>keyAt(0)</code> will return the
|
||||
* smallest key and <code>keyAt(size()-1)</code> will return the largest
|
||||
* key.</p>
|
||||
*/
|
||||
public int keyAt(int index) {
|
||||
return mKeys[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the value from the <code>index</code>th key-value mapping that this
|
||||
* SparseIntArray stores.
|
||||
*
|
||||
* <p>The values corresponding to indices in ascending order are guaranteed
|
||||
* to be associated with keys in ascending order, e.g.,
|
||||
* <code>valueAt(0)</code> will return the value associated with the
|
||||
* smallest key and <code>valueAt(size()-1)</code> will return the value
|
||||
* associated with the largest key.</p>
|
||||
*/
|
||||
public int valueAt(int index) {
|
||||
return mValues[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for which {@link #keyAt} would return the
|
||||
* specified key, or a negative number if the specified
|
||||
* key is not mapped.
|
||||
*/
|
||||
public int indexOfKey(int key) {
|
||||
return ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index for which {@link #valueAt} would return the
|
||||
* specified key, or a negative number if no keys map to the
|
||||
* specified value.
|
||||
* Beware that this is a linear search, unlike lookups by key,
|
||||
* and that multiple keys can map to the same value and this will
|
||||
* find only one of them.
|
||||
*/
|
||||
public int indexOfValue(int value) {
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mValues[i] == value)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value mappings from this SparseIntArray.
|
||||
*/
|
||||
public void clear() {
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a key/value pair into the array, optimizing for the case where
|
||||
* the key is greater than all existing keys in the array.
|
||||
*/
|
||||
public void append(int key, int value) {
|
||||
if (mSize != 0 && key <= mKeys[mSize - 1]) {
|
||||
put(key, value);
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = mSize;
|
||||
if (pos >= mKeys.length) {
|
||||
int n = ArrayUtils.idealIntArraySize(pos + 1);
|
||||
|
||||
int[] nkeys = new int[n];
|
||||
int[] nvalues = new int[n];
|
||||
|
||||
// Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
mKeys[pos] = key;
|
||||
mValues[pos] = value;
|
||||
mSize = pos + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation composes a string by iterating over its mappings.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (size() <= 0) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(mSize * 28);
|
||||
buffer.append('{');
|
||||
for (int i=0; i<mSize; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
int key = keyAt(i);
|
||||
buffer.append(key);
|
||||
buffer.append('=');
|
||||
int value = valueAt(i);
|
||||
buffer.append(value);
|
||||
}
|
||||
buffer.append('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user