diff --git a/src/api-impl-jni/generated_headers/android_widget_ProgressBar.h b/src/api-impl-jni/generated_headers/android_widget_ProgressBar.h index b494a023..2e8d5170 100644 --- a/src/api-impl-jni/generated_headers/android_widget_ProgressBar.h +++ b/src/api-impl-jni/generated_headers/android_widget_ProgressBar.h @@ -217,10 +217,10 @@ JNIEXPORT void JNICALL Java_android_widget_ProgressBar_native_1setProgress /* * Class: android_widget_ProgressBar - * Method: setIndeterminate + * Method: native_setIndeterminate * Signature: (Z)V */ -JNIEXPORT void JNICALL Java_android_widget_ProgressBar_setIndeterminate +JNIEXPORT void JNICALL Java_android_widget_ProgressBar_native_1setIndeterminate (JNIEnv *, jobject, jboolean); #ifdef __cplusplus diff --git a/src/api-impl-jni/widgets/android_widget_Progressbar.c b/src/api-impl-jni/widgets/android_widget_Progressbar.c index 993fcfb8..d63ac3af 100644 --- a/src/api-impl-jni/widgets/android_widget_Progressbar.c +++ b/src/api-impl-jni/widgets/android_widget_Progressbar.c @@ -29,7 +29,7 @@ JNIEXPORT void JNICALL Java_android_widget_ProgressBar_native_1setProgress(JNIEn gtk_progress_bar_set_fraction(progress_bar, progress); } -JNIEXPORT void JNICALL Java_android_widget_ProgressBar_setIndeterminate(JNIEnv *env, jobject this, jboolean indeterminate) +JNIEXPORT void JNICALL Java_android_widget_ProgressBar_native_1setIndeterminate(JNIEnv *env, jobject this, jboolean indeterminate) { GtkWidget *box = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget"))); GtkProgressBar *progress_bar = GTK_PROGRESS_BAR(gtk_widget_get_first_child(box)); diff --git a/src/api-impl/android/animation/ObjectAnimator.java b/src/api-impl/android/animation/ObjectAnimator.java index d53e69c0..5dfb031e 100644 --- a/src/api-impl/android/animation/ObjectAnimator.java +++ b/src/api-impl/android/animation/ObjectAnimator.java @@ -1,5 +1,6 @@ package android.animation; +import android.graphics.Path; import android.util.Property; public class ObjectAnimator extends ValueAnimator { @@ -8,7 +9,11 @@ public class ObjectAnimator extends ValueAnimator { return null; } - public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { + public static ObjectAnimator ofFloat(Object target, String xPropertyName, String yPropertyName, Path path) { + return new ObjectAnimator(); + } + + public static ObjectAnimator ofFloat(T target, Property xProperty, Property yProperty, Path path) { return new ObjectAnimator(); } @@ -16,6 +21,10 @@ public class ObjectAnimator extends ValueAnimator { return new ObjectAnimator(); } + public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { + return new ObjectAnimator(); + } + public static ObjectAnimator ofInt(T target, String propertyName, int... values) { return new ObjectAnimator(); } diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index e76e25fa..e186598f 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -6,6 +6,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.XmlResourceParser; import android.net.Uri; @@ -451,6 +452,20 @@ public class Activity extends ContextWrapper implements Window.Callback { } } + public String getLocalClassName() { + final String pkg = getPackageName(); + final String cls = this.getClass().getName(); + int packageLen = pkg.length(); + if (!cls.startsWith(pkg) || cls.length() <= packageLen || cls.charAt(packageLen) != '.') { + return cls; + } + return cls.substring(packageLen+1); + } + + public SharedPreferences getPreferences(int mode) { + return getSharedPreferences(getLocalClassName(), mode); + } + private native void nativeFinish(long native_window); public static native void nativeRecreateActivity(Activity activity); public static native void nativeStartActivity(Activity activity); diff --git a/src/api-impl/android/app/Application.java b/src/api-impl/android/app/Application.java index 92f0735b..882d2b29 100644 --- a/src/api-impl/android/app/Application.java +++ b/src/api-impl/android/app/Application.java @@ -9,6 +9,7 @@ import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; import java.io.InputStream; import java.io.IOException; +import android.content.Context; import android.content.ContextWrapper; public class Application extends ContextWrapper { @@ -44,13 +45,13 @@ public class Application extends ContextWrapper { } public Application() { - super(null); + super(new Context()); /* TODO: is this the right place to put this? */ InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); try { AndroidManifestBlock manifest = AndroidManifestBlock.load(inStream); int app_icon_resid = manifest.getIconResourceId(); - app_icon_path = this.getResources().getString(app_icon_resid); + app_icon_path = r.getString(app_icon_resid); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/api-impl/android/bluetooth/le/ScanCallback.java b/src/api-impl/android/bluetooth/le/ScanCallback.java new file mode 100644 index 00000000..f94e9b8a --- /dev/null +++ b/src/api-impl/android/bluetooth/le/ScanCallback.java @@ -0,0 +1,5 @@ +package android.bluetooth.le; + +public abstract class ScanCallback { + +} diff --git a/src/api-impl/android/content/Context.java b/src/api-impl/android/content/Context.java index 5f751538..72e674e9 100644 --- a/src/api-impl/android/content/Context.java +++ b/src/api-impl/android/content/Context.java @@ -15,6 +15,8 @@ import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; +import android.database.DatabaseErrorHandler; +import android.database.sqlite.SQLiteDatabase; import android.graphics.drawable.Drawable; import android.hardware.input.InputManager; import android.hardware.SensorManager; @@ -71,7 +73,7 @@ public class Context extends Object { static AssetManager assets; static DisplayMetrics dm; - static Resources r; + protected static Resources r; static ApplicationInfo application_info; static Resources.Theme theme; private static Map,Service> runningServices = new HashMap<>(); @@ -85,6 +87,7 @@ public class Context extends Object { File files_dir = null; File obb_dir = null; File cache_dir = null; + File nobackup_dir = null; private static Map receiverMap = new HashMap(); @@ -231,6 +234,10 @@ public class Context extends Object { return apk_path; } + public int getColor(int resId) { + return r.getColor(resId); + } + public final String getString(int resId) { return r.getString(resId); } @@ -324,6 +331,23 @@ public class Context extends Object { return getCacheDir(); } + public File getNoBackupFilesDir() { + if (nobackup_dir == null) { + nobackup_dir = new File(getDataDirFile(), "no_backup/" + getPackageName()); + } + if (!nobackup_dir.exists()) { + if (!nobackup_dir.mkdirs()) { + if (nobackup_dir.exists()) { + // spurious failure; probably racing with another process for this app + return nobackup_dir; + } + Slog.w(TAG, "Unable to create obb directory >" + nobackup_dir.getPath() + "<"); + return null; + } + } + return nobackup_dir; + } + private File getPreferencesDir() { if (prefs_dir == null) { prefs_dir = new File(getDataDirFile(), "shared_prefs"); @@ -331,6 +355,10 @@ public class Context extends Object { return prefs_dir; } + public File getFileStreamPath(String name) { + return makeFilename(getFilesDir(), name); + } + public File getSharedPrefsFile(String name) { return makeFilename(getPreferencesDir(), name + ".xml"); } @@ -503,4 +531,21 @@ public class Context extends Object { public void grantUriPermission(String dummy, Uri dummy2, int dummy3) { System.out.println("grantUriPermission(" + dummy + ", " + dummy2 + ", " + dummy3 + ") called"); } + + public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) { + return openOrCreateDatabase(name, mode, factory, null); + } + + public SQLiteDatabase openOrCreateDatabase(String filename, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { + int flags = SQLiteDatabase.CREATE_IF_NECESSARY; + if ((mode & (1 <<3) /*MODE_ENABLE_WRITE_AHEAD_LOGGING*/) != 0) { + flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING; + } + SQLiteDatabase db = SQLiteDatabase.openDatabase(filename, factory, flags, errorHandler); + return db; + } + + public Context createConfigurationContext(Configuration configuration) { + return this; + } } diff --git a/src/api-impl/android/content/Intent.java b/src/api-impl/android/content/Intent.java index 82196acf..8c2efcae 100644 --- a/src/api-impl/android/content/Intent.java +++ b/src/api-impl/android/content/Intent.java @@ -178,23 +178,33 @@ public class Intent { return this; } - public Intent putExtras (Intent src) { + public Intent putExtras(Intent src) { // FIXME HACK this.extras = src.getExtras(); return this; } - public Intent putExtras (Bundle extras) { + public Intent putExtras(Bundle extras) { // FIXME HACK this.extras = extras; return this; } + public Intent replaceExtras(Bundle extras) { + this.extras = extras; + return this; + } + public Intent setClass(Context packageContext, Class cls) { setComponent(new ComponentName(packageContext, cls)); return this; } + public Intent setClassName(String packageName, String className) { + setComponent(new ComponentName(packageName, className)); + return this; + } + public String getStringExtra(String name) { return (String)extras.get(name); } diff --git a/src/api-impl/android/content/res/Resources.java b/src/api-impl/android/content/res/Resources.java index a722051a..6b0c28e9 100644 --- a/src/api-impl/android/content/res/Resources.java +++ b/src/api-impl/android/content/res/Resources.java @@ -851,23 +851,28 @@ public class Resources { * solid color or multiple colors that can be selected based on a state. */ public ColorStateList getColorStateList(int id) throws NotFoundException { - TypedValue value; - synchronized (mAccessLock) { - value = mTmpValue; - if (value == null) { - value = new TypedValue(); - } else { - mTmpValue = null; - } - getValue(id, value, true); - } - ColorStateList res = loadColorStateList(value, id); - synchronized (mAccessLock) { - if (mTmpValue == null) { - mTmpValue = value; - } - } - return res; + return getColorStateList(id, null); + } + + /* FIXME use the theme */ + public ColorStateList getColorStateList(int id, Theme theme) throws NotFoundException { + TypedValue value; + synchronized (mAccessLock) { + value = mTmpValue; + if (value == null) { + value = new TypedValue(); + } else { + mTmpValue = null; + } + getValue(id, value, true); + } + ColorStateList res = loadColorStateList(value, id); + synchronized (mAccessLock) { + if (mTmpValue == null) { + mTmpValue = value; + } + } + return res; } /** diff --git a/src/api-impl/android/graphics/Canvas.java b/src/api-impl/android/graphics/Canvas.java index d3bd2480..dd450f3c 100644 --- a/src/api-impl/android/graphics/Canvas.java +++ b/src/api-impl/android/graphics/Canvas.java @@ -257,6 +257,9 @@ public class Canvas { if (dst == null) { throw new NullPointerException(); } + if(src == null) { + src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); + } native_drawBitmap(skia_canvas, widget, bitmap.pixbuf, src.left, src.top, src.right, src.bottom, dst.left, dst.top, dst.right, dst.bottom, (paint != null) ? paint.skia_paint : 0); @@ -416,6 +419,16 @@ public class Canvas { return false; } + public int getWidth() { + return 10; //FIXME + } + + public int getHeight() { + return 10; //FIXME + } + + public void drawColor(int dummy) {} + private static native long native_canvas_from_bitmap(long pixbuf); private static native void native_save(long skia_canvas, long widget); diff --git a/src/api-impl/android/graphics/Color.java b/src/api-impl/android/graphics/Color.java index bd6ec5e1..39d28ef9 100644 --- a/src/api-impl/android/graphics/Color.java +++ b/src/api-impl/android/graphics/Color.java @@ -37,6 +37,10 @@ public class Color { return (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); } + public static int rgb(int red, int green, int blue) { + return argb(0xff, red, green, blue); + } + /** * Return the alpha component of a color int. This is the same as saying * color >>> 24 diff --git a/src/api-impl/android/graphics/ColorMatrix.java b/src/api-impl/android/graphics/ColorMatrix.java new file mode 100644 index 00000000..51e258bb --- /dev/null +++ b/src/api-impl/android/graphics/ColorMatrix.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.util.FloatMath; + +/** + * 5x4 matrix for transforming the color+alpha components of a Bitmap. + * The matrix is stored in a single array, and its treated as follows: + * [ a, b, c, d, e, + * f, g, h, i, j, + * k, l, m, n, o, + * p, q, r, s, t ] + * + * When applied to a color [r, g, b, a], the resulting color is computed as + * (after clamping) + * R' = a*R + b*G + c*B + d*A + e; + * G' = f*R + g*G + h*B + i*A + j; + * B' = k*R + l*G + m*B + n*A + o; + * A' = p*R + q*G + r*B + s*A + t; + */ +public class ColorMatrix { + + private final float[] mArray = new float[20]; + + /** + * Create a new colormatrix initialized to identity (as if reset() had + * been called). + */ + public ColorMatrix() { + reset(); + } + + /** + * Create a new colormatrix initialized with the specified array of values. + */ + public ColorMatrix(float[] src) { + System.arraycopy(src, 0, mArray, 0, 20); + } + + /** + * Create a new colormatrix initialized with the specified colormatrix. + */ + public ColorMatrix(ColorMatrix src) { + System.arraycopy(src.mArray, 0, mArray, 0, 20); + } + + /** + * Return the array of floats representing this colormatrix. + */ + public final float[] getArray() { return mArray; } + + /** + * Set this colormatrix to identity: + * [ 1 0 0 0 0 - red vector + * 0 1 0 0 0 - green vector + * 0 0 1 0 0 - blue vector + * 0 0 0 1 0 ] - alpha vector + */ + public void reset() { + final float[] a = mArray; + + for (int i = 19; i > 0; --i) { + a[i] = 0; + } + a[0] = a[6] = a[12] = a[18] = 1; + } + + /** + * Assign the src colormatrix into this matrix, copying all of its values. + */ + public void set(ColorMatrix src) { + System.arraycopy(src.mArray, 0, mArray, 0, 20); + } + + /** + * Assign the array of floats into this matrix, copying all of its values. + */ + public void set(float[] src) { + System.arraycopy(src, 0, mArray, 0, 20); + } + + /** + * Set this colormatrix to scale by the specified values. + */ + public void setScale(float rScale, float gScale, float bScale, + float aScale) { + final float[] a = mArray; + + for (int i = 19; i > 0; --i) { + a[i] = 0; + } + a[0] = rScale; + a[6] = gScale; + a[12] = bScale; + a[18] = aScale; + } + + /** + * Set the rotation on a color axis by the specified values. + * axis=0 correspond to a rotation around the RED color + * axis=1 correspond to a rotation around the GREEN color + * axis=2 correspond to a rotation around the BLUE color + */ + public void setRotate(int axis, float degrees) { + reset(); + float radians = degrees * (float)Math.PI / 180; + float cosine = FloatMath.cos(radians); + float sine = FloatMath.sin(radians); + switch (axis) { + // Rotation around the red color + case 0: + mArray[6] = mArray[12] = cosine; + mArray[7] = sine; + mArray[11] = -sine; + break; + // Rotation around the green color + case 1: + mArray[0] = mArray[12] = cosine; + mArray[2] = -sine; + mArray[10] = sine; + break; + // Rotation around the blue color + case 2: + mArray[0] = mArray[6] = cosine; + mArray[1] = sine; + mArray[5] = -sine; + break; + default: + throw new RuntimeException(); + } + } + + /** + * Set this colormatrix to the concatenation of the two specified + * colormatrices, such that the resulting colormatrix has the same effect + * as applying matB and then applying matA. It is legal for either matA or + * matB to be the same colormatrix as this. + */ + public void setConcat(ColorMatrix matA, ColorMatrix matB) { + float[] tmp = null; + + if (matA == this || matB == this) { + tmp = new float[20]; + } else { + tmp = mArray; + } + + final float[] a = matA.mArray; + final float[] b = matB.mArray; + int index = 0; + for (int j = 0; j < 20; j += 5) { + for (int i = 0; i < 4; i++) { + tmp[index++] = a[j + 0] * b[i + 0] + a[j + 1] * b[i + 5] + + a[j + 2] * b[i + 10] + a[j + 3] * b[i + 15]; + } + tmp[index++] = a[j + 0] * b[4] + a[j + 1] * b[9] + + a[j + 2] * b[14] + a[j + 3] * b[19] + + a[j + 4]; + } + + if (tmp != mArray) { + System.arraycopy(tmp, 0, mArray, 0, 20); + } + } + + /** + * Concat this colormatrix with the specified prematrix. This is logically + * the same as calling setConcat(this, prematrix); + */ + public void preConcat(ColorMatrix prematrix) { + setConcat(this, prematrix); + } + + /** + * Concat this colormatrix with the specified postmatrix. This is logically + * the same as calling setConcat(postmatrix, this); + */ + public void postConcat(ColorMatrix postmatrix) { + setConcat(postmatrix, this); + } + + /////////////////////////////////////////////////////////////////////////// + + /** + * Set the matrix to affect the saturation of colors. A value of 0 maps the + * color to gray-scale. 1 is identity. + */ + public void setSaturation(float sat) { + reset(); + float[] m = mArray; + + final float invSat = 1 - sat; + final float R = 0.213f * invSat; + final float G = 0.715f * invSat; + final float B = 0.072f * invSat; + + m[0] = R + sat; + m[1] = G; + m[2] = B; + m[5] = R; + m[6] = G + sat; + m[7] = B; + m[10] = R; + m[11] = G; + m[12] = B + sat; + } + + /** + * Set the matrix to convert RGB to YUV + */ + public void setRGB2YUV() { + reset(); + float[] m = mArray; + // these coefficients match those in libjpeg + m[0] = 0.299f; + m[1] = 0.587f; + m[2] = 0.114f; + m[5] = -0.16874f; + m[6] = -0.33126f; + m[7] = 0.5f; + m[10] = 0.5f; + m[11] = -0.41869f; + m[12] = -0.08131f; + } + + /** + * Set the matrix to convert from YUV to RGB + */ + public void setYUV2RGB() { + reset(); + float[] m = mArray; + // these coefficients match those in libjpeg + m[2] = 1.402f; + m[5] = 1; + m[6] = -0.34414f; + m[7] = -0.71414f; + m[10] = 1; + m[11] = 1.772f; + m[12] = 0; + } +} diff --git a/src/api-impl/android/graphics/ColorMatrixColorFilter.java b/src/api-impl/android/graphics/ColorMatrixColorFilter.java new file mode 100644 index 00000000..784a160b --- /dev/null +++ b/src/api-impl/android/graphics/ColorMatrixColorFilter.java @@ -0,0 +1,11 @@ +package android.graphics; + +public class ColorMatrixColorFilter extends ColorFilter { + public ColorMatrixColorFilter(ColorMatrix matrix) { + super(); + } + + public ColorMatrixColorFilter(float[] array) { + super(); + } +} diff --git a/src/api-impl/android/graphics/CornerPathEffect.java b/src/api-impl/android/graphics/CornerPathEffect.java new file mode 100644 index 00000000..1c021806 --- /dev/null +++ b/src/api-impl/android/graphics/CornerPathEffect.java @@ -0,0 +1,7 @@ +package android.graphics; + +public class CornerPathEffect extends PathEffect { + public CornerPathEffect(float radius) { + super(); + } +} diff --git a/src/api-impl/android/graphics/DashPathEffect.java b/src/api-impl/android/graphics/DashPathEffect.java new file mode 100644 index 00000000..493c276a --- /dev/null +++ b/src/api-impl/android/graphics/DashPathEffect.java @@ -0,0 +1,6 @@ +package android.graphics; + +public class DashPathEffect extends PathEffect { + public DashPathEffect(float[] dummy, float dummy2) { + } +} diff --git a/src/api-impl/android/graphics/Paint.java b/src/api-impl/android/graphics/Paint.java index 979b76ca..185f9864 100644 --- a/src/api-impl/android/graphics/Paint.java +++ b/src/api-impl/android/graphics/Paint.java @@ -256,6 +256,16 @@ public class Paint { return new Shader(); } + public PathEffect setPathEffect(PathEffect effect) { + return effect; + } + + public int breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth) { return 10; } + public int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth) { return 10; } + public int breakText(CharSequence text, int start, int end, boolean measureForwards, float maxWidth, float[] measuredWidth) { return 10; } + + public void clearShadowLayer() {} + private native long native_constructor(); private native void native_set_antialias(long skia_paint, boolean aa); private native void native_set_color(long skia_paint, int color); diff --git a/src/api-impl/android/graphics/PathEffect.java b/src/api-impl/android/graphics/PathEffect.java new file mode 100644 index 00000000..1173850c --- /dev/null +++ b/src/api-impl/android/graphics/PathEffect.java @@ -0,0 +1,5 @@ +package android.graphics; + +public class PathEffect { + +} diff --git a/src/api-impl/android/graphics/PathMeasure.java b/src/api-impl/android/graphics/PathMeasure.java new file mode 100644 index 00000000..c112f7c4 --- /dev/null +++ b/src/api-impl/android/graphics/PathMeasure.java @@ -0,0 +1,6 @@ +package android.graphics; + +public class PathMeasure { + public PathMeasure(Path path, boolean dummy) { + } +} diff --git a/src/api-impl/android/graphics/drawable/Drawable.java b/src/api-impl/android/graphics/drawable/Drawable.java index 6e7f1d6d..ceb28255 100644 --- a/src/api-impl/android/graphics/drawable/Drawable.java +++ b/src/api-impl/android/graphics/drawable/Drawable.java @@ -52,7 +52,7 @@ public class Drawable { return null; } - public abstract class ConstantState { + public static abstract class ConstantState { public abstract Drawable newDrawable(Resources res); @@ -88,6 +88,10 @@ public class Drawable { this.callback = callback; } + public Callback getCallback() { + return this.callback; + } + public void invalidateSelf() { native_invalidate(paintable); @@ -172,10 +176,16 @@ public class Drawable { VectorDrawable drawable = new VectorDrawable(); drawable.inflate(resources, parser, parser, null); return drawable; + } else if ("layer-list".equals(parser.getName())) { + return new LayerDrawable(); } return null; } + public static Drawable createFromXmlInner(Resources resources, XmlPullParser parser, AttributeSet attrs) { + return createFromXmlInner(resources, parser, attrs, null); + } + public static Drawable createFromXmlInner(Resources resources, XmlPullParser parser, AttributeSet attrs, Theme theme) { return null; } @@ -211,6 +221,13 @@ public class Drawable { bounds.set(mBounds); } + public int getMinimumWidth() { + return 10; // FIXME + } + public int getMinimumHeight() { + return 10; // FIXME + } + protected void onBoundsChange(Rect bounds) {} protected static native long native_paintable_from_path(String path); diff --git a/src/api-impl/android/graphics/drawable/LayerDrawable.java b/src/api-impl/android/graphics/drawable/LayerDrawable.java index d093b3f6..f0266b1d 100644 --- a/src/api-impl/android/graphics/drawable/LayerDrawable.java +++ b/src/api-impl/android/graphics/drawable/LayerDrawable.java @@ -1,14 +1,763 @@ +/* + * 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.graphics.drawable; +import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.ColorFilter; +//import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.View; +import java.io.IOException; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; -public class LayerDrawable extends Drawable { +/** + * A Drawable that manages an array of other Drawables. These are drawn in array + * order, so the element with the largest index will be drawn on top. + *

+ * It can be defined in an XML file with the <layer-list> element. + * Each Drawable in the layer is defined in a nested <item>. For more + * information, see the guide to Drawable Resources.

+ * + * @attr ref android.R.styleable#LayerDrawableItem_left + * @attr ref android.R.styleable#LayerDrawableItem_top + * @attr ref android.R.styleable#LayerDrawableItem_right + * @attr ref android.R.styleable#LayerDrawableItem_bottom + * @attr ref android.R.styleable#LayerDrawableItem_drawable + * @attr ref android.R.styleable#LayerDrawableItem_id + */ +public class LayerDrawable extends Drawable implements Drawable.Callback { + LayerState mLayerState; - public LayerDrawable(Drawable[] drawables) { +// private int mOpacityOverride = PixelFormat.UNKNOWN; + private int[] mPaddingL; + private int[] mPaddingT; + private int[] mPaddingR; + private int[] mPaddingB; + + private final Rect mTmpRect = new Rect(); + private boolean mMutated; + + /** + * Create a new layer drawable with the list of specified layers. + * + * @param layers A list of drawables to use as layers in this new drawable. + */ + public LayerDrawable(Drawable[] layers) { + this(layers, null); } + /** + * Create a new layer drawable with the specified list of layers and the specified + * constant state. + * + * @param layers The list of layers to add to this drawable. + * @param state The constant drawable state. + */ + LayerDrawable(Drawable[] layers, LayerState state) { + this(state, null); + int length = layers.length; + ChildDrawable[] r = new ChildDrawable[length]; + + for (int i = 0; i < length; i++) { + r[i] = new ChildDrawable(); + r[i].mDrawable = layers[i]; + layers[i].setCallback(this); + mLayerState.mChildrenChangingConfigurations |= layers[i].getChangingConfigurations(); + } + mLayerState.mNum = length; + mLayerState.mChildren = r; + + ensurePadding(); + } + + LayerDrawable() { + this((LayerState)null, null); + } + + LayerDrawable(LayerState state, Resources res) { + LayerState as = createConstantState(state, res); + mLayerState = as; + if (as.mNum > 0) { + ensurePadding(); + } + } + + LayerState createConstantState(LayerState state, Resources res) { + return new LayerState(state, this, res); + } + +// @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) + throws XmlPullParserException, IOException { + //super.inflate(r, parser, attrs); + + int type; + + TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.LayerDrawable); + +// mOpacityOverride = a.getInt(com.android.internal.R.styleable.LayerDrawable_opacity, PixelFormat.UNKNOWN); + +// setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.LayerDrawable_autoMirrored, false)); + + a.recycle(); + + final int innerDepth = parser.getDepth() + 1; + int depth; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { + if (type != XmlPullParser.START_TAG) { + continue; + } + + if (depth > innerDepth || !parser.getName().equals("item")) { + continue; + } + + a = r.obtainAttributes(attrs, + com.android.internal.R.styleable.LayerDrawableItem); + + int left = a.getDimensionPixelOffset( + com.android.internal.R.styleable.LayerDrawableItem_left, 0); + int top = a.getDimensionPixelOffset( + com.android.internal.R.styleable.LayerDrawableItem_top, 0); + int right = a.getDimensionPixelOffset( + com.android.internal.R.styleable.LayerDrawableItem_right, 0); + int bottom = a.getDimensionPixelOffset( + com.android.internal.R.styleable.LayerDrawableItem_bottom, 0); + int drawableRes = a.getResourceId( + com.android.internal.R.styleable.LayerDrawableItem_drawable, 0); + int id = a.getResourceId(com.android.internal.R.styleable.LayerDrawableItem_id, + View.NO_ID); + + a.recycle(); + + Drawable dr; + if (drawableRes != 0) { + dr = r.getDrawable(drawableRes); + } else { + while ((type = parser.next()) == XmlPullParser.TEXT) { + } + if (type != XmlPullParser.START_TAG) { + throw new XmlPullParserException(parser.getPositionDescription() + ": tag requires a 'drawable' attribute or " + + "child tag defining a drawable"); + } + dr = Drawable.createFromXmlInner(r, parser, attrs); + } + + addLayer(dr, id, left, top, right, bottom); + } + + ensurePadding(); + onStateChange(getState()); + } + + /** + * Add a new layer to this drawable. The new layer is identified by an id. + * + * @param layer The drawable to add as a layer. + * @param id The id of the new layer. + * @param left The left padding of the new layer. + * @param top The top padding of the new layer. + * @param right The right padding of the new layer. + * @param bottom The bottom padding of the new layer. + */ + private void addLayer(Drawable layer, int id, int left, int top, int right, int bottom) { + final LayerState st = mLayerState; + int N = st.mChildren != null ? st.mChildren.length : 0; + int i = st.mNum; + if (i >= N) { + ChildDrawable[] nu = new ChildDrawable[N + 10]; + if (i > 0) { + System.arraycopy(st.mChildren, 0, nu, 0, i); + } + st.mChildren = nu; + } + + //mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations(); + + ChildDrawable childDrawable = new ChildDrawable(); + st.mChildren[i] = childDrawable; + childDrawable.mId = id; + childDrawable.mDrawable = layer; + //childDrawable.mDrawable.setAutoMirrored(isAutoMirrored()); + childDrawable.mInsetL = left; + childDrawable.mInsetT = top; + childDrawable.mInsetR = right; + childDrawable.mInsetB = bottom; + st.mNum++; + + layer.setCallback(this); + } + + /** + * Look for a layer with the given id, and returns its {@link Drawable}. + * + * @param id The layer ID to search for. + * @return The {@link Drawable} of the layer that has the given id in the hierarchy or null. + */ + public Drawable findDrawableByLayerId(int id) { + final ChildDrawable[] layers = mLayerState.mChildren; + + for (int i = mLayerState.mNum - 1; i >= 0; i--) { + if (layers[i].mId == id) { + return layers[i].mDrawable; + } + } + + return null; + } + + /** + * Sets the ID of a layer. + * + * @param index The index of the layer which will received the ID. + * @param id The ID to assign to the layer. + */ + public void setId(int index, int id) { + mLayerState.mChildren[index].mId = id; + } + + /** + * Returns the number of layers contained within this. + * @return The number of layers. + */ + public int getNumberOfLayers() { + return mLayerState.mNum; + } + + /** + * Returns the drawable at the specified layer index. + * + * @param index The layer index of the drawable to retrieve. + * + * @return The {@link android.graphics.drawable.Drawable} at the specified layer index. + */ + public Drawable getDrawable(int index) { + if(mLayerState.mChildren == null) { + return new Drawable() { + @Override + public void draw(Canvas canvas) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'draw'"); + } + }; + } + + return mLayerState.mChildren[index].mDrawable; + } + + /** + * Returns the id of the specified layer. + * + * @param index The index of the layer. + * + * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id. + */ + public int getId(int index) { + return mLayerState.mChildren[index].mId; + } + + /** + * Sets (or replaces) the {@link Drawable} for the layer with the given id. + * + * @param id The layer ID to search for. + * @param drawable The replacement {@link Drawable}. + * @return Whether the {@link Drawable} was replaced (could return false if + * the id was not found). + */ + public boolean setDrawableByLayerId(int id, Drawable drawable) { + final ChildDrawable[] layers = mLayerState.mChildren; + + for (int i = mLayerState.mNum - 1; i >= 0; i--) { + if (layers[i].mId == id) { + if (layers[i].mDrawable != null) { + if (drawable != null) { + Rect bounds = layers[i].mDrawable.getBounds(); + drawable.setBounds(bounds); + } + layers[i].mDrawable.setCallback(null); + } + if (drawable != null) { + drawable.setCallback(this); + } + layers[i].mDrawable = drawable; + return true; + } + } + + return false; + } + + /** + Specify modifiers to the bounds for the drawable[index]. + left += l + top += t; + right -= r; + bottom -= b; + */ + public void setLayerInset(int index, int l, int t, int r, int b) { + ChildDrawable childDrawable = mLayerState.mChildren[index]; + childDrawable.mInsetL = l; + childDrawable.mInsetT = t; + childDrawable.mInsetR = r; + childDrawable.mInsetB = b; + } + + // overrides from Drawable.Callback + + public void invalidateDrawable(Drawable who) { + final Callback callback = getCallback(); + if (callback != null) { + callback.invalidateDrawable(this); + } + } + + public void scheduleDrawable(Drawable who, Runnable what, long when) { + final Callback callback = getCallback(); + if (callback != null) { + callback.scheduleDrawable(this, what, when); + } + } + + public void unscheduleDrawable(Drawable who, Runnable what) { + final Callback callback = getCallback(); + if (callback != null) { + callback.unscheduleDrawable(this, what); + } + } + + // overrides from Drawable + @Override public void draw(Canvas canvas) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.draw(canvas); + } + } + +/* @Override + public int getChangingConfigurations() { + return super.getChangingConfigurations() | mLayerState.mChangingConfigurations | mLayerState.mChildrenChangingConfigurations; + }*/ + + @Override + public boolean getPadding(Rect padding) { + // Arbitrarily get the padding from the first image. + // Technically we should maybe do something more intelligent, + // like take the max padding of all the images. + padding.left = 0; + padding.top = 0; + padding.right = 0; + padding.bottom = 0; + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + reapplyPadding(i, array[i]); + padding.left += mPaddingL[i]; + padding.top += mPaddingT[i]; + padding.right += mPaddingR[i]; + padding.bottom += mPaddingB[i]; + } + return true; + } + + @Override + public boolean setVisible(boolean visible, boolean restart) { + boolean changed = super.setVisible(visible, restart); + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.setVisible(visible, restart); + } + return changed; + } + +/* @Override + public void setDither(boolean dither) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.setDither(dither); + } + }*/ + +/* @Override + public void setAlpha(int alpha) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.setAlpha(alpha); + } + }*/ + +/* @Override + public int getAlpha() { + final ChildDrawable[] array = mLayerState.mChildren; + if (mLayerState.mNum > 0) { + // All layers should have the same alpha set on them - just return the first one + return array[0].mDrawable.getAlpha(); + } else { + return super.getAlpha(); + } + }*/ + +/* @Override + public void setColorFilter(ColorFilter cf) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.setColorFilter(cf); + } + }*/ + + /** + * Sets the opacity of this drawable directly, instead of collecting the states from + * the layers + * + * @param opacity The opacity to use, or {@link PixelFormat#UNKNOWN PixelFormat.UNKNOWN} + * for the default behavior + * + * @see PixelFormat#UNKNOWN + * @see PixelFormat#TRANSLUCENT + * @see PixelFormat#TRANSPARENT + * @see PixelFormat#OPAQUE + */ +/* public void setOpacity(int opacity) { + mOpacityOverride = opacity; + }*/ + +/* @Override + public int getOpacity() { + if (mOpacityOverride != PixelFormat.UNKNOWN) { + return mOpacityOverride; + } + return mLayerState.getOpacity(); + }*/ + +/* @Override + public void setAutoMirrored(boolean mirrored) { + mLayerState.mAutoMirrored = mirrored; + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.setAutoMirrored(mirrored); + } + }*/ + +/* @Override + public boolean isAutoMirrored() { + return mLayerState.mAutoMirrored; + }*/ + +/* @Override + public boolean isStateful() { + return mLayerState.isStateful(); + }*/ + +/* @Override + protected boolean onStateChange(int[] state) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + boolean paddingChanged = false; + boolean changed = false; + for (int i = 0; i < N; i++) { + final ChildDrawable r = array[i]; + if (r.mDrawable.setState(state)) { + changed = true; + } + if (reapplyPadding(i, r)) { + paddingChanged = true; + } + } + if (paddingChanged) { + onBoundsChange(getBounds()); + } + return changed; + }*/ + +/* @Override + protected boolean onLevelChange(int level) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + boolean paddingChanged = false; + boolean changed = false; + for (int i = 0; i < N; i++) { + final ChildDrawable r = array[i]; + if (r.mDrawable.setLevel(level)) { + changed = true; + } + if (reapplyPadding(i, r)) { + paddingChanged = true; + } + } + if (paddingChanged) { + onBoundsChange(getBounds()); + } + return changed; + }*/ + + @Override + protected void onBoundsChange(Rect bounds) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + int padL = 0, padT = 0, padR = 0, padB = 0; + for (int i = 0; i < N; i++) { + final ChildDrawable r = array[i]; + r.mDrawable.setBounds(bounds.left + r.mInsetL + padL, + bounds.top + r.mInsetT + padT, + bounds.right - r.mInsetR - padR, + bounds.bottom - r.mInsetB - padB); + padL += mPaddingL[i]; + padR += mPaddingR[i]; + padT += mPaddingT[i]; + padB += mPaddingB[i]; + } + } + + @Override + public int getIntrinsicWidth() { + int width = -1; + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + int padL = 0, padR = 0; + for (int i = 0; i < N; i++) { + final ChildDrawable r = array[i]; + int w = r.mDrawable.getIntrinsicWidth() + r.mInsetL + r.mInsetR + padL + padR; + if (w > width) { + width = w; + } + padL += mPaddingL[i]; + padR += mPaddingR[i]; + } + return width; + } + + @Override + public int getIntrinsicHeight() { + int height = -1; + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + int padT = 0, padB = 0; + for (int i = 0; i < N; i++) { + final ChildDrawable r = array[i]; + int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + +padT + padB; + if (h > height) { + height = h; + } + padT += mPaddingT[i]; + padB += mPaddingB[i]; + } + return height; + } + + private boolean reapplyPadding(int i, ChildDrawable r) { + final Rect rect = mTmpRect; + r.mDrawable.getPadding(rect); + if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] || + rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) { + mPaddingL[i] = rect.left; + mPaddingT[i] = rect.top; + mPaddingR[i] = rect.right; + mPaddingB[i] = rect.bottom; + return true; + } + return false; + } + + private void ensurePadding() { + final int N = mLayerState.mNum; + if (mPaddingL != null && mPaddingL.length >= N) { + return; + } + mPaddingL = new int[N]; + mPaddingT = new int[N]; + mPaddingR = new int[N]; + mPaddingB = new int[N]; + } + +/* @Override + public ConstantState getConstantState() { + if (mLayerState.canConstantState()) { + mLayerState.mChangingConfigurations = getChangingConfigurations(); + return mLayerState; + } + return null; + }*/ + + @Override + public Drawable mutate() { + if (!mMutated && super.mutate() == this) { + mLayerState = createConstantState(mLayerState, null); + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.mutate(); + } + mMutated = true; + } + return this; + } + + /** + * @hide + */ +/* @Override + public void setLayoutDirection(int layoutDirection) { + final ChildDrawable[] array = mLayerState.mChildren; + final int N = mLayerState.mNum; + for (int i = 0; i < N; i++) { + array[i].mDrawable.setLayoutDirection(layoutDirection); + } + super.setLayoutDirection(layoutDirection); + }*/ + + static class ChildDrawable { + public Drawable mDrawable; + public int mInsetL, mInsetT, mInsetR, mInsetB; + public int mId; + } + + static class LayerState extends ConstantState { + int mNum; + ChildDrawable[] mChildren; + + int mChangingConfigurations; + int mChildrenChangingConfigurations; + + private boolean mHaveOpacity = false; + private int mOpacity; + + private boolean mHaveStateful = false; + private boolean mStateful; + + private boolean mCheckedConstantState; + private boolean mCanConstantState; + + private boolean mAutoMirrored; + + LayerState(LayerState orig, LayerDrawable owner, Resources res) { + if (orig != null) { + final ChildDrawable[] origChildDrawable = orig.mChildren; + final int N = orig.mNum; + + mNum = N; + mChildren = new ChildDrawable[N]; + + mChangingConfigurations = orig.mChangingConfigurations; + mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; + + for (int i = 0; i < N; i++) { + final ChildDrawable r = mChildren[i] = new ChildDrawable(); + final ChildDrawable or = origChildDrawable[i]; + if (res != null) { + r.mDrawable = or.mDrawable.getConstantState().newDrawable(res); + } else { + r.mDrawable = or.mDrawable.getConstantState().newDrawable(); + } + r.mDrawable.setCallback(owner); + //r.mDrawable.setLayoutDirection(or.mDrawable.getLayoutDirection()); + r.mInsetL = or.mInsetL; + r.mInsetT = or.mInsetT; + r.mInsetR = or.mInsetR; + r.mInsetB = or.mInsetB; + r.mId = or.mId; + } + + mHaveOpacity = orig.mHaveOpacity; + mOpacity = orig.mOpacity; + mHaveStateful = orig.mHaveStateful; + mStateful = orig.mStateful; + mCheckedConstantState = mCanConstantState = true; + mAutoMirrored = orig.mAutoMirrored; + } else { + mNum = 0; + mChildren = null; + } + } + + @Override + public Drawable newDrawable() { + return new LayerDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new LayerDrawable(this, res); + } + + //@Override + public int getChangingConfigurations() { + return mChangingConfigurations; + } +/* + public final int getOpacity() { + if (mHaveOpacity) { + return mOpacity; + } + + final int N = mNum; + int op = N > 0 ? mChildren[0].mDrawable.getOpacity() : PixelFormat.TRANSPARENT; + for (int i = 1; i < N; i++) { + op = Drawable.resolveOpacity(op, mChildren[i].mDrawable.getOpacity()); + } + mOpacity = op; + mHaveOpacity = true; + return op; + } + + public final boolean isStateful() { + if (mHaveStateful) { + return mStateful; + } + + boolean stateful = false; + final int N = mNum; + for (int i = 0; i < N; i++) { + if (mChildren[i].mDrawable.isStateful()) { + stateful = true; + break; + } + } + + mStateful = stateful; + mHaveStateful = true; + return stateful; + } + + public boolean canConstantState() { + if (!mCheckedConstantState && mChildren != null) { + mCanConstantState = true; + final int N = mNum; + for (int i = 0; i < N; i++) { + if (mChildren[i].mDrawable.getConstantState() == null) { + mCanConstantState = false; + break; + } + } + mCheckedConstantState = true; + } + + return mCanConstantState; + }*/ } - } diff --git a/src/api-impl/android/location/LocationManager.java b/src/api-impl/android/location/LocationManager.java index c5b1c915..d4ce0f18 100644 --- a/src/api-impl/android/location/LocationManager.java +++ b/src/api-impl/android/location/LocationManager.java @@ -1,5 +1,7 @@ package android.location; +import android.os.Bundle; + import java.util.HashSet; import java.util.Set; @@ -27,5 +29,11 @@ public class LocationManager { locationListener.onLocationChanged(new Location(latitude, longitude, heading)); } } - + + public boolean sendExtraCommand(String provider, String command, Bundle extras) { + return true; + } + + public void removeUpdates(LocationListener listener) { + } } diff --git a/src/api-impl/android/media/AudioAttributes.java b/src/api-impl/android/media/AudioAttributes.java index 737210c8..884c30cb 100644 --- a/src/api-impl/android/media/AudioAttributes.java +++ b/src/api-impl/android/media/AudioAttributes.java @@ -8,6 +8,10 @@ public class AudioAttributes { public class Builder { + public Builder setContentType(int content_type) { + return this; + } + public Builder setUsage(int usage) { return this; } diff --git a/src/api-impl/android/media/SoundPool.java b/src/api-impl/android/media/SoundPool.java index c8aa80f5..cce56a9f 100644 --- a/src/api-impl/android/media/SoundPool.java +++ b/src/api-impl/android/media/SoundPool.java @@ -36,6 +36,20 @@ public class SoundPool { return nativePlay(nativePool, soundID); } + public class Builder { + public Builder setAudioAttributes(AudioAttributes attributes) { + return this; + } + + public Builder setMaxStreams(int maxStreams) { + return this; + } + + public SoundPool build() { + return new SoundPool(0, 0, 0); // FIXME + } + } + private static native long native_constructor(); private static native int nativeLoad(long nativePool, String path); public static native int nativePlay(long nativePool, int soundID); diff --git a/src/api-impl/android/net/TrafficStats.java b/src/api-impl/android/net/TrafficStats.java new file mode 100644 index 00000000..49e83bd3 --- /dev/null +++ b/src/api-impl/android/net/TrafficStats.java @@ -0,0 +1,5 @@ +package android.net; + +public class TrafficStats { + public static void setThreadStatsTag(int dummy) {} +} diff --git a/src/api-impl/android/os/Environment.java b/src/api-impl/android/os/Environment.java index 19b00e71..a81ae0ec 100644 --- a/src/api-impl/android/os/Environment.java +++ b/src/api-impl/android/os/Environment.java @@ -93,6 +93,10 @@ public class Environment { } } + public static boolean isExternalStorageRemovable(File file) { + return true; + } + /** * {@hide} */ diff --git a/src/api-impl/android/os/StrictMode.java b/src/api-impl/android/os/StrictMode.java new file mode 100644 index 00000000..245230ab --- /dev/null +++ b/src/api-impl/android/os/StrictMode.java @@ -0,0 +1,60 @@ +package android.os; + +public final class StrictMode { + public static void setThreadPolicy(final ThreadPolicy policy) {} + public static void setVmPolicy(final VmPolicy policy) {} + + public static final class ThreadPolicy { + public static final class Builder { + public Builder detectAll() { + return this; + } + public Builder permitDiskReads() { + return this; + } + public Builder permitDiskWrites() { + return this; + } + public Builder penaltyLog() { + return this; + } + public ThreadPolicy build() { + return new ThreadPolicy(); + } + } + } + public static final class VmPolicy { + public static final class Builder { + public Builder detectActivityLeaks() { + return this; + } + public Builder detectAll() { + return this; + } + public Builder detectLeakedSqlLiteObjects() { + return this; + } + public Builder detectLeakedClosableObjects() { + return this; + } + public Builder detectLeakedRegistrationObjects() { + return this; + } + public Builder detectFileUriExposure() { + return this; + } + public Builder penaltyDeath() { + return this; + } + public Builder penaltyLog() { + return this; + } + public Builder penaltyDropBox() { + return this; + } + public VmPolicy build() { + return new VmPolicy(); + } + } + } +} diff --git a/src/api-impl/android/text/TextUtils.java b/src/api-impl/android/text/TextUtils.java index 96791751..aa564cfc 100644 --- a/src/api-impl/android/text/TextUtils.java +++ b/src/api-impl/android/text/TextUtils.java @@ -1,8 +1,13 @@ package android.text; +import java.util.Locale; import java.util.regex.Pattern; public class TextUtils { + public static int getLayoutDirectionFromLocale(Locale locale) { + return 0 /*LTR*/; // FIXME + } + // unchanged from android source /* split */ @@ -66,28 +71,30 @@ public class TextUtils { } /** - * Returns true if a and b are equal, including if they are both null. - *

Note: In platform versions 1.1 and earlier, this method only worked well if - * both the arguments were instances of String.

- * @param a first CharSequence to check - * @param b second CharSequence to check - * @return true if a and b are equal - */ - public static boolean equals(CharSequence a, CharSequence b) { - if (a == b) return true; - int length; - if (a != null && b != null && (length = a.length()) == b.length()) { - if (a instanceof String && b instanceof String) { - return a.equals(b); - } else { - for (int i = 0; i < length; i++) { - if (a.charAt(i) != b.charAt(i)) return false; - } - return true; - } - } - return false; - } + * Returns true if a and b are equal, including if they are both null. + *

Note: In platform versions 1.1 and earlier, this method only worked well if + * both the arguments were instances of String.

+ * @param a first CharSequence to check + * @param b second CharSequence to check + * @return true if a and b are equal + */ + public static boolean equals(CharSequence a, CharSequence b) { + if (a == b) + return true; + int length; + if (a != null && b != null && (length = a.length()) == b.length()) { + if (a instanceof String && b instanceof String) { + return a.equals(b); + } else { + for (int i = 0; i < length; i++) { + if (a.charAt(i) != b.charAt(i)) + return false; + } + return true; + } + } + return false; + } public enum TruncateAt { START, @@ -103,22 +110,20 @@ public class TextUtils { * or, if it does not fit, a truncated * copy with ellipsis character added at the specified edge or center. */ - public static CharSequence ellipsize(CharSequence text, - TextPaint p, - float avail, TruncateAt where) { + public static CharSequence ellipsize(CharSequence text, TextPaint p, float avail, TruncateAt where) { return text; } public static void getChars(CharSequence s, int start, int end, char[] dest, int destoff) { Class c = s.getClass(); if (c == String.class) - ((String) s).getChars(start, end, dest, destoff); + ((String)s).getChars(start, end, dest, destoff); else if (c == StringBuffer.class) - ((StringBuffer) s).getChars(start, end, dest, destoff); + ((StringBuffer)s).getChars(start, end, dest, destoff); else if (c == StringBuilder.class) - ((StringBuilder) s).getChars(start, end, dest, destoff); + ((StringBuilder)s).getChars(start, end, dest, destoff); else if (s instanceof GetChars) - ((GetChars) s).getChars(start, end, dest, destoff); + ((GetChars)s).getChars(start, end, dest, destoff); else { for (int i = start; i < end; i++) dest[destoff++] = s.charAt(i); diff --git a/src/api-impl/android/text/format/DateFormat.java b/src/api-impl/android/text/format/DateFormat.java new file mode 100644 index 00000000..478bcb3c --- /dev/null +++ b/src/api-impl/android/text/format/DateFormat.java @@ -0,0 +1,602 @@ +/* + * 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.text.format; + +import android.content.Context; +import android.provider.Settings; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.SpannedString; +import com.android.internal.R; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; +import libcore.icu.ICU; +import libcore.icu.LocaleData; + +/** + * Utility class for producing strings with formatted date/time. + * + *

Most callers should avoid supplying their own format strings to this + * class' {@code format} methods and rely on the correctly localized ones + * supplied by the system. This class' factory methods return + * appropriately-localized {@link java.text.DateFormat} instances, suitable + * for both formatting and parsing dates. For the canonical documentation + * of format strings, see {@link java.text.SimpleDateFormat}. + * + *

In cases where the system does not provide a suitable pattern, + * this class offers the {@link #getBestDateTimePattern} method. + * + *

The {@code format} methods in this class implement a subset of Unicode + * UTS #35 patterns. + * The subset currently supported by this class includes the following format characters: + * {@code acdEHhLKkLMmsyz}. Up to API level 17, only {@code adEhkMmszy} were supported. + * Note that this class incorrectly implements {@code k} as if it were {@code H} for backwards + * compatibility. + * + *

See {@link java.text.SimpleDateFormat} for more documentation + * about patterns, or if you need a more complete or correct implementation. + * Note that the non-{@code format} methods in this class are implemented by + * {@code SimpleDateFormat}. + */ +public class DateFormat { + /** + * @deprecated Use a literal {@code '} instead. + */ + @Deprecated + public static final char QUOTE = '\''; + + /** + * @deprecated Use a literal {@code 'a'} instead. + */ + @Deprecated + public static final char AM_PM = 'a'; + + /** + * @deprecated Use a literal {@code 'a'} instead; 'A' was always equivalent to 'a'. + */ + @Deprecated + public static final char CAPITAL_AM_PM = 'A'; + + /** + * @deprecated Use a literal {@code 'd'} instead. + */ + @Deprecated + public static final char DATE = 'd'; + + /** + * @deprecated Use a literal {@code 'E'} instead. + */ + @Deprecated + public static final char DAY = 'E'; + + /** + * @deprecated Use a literal {@code 'h'} instead. + */ + @Deprecated + public static final char HOUR = 'h'; + + /** + * @deprecated Use a literal {@code 'H'} (for compatibility with {@link SimpleDateFormat} + * and Unicode) or {@code 'k'} (for compatibility with Android releases up to and including + * Jelly Bean MR-1) instead. Note that the two are incompatible. + */ + @Deprecated + public static final char HOUR_OF_DAY = 'k'; + + /** + * @deprecated Use a literal {@code 'm'} instead. + */ + @Deprecated + public static final char MINUTE = 'm'; + + /** + * @deprecated Use a literal {@code 'M'} instead. + */ + @Deprecated + public static final char MONTH = 'M'; + + /** + * @deprecated Use a literal {@code 'L'} instead. + */ + @Deprecated + public static final char STANDALONE_MONTH = 'L'; + + /** + * @deprecated Use a literal {@code 's'} instead. + */ + @Deprecated + public static final char SECONDS = 's'; + + /** + * @deprecated Use a literal {@code 'z'} instead. + */ + @Deprecated + public static final char TIME_ZONE = 'z'; + + /** + * @deprecated Use a literal {@code 'y'} instead. + */ + @Deprecated + public static final char YEAR = 'y'; + + private static final Object sLocaleLock = new Object(); + private static Locale sIs24HourLocale; + private static boolean sIs24Hour; + + /** + * Returns true if user preference is set to 24-hour format. + * @param context the context to use for the content resolver + * @return true if 24 hour time format is selected, false otherwise. + */ + public static boolean is24HourFormat(Context context) { + return true; + } + + /** + * Returns the best possible localized form of the given skeleton for the given + * locale. A skeleton is similar to, and uses the same format characters as, a Unicode + * UTS #35 + * pattern. + * + *

One difference is that order is irrelevant. For example, "MMMMd" will return + * "MMMM d" in the {@code en_US} locale, but "d. MMMM" in the {@code de_CH} locale. + * + *

Note also in that second example that the necessary punctuation for German was + * added. For the same input in {@code es_ES}, we'd have even more extra text: + * "d 'de' MMMM". + * + *

This method will automatically correct for grammatical necessity. Given the + * same "MMMMd" input, this method will return "d LLLL" in the {@code fa_IR} locale, + * where stand-alone months are necessary. Lengths are preserved where meaningful, + * so "Md" would give a different result to "MMMd", say, except in a locale such as + * {@code ja_JP} where there is only one length of month. + * + *

This method will only return patterns that are in CLDR, and is useful whenever + * you know what elements you want in your format string but don't want to make your + * code specific to any one locale. + * + * @param locale the locale into which the skeleton should be localized + * @param skeleton a skeleton as described above + * @return a string pattern suitable for use with {@link java.text.SimpleDateFormat}. + */ + public static String getBestDateTimePattern(Locale locale, String skeleton) { + return ICU.getBestDateTimePattern(skeleton, locale); + } + + /** + * Returns a {@link java.text.DateFormat} object that can format the time according + * to the current locale and the user's 12-/24-hour clock preference. + * @param context the application context + * @return the {@link java.text.DateFormat} object that properly formats the time. + */ + public static java.text.DateFormat getTimeFormat(Context context) { + return new java.text.SimpleDateFormat(getTimeFormatString(context)); + } + + /** + * Returns a String pattern that can be used to format the time according + * to the current locale and the user's 12-/24-hour clock preference. + * @param context the application context + * @hide + */ + public static String getTimeFormatString(Context context) { + return "HH:mm"; + } + + /** + * Returns a {@link java.text.DateFormat} object that can format the date + * in short form (such as 12/31/1999) according + * to the current locale and the user's date-order preference. + * @param context the application context + * @return the {@link java.text.DateFormat} object that properly formats the date. + */ + public static java.text.DateFormat getDateFormat(Context context) { + return new java.text.SimpleDateFormat(); + } + + /** + * Returns a {@link java.text.DateFormat} object to format the date + * as if the date format setting were set to value, + * including null to use the locale's default format. + * @param context the application context + * @param value the date format setting string to interpret for + * the current locale + * @hide + */ + /*public static java.text.DateFormat getDateFormatForSetting(Context context, + String value) { + String format = getDateFormatStringForSetting(context, value); + return new java.text.SimpleDateFormat(format); + } + + private static String getDateFormatStringForSetting(Context context, String value) { + if (value != null) { + int month = value.indexOf('M'); + int day = value.indexOf('d'); + int year = value.indexOf('y'); + + if (month >= 0 && day >= 0 && year >= 0) { + String template = context.getString(R.string.numeric_date_template); + if (year < month && year < day) { + if (month < day) { + value = String.format(template, "yyyy", "MM", "dd"); + } else { + value = String.format(template, "yyyy", "dd", "MM"); + } + } else if (month < day) { + if (day < year) { + value = String.format(template, "MM", "dd", "yyyy"); + } else { // unlikely + value = String.format(template, "MM", "yyyy", "dd"); + } + } else { // day < month + if (month < year) { + value = String.format(template, "dd", "MM", "yyyy"); + } else { // unlikely + value = String.format(template, "dd", "yyyy", "MM"); + } + } + + return value; + } + } + + // The setting is not set; use the locale's default. + LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); + return d.shortDateFormat4; + }*/ + + /** + * Returns a {@link java.text.DateFormat} object that can format the date + * in long form (such as {@code Monday, January 3, 2000}) for the current locale. + * @param context the application context + * @return the {@link java.text.DateFormat} object that formats the date in long form. + */ + public static java.text.DateFormat getLongDateFormat(Context context) { + return java.text.DateFormat.getDateInstance(java.text.DateFormat.LONG); + } + + /** + * Returns a {@link java.text.DateFormat} object that can format the date + * in medium form (such as {@code Jan 3, 2000}) for the current locale. + * @param context the application context + * @return the {@link java.text.DateFormat} object that formats the date in long form. + */ + public static java.text.DateFormat getMediumDateFormat(Context context) { + return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM); + } + + /** + * Gets the current date format stored as a char array. The array will contain + * 3 elements ({@link #DATE}, {@link #MONTH}, and {@link #YEAR}) in the order + * specified by the user's format preference. Note that this order is + * only appropriate for all-numeric dates; spelled-out (MEDIUM and LONG) + * dates will generally contain other punctuation, spaces, or words, + * not just the day, month, and year, and not necessarily in the same + * order returned here. + */ + public static char[] getDateFormatOrder(Context context) { + return ICU.getDateFormatOrder(getDateFormatString(context)); + } + + private static String getDateFormatString(Context context) { + return "dd. MM. yyyy"; + } + + /** + * Given a format string and a time in milliseconds since Jan 1, 1970 GMT, returns a + * CharSequence containing the requested date. + * @param inFormat the format string, as described in {@link android.text.format.DateFormat} + * @param inTimeInMillis in milliseconds since Jan 1, 1970 GMT + * @return a {@link CharSequence} containing the requested text + */ + public static CharSequence format(CharSequence inFormat, long inTimeInMillis) { + return format(inFormat, new Date(inTimeInMillis)); + } + + /** + * Given a format string and a {@link java.util.Date} object, returns a CharSequence containing + * the requested date. + * @param inFormat the format string, as described in {@link android.text.format.DateFormat} + * @param inDate the date to format + * @return a {@link CharSequence} containing the requested text + */ + public static CharSequence format(CharSequence inFormat, Date inDate) { + Calendar c = new GregorianCalendar(); + c.setTime(inDate); + return format(inFormat, c); + } + + /** + * Indicates whether the specified format string contains seconds. + * + * Always returns false if the input format is null. + * + * @param inFormat the format string, as described in {@link android.text.format.DateFormat} + * + * @return true if the format string contains {@link #SECONDS}, false otherwise + * + * @hide + */ + public static boolean hasSeconds(CharSequence inFormat) { + return hasDesignator(inFormat, SECONDS); + } + + /** + * Test if a format string contains the given designator. Always returns + * {@code false} if the input format is {@code null}. + * + * @hide + */ + public static boolean hasDesignator(CharSequence inFormat, char designator) { + if (inFormat == null) + return false; + + final int length = inFormat.length(); + + int c; + int count; + + for (int i = 0; i < length; i += count) { + count = 1; + c = inFormat.charAt(i); + + if (c == QUOTE) { + count = skipQuotedText(inFormat, i, length); + } else if (c == designator) { + return true; + } + } + + return false; + } + + private static int skipQuotedText(CharSequence s, int i, int len) { + if (i + 1 < len && s.charAt(i + 1) == QUOTE) { + return 2; + } + + int count = 1; + // skip leading quote + i++; + + while (i < len) { + char c = s.charAt(i); + + if (c == QUOTE) { + count++; + // QUOTEQUOTE -> QUOTE + if (i + 1 < len && s.charAt(i + 1) == QUOTE) { + i++; + } else { + break; + } + } else { + i++; + count++; + } + } + + return count; + } + + /** + * Given a format string and a {@link java.util.Calendar} object, returns a CharSequence + * containing the requested date. + * @param inFormat the format string, as described in {@link android.text.format.DateFormat} + * @param inDate the date to format + * @return a {@link CharSequence} containing the requested text + */ + public static CharSequence format(CharSequence inFormat, Calendar inDate) { + SpannableStringBuilder s = new SpannableStringBuilder(inFormat); + int count; + + LocaleData localeData = LocaleData.get(Locale.getDefault()); + + int len = inFormat.length(); + + for (int i = 0; i < len; i += count) { + count = 1; + int c = s.charAt(i); + + if (c == QUOTE) { + count = appendQuotedText(s, i, len); + len = s.length(); + continue; + } + + while ((i + count < len) && (s.charAt(i + count) == c)) { + count++; + } + + String replacement; + switch (c) { + case 'A': + case 'a': + replacement = localeData.amPm[inDate.get(Calendar.AM_PM) - Calendar.AM]; + break; + case 'd': + replacement = zeroPad(inDate.get(Calendar.DATE), count); + break; + case 'c': + case 'E': + replacement = getDayOfWeekString(localeData, + inDate.get(Calendar.DAY_OF_WEEK), count, c); + break; + case 'K': // hour in am/pm (0-11) + case 'h': // hour in am/pm (1-12) + { + int hour = inDate.get(Calendar.HOUR); + if (c == 'h' && hour == 0) { + hour = 12; + } + replacement = zeroPad(hour, count); + } break; + case 'H': // hour in day (0-23) + case 'k': // hour in day (1-24) [but see note below] + { + int hour = inDate.get(Calendar.HOUR_OF_DAY); + // Historically on Android 'k' was interpreted as 'H', which wasn't + // implemented, so pretty much all callers that want to format 24-hour + // times are abusing 'k'. http://b/8359981. + if (false && c == 'k' && hour == 0) { + hour = 24; + } + replacement = zeroPad(hour, count); + } break; + case 'L': + case 'M': + replacement = getMonthString(localeData, + inDate.get(Calendar.MONTH), count, c); + break; + case 'm': + replacement = zeroPad(inDate.get(Calendar.MINUTE), count); + break; + case 's': + replacement = zeroPad(inDate.get(Calendar.SECOND), count); + break; + case 'y': + replacement = getYearString(inDate.get(Calendar.YEAR), count); + break; + case 'z': + replacement = getTimeZoneString(inDate, count); + break; + default: + replacement = null; + break; + } + + if (replacement != null) { + s.replace(i, i + count, replacement); + count = replacement.length(); // CARE: count is used in the for loop above + len = s.length(); + } + } + + if (inFormat instanceof Spanned) { + return new SpannedString(s); + } else { + return s.toString(); + } + } + + private static String getDayOfWeekString(LocaleData ld, int day, int count, int kind) { + boolean standalone = (kind == 'c'); + if (count == 5) { + return standalone ? ld.tinyStandAloneWeekdayNames[day] : ld.tinyWeekdayNames[day]; + } else if (count == 4) { + return standalone ? ld.longStandAloneWeekdayNames[day] : ld.longWeekdayNames[day]; + } else { + return standalone ? ld.shortStandAloneWeekdayNames[day] : ld.shortWeekdayNames[day]; + } + } + + private static String getMonthString(LocaleData ld, int month, int count, int kind) { + boolean standalone = (kind == 'L'); + if (count == 5) { + return standalone ? ld.tinyStandAloneMonthNames[month] : ld.tinyMonthNames[month]; + } else if (count == 4) { + return standalone ? ld.longStandAloneMonthNames[month] : ld.longMonthNames[month]; + } else if (count == 3) { + return standalone ? ld.shortStandAloneMonthNames[month] : ld.shortMonthNames[month]; + } else { + // Calendar.JANUARY == 0, so add 1 to month. + return zeroPad(month + 1, count); + } + } + + private static String getTimeZoneString(Calendar inDate, int count) { + TimeZone tz = inDate.getTimeZone(); + if (count < 2) { // FIXME: shouldn't this be <= 2 ? + return formatZoneOffset(inDate.get(Calendar.DST_OFFSET) + + inDate.get(Calendar.ZONE_OFFSET), + count); + } else { + boolean dst = inDate.get(Calendar.DST_OFFSET) != 0; + return tz.getDisplayName(dst, TimeZone.SHORT); + } + } + + private static String formatZoneOffset(int offset, int count) { + offset /= 1000; // milliseconds to seconds + StringBuilder tb = new StringBuilder(); + + if (offset < 0) { + tb.insert(0, "-"); + offset = -offset; + } else { + tb.insert(0, "+"); + } + + int hours = offset / 3600; + int minutes = (offset % 3600) / 60; + + tb.append(zeroPad(hours, 2)); + tb.append(zeroPad(minutes, 2)); + return tb.toString(); + } + + private static String getYearString(int year, int count) { + return (count <= 2) ? zeroPad(year % 100, 2) + : String.format(Locale.getDefault(), "%d", year); + } + + private static int appendQuotedText(SpannableStringBuilder s, int i, int len) { + if (i + 1 < len && s.charAt(i + 1) == QUOTE) { + s.delete(i, i + 1); + return 1; + } + + int count = 0; + + // delete leading quote + s.delete(i, i + 1); + len--; + + while (i < len) { + char c = s.charAt(i); + + if (c == QUOTE) { + // QUOTEQUOTE -> QUOTE + if (i + 1 < len && s.charAt(i + 1) == QUOTE) { + + s.delete(i, i + 1); + len--; + count++; + i++; + } else { + // Closing QUOTE ends quoted text copying + s.delete(i, i + 1); + break; + } + } else { + i++; + count++; + } + } + + return count; + } + + private static String zeroPad(int inValue, int inMinDigits) { + return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue); + } +} diff --git a/src/api-impl/android/text/style/ForegroundColorSpan.java b/src/api-impl/android/text/style/ForegroundColorSpan.java new file mode 100644 index 00000000..3f397161 --- /dev/null +++ b/src/api-impl/android/text/style/ForegroundColorSpan.java @@ -0,0 +1,5 @@ +package android.text.style; + +public class ForegroundColorSpan { + public ForegroundColorSpan(int dummy) {} +} diff --git a/src/api-impl/android/text/style/MetricAffectingSpan.java b/src/api-impl/android/text/style/MetricAffectingSpan.java new file mode 100644 index 00000000..bcabef9b --- /dev/null +++ b/src/api-impl/android/text/style/MetricAffectingSpan.java @@ -0,0 +1,5 @@ +package android.text.style; + +public class MetricAffectingSpan { + +} diff --git a/src/api-impl/android/util/FloatMath.java b/src/api-impl/android/util/FloatMath.java new file mode 100644 index 00000000..2d77ddac --- /dev/null +++ b/src/api-impl/android/util/FloatMath.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.util; +/** + * Math routines similar to those found in {@link java.lang.Math}. + * + *

Historically these methods were faster than the equivalent double-based + * {@link java.lang.Math} methods. On versions of Android with a JIT they + * became slower and have since been re-implemented to wrap calls to + * {@link java.lang.Math}. {@link java.lang.Math} should be used in + * preference. + * + *

All methods were removed from the public API in version 23. + * + * @deprecated Use {@link java.lang.Math} instead. + */ +//@Deprecated +public class FloatMath { + /** + * Prevents instantiation. + */ + private FloatMath() {} + /** + * Returns the float conversion of the most positive (i.e. closest to + * positive infinity) integer value which is less than the argument. + * + * @param value to be converted + * @return the floor of value + * @removed + */ + public static float floor(float value) { + return (float)Math.floor(value); + } + /** + * Returns the float conversion of the most negative (i.e. closest to + * negative infinity) integer value which is greater than the argument. + * + * @param value to be converted + * @return the ceiling of value + * @removed + */ + public static float ceil(float value) { + return (float)Math.ceil(value); + } + /** + * Returns the closest float approximation of the sine of the argument. + * + * @param angle to compute the cosine of, in radians + * @return the sine of angle + * @removed + */ + public static float sin(float angle) { + return (float)Math.sin(angle); + } + /** + * Returns the closest float approximation of the cosine of the argument. + * + * @param angle to compute the cosine of, in radians + * @return the cosine of angle + * @removed + */ + public static float cos(float angle) { + return (float)Math.cos(angle); + } + /** + * Returns the closest float approximation of the square root of the + * argument. + * + * @param value to compute sqrt of + * @return the square root of value + * @removed + */ + public static float sqrt(float value) { + return (float)Math.sqrt(value); + } + /** + * Returns the closest float approximation of the raising "e" to the power + * of the argument. + * + * @param value to compute the exponential of + * @return the exponential of value + * @removed + */ + public static float exp(float value) { + return (float)Math.exp(value); + } + /** + * Returns the closest float approximation of the result of raising {@code + * x} to the power of {@code y}. + * + * @param x the base of the operation. + * @param y the exponent of the operation. + * @return {@code x} to the power of {@code y}. + * @removed + */ + public static float pow(float x, float y) { + return (float)Math.pow(x, y); + } + /** + * Returns {@code sqrt(}{@code x}{@code 2}{@code +} + * {@code y}{@code 2}{@code )}. + * + * @param x a float number + * @param y a float number + * @return the hypotenuse + * @removed + */ + public static float hypot(float x, float y) { + return (float)Math.hypot(x, y); + } +} diff --git a/src/api-impl/android/view/View.java b/src/api-impl/android/view/View.java index c0a76d3e..24f7c64e 100644 --- a/src/api-impl/android/view/View.java +++ b/src/api-impl/android/view/View.java @@ -867,16 +867,18 @@ public class View implements Drawable.Callback { TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, defStyle, 0); this.id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID); if (a.hasValue(com.android.internal.R.styleable.View_background)) { - Drawable background = a.getDrawable(com.android.internal.R.styleable.View_background); + try { + Drawable background = a.getDrawable(com.android.internal.R.styleable.View_background); - if(background != null) { - if(background instanceof ColorDrawable) { - System.out.printf("__background__: >%x<\n", ((ColorDrawable)background).getColor()); - setBackgroundColor(((ColorDrawable)background).getColor()); - } else { - setBackgroundDrawable(background); + if(background != null) { + if(background instanceof ColorDrawable) { + System.out.printf("__background__: >%x<\n", ((ColorDrawable)background).getColor()); + setBackgroundColor(((ColorDrawable)background).getColor()); + } else { + setBackgroundDrawable(background); + } } - } + } catch (Exception e) { e.printStackTrace(); } } if (a.hasValue(com.android.internal.R.styleable.View_visibility)) { setVisibility(VISIBILITY_FLAGS[a.getInt(com.android.internal.R.styleable.View_visibility, 0)]); @@ -1714,4 +1716,10 @@ public class View implements Drawable.Callback { public void requestFitSystemWindows() {} public boolean isPressed() {return false;} + + public void getWindowVisibleDisplayFrame(Rect rect) {} + + public void setRotationX(float deg) {} + + public void setRotationY(float deg) {} } diff --git a/src/api-impl/android/view/ViewOutlineProvider.java b/src/api-impl/android/view/ViewOutlineProvider.java index e41f20ce..76c84723 100644 --- a/src/api-impl/android/view/ViewOutlineProvider.java +++ b/src/api-impl/android/view/ViewOutlineProvider.java @@ -1,6 +1,6 @@ package android.view; public class ViewOutlineProvider { - public static final ViewOutlineProvider BACKGROUND = new ViewOutlineProvider(); + public static final ViewOutlineProvider BOUNDS = new ViewOutlineProvider(); } diff --git a/src/api-impl/android/view/WindowManager.java b/src/api-impl/android/view/WindowManager.java index 18282da4..fdc713cb 100644 --- a/src/api-impl/android/view/WindowManager.java +++ b/src/api-impl/android/view/WindowManager.java @@ -10,6 +10,7 @@ public interface WindowManager { public int softInputMode; public int x; public int y; + public int windowAnimations; public LayoutParams(int w, int h, int type, int flags, int format) { super(w, h); diff --git a/src/api-impl/android/view/accessibility/AccessibilityNodeInfo.java b/src/api-impl/android/view/accessibility/AccessibilityNodeInfo.java index f4a010a7..7c019633 100644 --- a/src/api-impl/android/view/accessibility/AccessibilityNodeInfo.java +++ b/src/api-impl/android/view/accessibility/AccessibilityNodeInfo.java @@ -1,12 +1,17 @@ package android.view.accessibility; public class AccessibilityNodeInfo { - public static final class AccessibilityAction { - + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN = new AccessibilityAction(0, null); + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_TO_POSITION = new AccessibilityAction(0, null); + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_UP = new AccessibilityAction(0, null); + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_LEFT = new AccessibilityAction(0, null); + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_RIGHT = new AccessibilityAction(0, null); + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_DOWN = new AccessibilityAction(0, null); + public static final AccessibilityNodeInfo.AccessibilityAction ACTION_CONTEXT_CLICK = new AccessibilityAction(0, null); + public AccessibilityAction(int actionId, CharSequence label) {} public int getId() {return 0;} - } } diff --git a/src/api-impl/android/view/animation/PathInterpolator.java b/src/api-impl/android/view/animation/PathInterpolator.java index 1bb2f433..4de872ec 100644 --- a/src/api-impl/android/view/animation/PathInterpolator.java +++ b/src/api-impl/android/view/animation/PathInterpolator.java @@ -1,7 +1,13 @@ package android.view.animation; +import android.graphics.Path; + public class PathInterpolator extends BaseInterpolator { + public PathInterpolator(Path path) { + super(); + } + public PathInterpolator(float f1, float f2, float f3, float f4) { super(); } diff --git a/src/api-impl/android/widget/CompoundButton.java b/src/api-impl/android/widget/CompoundButton.java index 7dbb41fc..ef92a6f8 100644 --- a/src/api-impl/android/widget/CompoundButton.java +++ b/src/api-impl/android/widget/CompoundButton.java @@ -1,14 +1,16 @@ package android.widget; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; public abstract class CompoundButton extends Button implements Checkable { + Drawable button_drawable = null; public CompoundButton(Context context) { super(context); } - + public CompoundButton(Context context, AttributeSet attributeSet) { super(context, attributeSet); } @@ -41,4 +43,12 @@ public abstract class CompoundButton extends Button implements Checkable { public void setTextColor(int color) {} @Override public void setTextSize(float size) {} + + public void setButtonDrawable(Drawable drawable) { + button_drawable = drawable; + } + + public Drawable getButtonDrawable() { + return button_drawable; + } } diff --git a/src/api-impl/android/widget/ImageView.java b/src/api-impl/android/widget/ImageView.java index ade0cfc7..0287e714 100644 --- a/src/api-impl/android/widget/ImageView.java +++ b/src/api-impl/android/widget/ImageView.java @@ -5,6 +5,7 @@ import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.PorterDuff; import android.graphics.drawable.BitmapDrawable; @@ -55,8 +56,15 @@ public class ImageView extends View { } public Drawable getDrawable() { - if(bitmap == null) - return null; + if(bitmap == null) { + return new Drawable() { + @Override + public void draw(Canvas canvas) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'draw'"); + } + }; + } return new BitmapDrawable(getContext().getResources(), bitmap); } diff --git a/src/api-impl/android/widget/ListView.java b/src/api-impl/android/widget/ListView.java index e1173086..86d23d8d 100644 --- a/src/api-impl/android/widget/ListView.java +++ b/src/api-impl/android/widget/ListView.java @@ -23,4 +23,19 @@ public class ListView extends AbsListView { public void addHeaderView(View v, Object data, boolean isSelectable) {} + public void setDrawSelectorOnTop(boolean dummy) {} + + public void addHeaderView(View view) {} + + public boolean removeHeaderView(View view) { return true; } + + public int getHeaderViewsCount() { + return 0; + } + + public int getFooterViewsCount() { + return 0; + } + + public void setDivider(Drawable drawable) {} } diff --git a/src/api-impl/android/widget/ProgressBar.java b/src/api-impl/android/widget/ProgressBar.java index 3febc1b7..47f1d00f 100644 --- a/src/api-impl/android/widget/ProgressBar.java +++ b/src/api-impl/android/widget/ProgressBar.java @@ -11,6 +11,7 @@ public class ProgressBar extends View { protected int max = 100; protected int progress = 0; + private boolean indeterminate = false; private Drawable indeterminateDrawable; public ProgressBar(Context context, AttributeSet attrs, int defStyle) { @@ -43,7 +44,15 @@ public class ProgressBar extends View { protected native long native_constructor(Context context, AttributeSet attrs); protected native void native_setProgress(long widget, float fraction); - public native void setIndeterminate(boolean indeterminate); + public boolean isIndeterminate() { + return indeterminate; + } + + public void setIndeterminate(boolean indeterminate) { + native_setIndeterminate(indeterminate); + indeterminate = true; + } + public Drawable getProgressDrawable() { return new Drawable() { @@ -82,4 +91,9 @@ public class ProgressBar extends View { public void setIndeterminateDrawable(Drawable indeterminateDrawable) { this.indeterminateDrawable = indeterminateDrawable; } + + public void setProgressDrawable(Drawable indeterminateDrawable) { + } + + public native void native_setIndeterminate(boolean indeterminate); } diff --git a/src/api-impl/android/widget/Toast.java b/src/api-impl/android/widget/Toast.java index c0ca4fa1..3e6dbed6 100644 --- a/src/api-impl/android/widget/Toast.java +++ b/src/api-impl/android/widget/Toast.java @@ -4,6 +4,10 @@ import android.content.Context; public class Toast { + public Toast(Context context) { + /* TODO */ + } + private String text; public static Toast makeText(Context context, int resId, int duration) { @@ -11,7 +15,7 @@ public class Toast { } public static Toast makeText(Context context, CharSequence text, int duration) { - Toast toast = new Toast(); + Toast toast = new Toast(context); toast.text = String.valueOf(text); return toast; } diff --git a/src/api-impl/meson.build b/src/api-impl/meson.build index 1f9b192a..f31bae25 100644 --- a/src/api-impl/meson.build +++ b/src/api-impl/meson.build @@ -50,6 +50,7 @@ hax_jar = jar('hax', [ 'android/app/job/JobService.java', 'android/appwidget/AppWidgetManager.java', 'android/bluetooth/BluetoothManager.java', + 'android/bluetooth/le/ScanCallback.java', 'android/content/ActivityNotFoundException.java', 'android/content/BroadcastReceiver.java', 'android/content/ClipboardManager.java', @@ -163,11 +164,17 @@ hax_jar = jar('hax', [ 'android/graphics/Canvas.java', 'android/graphics/Color.java', 'android/graphics/ColorFilter.java', + 'android/graphics/ColorMatrix.java', + 'android/graphics/ColorMatrixColorFilter.java', + 'android/graphics/CornerPathEffect.java', + 'android/graphics/DashPathEffect.java', 'android/graphics/GskCanvas.java', 'android/graphics/LinearGradient.java', 'android/graphics/Matrix.java', 'android/graphics/Paint.java', 'android/graphics/Path.java', + 'android/graphics/PathEffect.java', + 'android/graphics/PathMeasure.java', 'android/graphics/Point.java', 'android/graphics/PointF.java', 'android/graphics/PorterDuff.java', @@ -231,6 +238,7 @@ hax_jar = jar('hax', [ 'android/net/ConnectivityManager.java', 'android/net/NetworkInfo.java', 'android/net/NetworkRequest.java', + 'android/net/TrafficStats.java', 'android/net/Uri.java', 'android/net/http/X509TrustManagerExtensions.java', 'android/net/nsd/NsdManager.java', @@ -276,6 +284,7 @@ hax_jar = jar('hax', [ 'android/os/RemoteException.java', 'android/os/ResultReceiver.java', 'android/os/StatFs.java', + 'android/os/StrictMode.java', 'android/os/SystemClock.java', 'android/os/Trace.java', 'android/os/UserHandle.java', @@ -310,6 +319,7 @@ hax_jar = jar('hax', [ 'android/text/TextPaint.java', 'android/text/TextUtils.java', 'android/text/TextWatcher.java', + 'android/text/format/DateFormat.java', 'android/text/format/Formatter.java', 'android/text/method/KeyListener.java', 'android/text/method/LinkMovementMethod.java', @@ -319,6 +329,8 @@ hax_jar = jar('hax', [ 'android/text/method/TransformationMethod.java', 'android/text/style/CharacterStyle.java', 'android/text/style/ClickableSpan.java', + 'android/text/style/ForegroundColorSpan.java', + 'android/text/style/MetricAffectingSpan.java', 'android/text/style/StyleSpan.java', 'android/text/style/URLSpan.java', 'android/text/util/Linkify.java', @@ -333,6 +345,7 @@ hax_jar = jar('hax', [ 'android/util/ContainerHelpers.java', 'android/util/DecompiledXmlResourceParser.java', 'android/util/DisplayMetrics.java', + 'android/util/FloatMath.java', 'android/util/LayoutDirection.java', 'android/util/Log.java', 'android/util/LongSparseArray.java',