diff --git a/src/api-impl-jni/android_os_SystemClock.c b/src/api-impl-jni/android_os_SystemClock.c index 752723b6..189c6996 100644 --- a/src/api-impl-jni/android_os_SystemClock.c +++ b/src/api-impl-jni/android_os_SystemClock.c @@ -17,3 +17,10 @@ JNIEXPORT jlong JNICALL Java_android_os_SystemClock_uptimeMillis(JNIEnv *env, jc clock_gettime(CLOCK_MONOTONIC, &now); return now.tv_sec * 1000 + lround(now.tv_nsec / 1e6); } + +JNIEXPORT jlong JNICALL Java_android_os_SystemClock_elapsedRealtimeNanos(JNIEnv *env, jclass this) +{ + struct timespec t; + clock_gettime(CLOCK_BOOTTIME, &t); + return t.tv_sec * 1000000000 + t.tv_nsec; +} diff --git a/src/api-impl-jni/generated_headers/android_os_Process.h b/src/api-impl-jni/generated_headers/android_os_Process.h index 5aabff04..ba86acb1 100644 --- a/src/api-impl-jni/generated_headers/android_os_Process.h +++ b/src/api-impl-jni/generated_headers/android_os_Process.h @@ -273,14 +273,6 @@ JNIEXPORT void JNICALL Java_android_os_Process_readProcLines JNIEXPORT jintArray JNICALL Java_android_os_Process_getPids (JNIEnv *, jclass, jstring, jintArray); -/* - * Class: android_os_Process - * Method: readProcFile - * Signature: (Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z - */ -JNIEXPORT jboolean JNICALL Java_android_os_Process_readProcFile - (JNIEnv *, jclass, jstring, jintArray, jobjectArray, jlongArray, jfloatArray); - /* * Class: android_os_Process * Method: parseProcLine diff --git a/src/api-impl/android/animation/Animator.java b/src/api-impl/android/animation/Animator.java index a4ddf6c5..7dc3153a 100644 --- a/src/api-impl/android/animation/Animator.java +++ b/src/api-impl/android/animation/Animator.java @@ -27,4 +27,6 @@ public class Animator { public Animator setDuration(long duration) { return this; } + public void setInterpolator(TimeInterpolator i) {} + } diff --git a/src/api-impl/android/animation/PropertyValuesHolder.java b/src/api-impl/android/animation/PropertyValuesHolder.java index 96ab7ec0..bd8a7e00 100644 --- a/src/api-impl/android/animation/PropertyValuesHolder.java +++ b/src/api-impl/android/animation/PropertyValuesHolder.java @@ -4,4 +4,8 @@ public class PropertyValuesHolder{ public static PropertyValuesHolder ofFloat(String propertyName, float... values) { return null; } + + public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, Object... values) { + return null; + } } diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index 51b3cf7d..88dd3c13 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -3,7 +3,7 @@ package android.app; import android.R; import android.content.BroadcastReceiver; import android.content.ComponentName; -import android.content.ContextWrapper; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageParser; @@ -12,6 +12,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -28,7 +29,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class Activity extends ContextWrapper implements Window.Callback { +public class Activity extends ContextThemeWrapper implements Window.Callback { LayoutInflater layout_inflater; Window window = new Window(this); int requested_orientation = -1 /*ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED*/; // dummy @@ -54,7 +55,7 @@ public class Activity extends ContextWrapper implements Window.Callback { if (className == null) { for (PackageParser.Activity activity: pkg.activities) { for (PackageParser.IntentInfo intent: activity.intents) { - if (intent.matchAction("android.intent.action.MAIN")) { + if (intent.hasCategory("android.intent.category.LAUNCHER")) { className = activity.className; break; } @@ -74,23 +75,27 @@ public class Activity extends ContextWrapper implements Window.Callback { public Activity() { super(null); - layout_inflater = new LayoutInflater(); + layout_inflater = new LayoutInflater(this); intent = new Intent(); CharSequence label = null; CharSequence app_label = null; + int themeResId = 0; for (PackageParser.Activity activity: pkg.activities) { if (getClass().getName().equals(activity.className)) { - label = getText(activity.info.labelRes); + label = r.getText(activity.info.labelRes); + themeResId = activity.info.getThemeResource(); break; } } - app_label = getText(pkg.applicationInfo.labelRes); + app_label = r.getText(pkg.applicationInfo.labelRes); if (label != null) { setTitle(label); } else if (app_label != null) { setTitle(app_label); } + attachBaseContext(new Context()); + setTheme(themeResId); } public View root_view; @@ -422,6 +427,10 @@ public class Activity extends ContextWrapper implements Window.Callback { this.title = title; } + public void setTitle(int titleId) { + this.title = getText(titleId); + } + public CharSequence getTitle() { return title; } @@ -488,6 +497,10 @@ public class Activity extends ContextWrapper implements Window.Callback { return destroyed; } + public void finishAffinity() { + finish(); + } + 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/ActivityManager.java b/src/api-impl/android/app/ActivityManager.java index 30c2b619..53e89625 100644 --- a/src/api-impl/android/app/ActivityManager.java +++ b/src/api-impl/android/app/ActivityManager.java @@ -5,7 +5,9 @@ import java.util.List; public class ActivityManager { - public static class RunningAppProcessInfo{} + public static class RunningAppProcessInfo{ + public int importance; + } public List getRunningAppProcesses() { return null; @@ -16,6 +18,8 @@ public class ActivityManager { public static class MemoryInfo { /* For now, just always report there's 10GB free RAM */ public long availMem = 10000; + + public long totalMem = 10000; } public void getMemoryInfo(MemoryInfo outInfo) @@ -26,4 +30,8 @@ public class ActivityManager { public ConfigurationInfo getDeviceConfigurationInfo() { return new ConfigurationInfo(); } + + public int getMemoryClass() {return 20;} // suggested heap size in MB + + public static void getMyMemoryState(RunningAppProcessInfo outInfo) {} } diff --git a/src/api-impl/android/app/AlarmManager.java b/src/api-impl/android/app/AlarmManager.java index 1367a4d7..f9b58ebb 100644 --- a/src/api-impl/android/app/AlarmManager.java +++ b/src/api-impl/android/app/AlarmManager.java @@ -2,4 +2,8 @@ package android.app; public class AlarmManager { public void cancel(PendingIntent operation) {} + + public void setInexactRepeating(int type, long triggerTime, long interval, PendingIntent operation) {} + + public void setExact(int type, long triggerTime, PendingIntent operation) {} } diff --git a/src/api-impl/android/app/Application.java b/src/api-impl/android/app/Application.java index 1da8c672..0fa422bf 100644 --- a/src/api-impl/android/app/Application.java +++ b/src/api-impl/android/app/Application.java @@ -41,7 +41,7 @@ public class Application extends ContextWrapper { } public Application() { - super(new Context()); + super(null); } /** * Called when the application is starting, before any activity, service, diff --git a/src/api-impl/android/app/Dialog.java b/src/api-impl/android/app/Dialog.java index 1e13b937..9bcdb48f 100644 --- a/src/api-impl/android/app/Dialog.java +++ b/src/api-impl/android/app/Dialog.java @@ -22,6 +22,7 @@ public class Dialog implements Window.Callback, DialogInterface { private Context context; private Window window; private OnDismissListener onDismissListener; + private OnShowListener onShowListener; public Dialog(Context context, int themeResId) { this.context = context; @@ -75,6 +76,8 @@ public class Dialog implements Window.Callback, DialogInterface { public void run() { onCreate(null); nativeShow(nativePtr); + if (onShowListener != null) + onShowListener.onShow(Dialog.this); } }; if(Looper.myLooper() == Looper.getMainLooper()) { @@ -160,4 +163,8 @@ public class Dialog implements Window.Callback, DialogInterface { public void cancel() { dismiss(); } + + public void setOnShowListener(OnShowListener onShowListener) { + this.onShowListener = onShowListener; + } } diff --git a/src/api-impl/android/app/KeyguardManager.java b/src/api-impl/android/app/KeyguardManager.java index 3fc210ec..81c1f195 100644 --- a/src/api-impl/android/app/KeyguardManager.java +++ b/src/api-impl/android/app/KeyguardManager.java @@ -4,4 +4,8 @@ public class KeyguardManager { public boolean inKeyguardRestrictedInputMode() { return false; } + + public boolean isKeyguardLocked() { + return false; + } } diff --git a/src/api-impl/android/app/NotificationManager.java b/src/api-impl/android/app/NotificationManager.java index b49d4ace..12234625 100644 --- a/src/api-impl/android/app/NotificationManager.java +++ b/src/api-impl/android/app/NotificationManager.java @@ -4,6 +4,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Handler; +import android.os.Looper; public class NotificationManager { public void cancelAll() {} @@ -40,7 +41,7 @@ public class NotificationManager { public void cancel(String tag, final int id) { // remove_notification doesn't work reliably when sent directly after add_notification in GNOME session. // So we give some extra delay here. - new Handler().postDelayed(new Runnable() { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { nativeCancel(id); diff --git a/src/api-impl/android/app/Service.java b/src/api-impl/android/app/Service.java index e54507c4..422a32d6 100644 --- a/src/api-impl/android/app/Service.java +++ b/src/api-impl/android/app/Service.java @@ -25,4 +25,12 @@ public abstract class Service extends Context { public Application getApplication() { return this_application; } + + public void stopSelf(int startId) { + System.out.println("Service.stopSelf(" + startId + ") called"); + } + + public void stopSelf() { + System.out.println("Service.stopSelf() called"); + } } diff --git a/src/api-impl/android/bluetooth/BluetoothAdapter.java b/src/api-impl/android/bluetooth/BluetoothAdapter.java new file mode 100644 index 00000000..0bf3896c --- /dev/null +++ b/src/api-impl/android/bluetooth/BluetoothAdapter.java @@ -0,0 +1,8 @@ +package android.bluetooth; + +public class BluetoothAdapter { + + public static BluetoothAdapter getDefaultAdapter() { + return null; + } +} diff --git a/src/api-impl/android/bluetooth/BluetoothProfile.java b/src/api-impl/android/bluetooth/BluetoothProfile.java new file mode 100644 index 00000000..42eec903 --- /dev/null +++ b/src/api-impl/android/bluetooth/BluetoothProfile.java @@ -0,0 +1,6 @@ +package android.bluetooth; + +public class BluetoothProfile { + + public interface ServiceListener {} +} diff --git a/src/api-impl/android/content/ContentProvider.java b/src/api-impl/android/content/ContentProvider.java index a1dca394..4d3b372b 100644 --- a/src/api-impl/android/content/ContentProvider.java +++ b/src/api-impl/android/content/ContentProvider.java @@ -17,7 +17,7 @@ public class ContentProvider { public boolean onCreate() {return false;} public Context getContext() { - return Context.this_application; + return new Context(); } } diff --git a/src/api-impl/android/content/Context.java b/src/api-impl/android/content/Context.java index 28704792..340f3976 100644 --- a/src/api-impl/android/content/Context.java +++ b/src/api-impl/android/content/Context.java @@ -41,6 +41,7 @@ import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Slog; +import android.view.Display; import android.view.LayoutInflater; import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityManager; @@ -128,6 +129,7 @@ public class Context extends Object { application.setTheme(pkg.applicationInfo.theme); application.native_window = native_window; this_application = application; + application.attachBaseContext(new Context()); return application; } @@ -199,7 +201,7 @@ public class Context extends Object { case "accessibility": return new AccessibilityManager(); case "layout_inflater": - return new LayoutInflater(); + return new LayoutInflater(getApplicationContext()); case "wifi": return new WifiManager(); default: @@ -214,14 +216,7 @@ public class Context extends Object { } public Looper getMainLooper() { - /* TODO: this is not what AOSP does, which could be a problem */ - Looper looper = Looper.myLooper(); - if(looper == null) { - Looper.prepare(); - looper = Looper.myLooper(); - } - - return looper; + return Looper.getMainLooper(); } public String getPackageName() { @@ -452,7 +447,7 @@ public class Context extends Object { return false; } - new Handler().post(new Runnable() { // run this asynchron so the caller can finish its setup before onServiceConnected is called + new Handler(Looper.getMainLooper()).post(new Runnable() { // run this asynchron so the caller can finish its setup before onServiceConnected is called @Override public void run() { try { @@ -490,15 +485,26 @@ public class Context extends Object { } return; } - try { - Class cls = Class.forName(intent.getComponent().getClassName()).asSubclass(Activity.class); - Constructor constructor = cls.getConstructor(); - Activity activity = constructor.newInstance(); - activity.intent = intent; - activity.getWindow().native_window = this_application.native_window; - Activity.nativeStartActivity(activity); - } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - e.printStackTrace(); + final Intent intent_ = intent; + Runnable runnable = new Runnable() { + @Override + public void run() { + try { + Class cls = Class.forName(intent_.getComponent().getClassName()).asSubclass(Activity.class); + Constructor constructor = cls.getConstructor(); + Activity activity = constructor.newInstance(); + activity.intent = intent_; + activity.getWindow().native_window = this_application.native_window; + Activity.nativeStartActivity(activity); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + if (Looper.myLooper() == Looper.getMainLooper()) { + runnable.run(); + } else { + new Handler(Looper.getMainLooper()).post(runnable); } } @@ -576,6 +582,18 @@ public class Context extends Object { } public Context createConfigurationContext(Configuration configuration) { - return this; + return new Context(); + } + + public void sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler handler, int flags, String extra, Bundle options) { + System.out.println("sendOrderedBroadcast(" + intent + ", " + receiverPermission + ", " + resultReceiver + ", " + handler + ", " + flags + ", " + extra + ", " + options + ") called"); + } + + public Context createDisplayContext(Display display) { + return new Context(); + } + + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { + return registerReceiver(receiver, filter); } } diff --git a/src/api-impl/android/content/ContextWrapper.java b/src/api-impl/android/content/ContextWrapper.java index 4c300f1c..e900ce1d 100644 --- a/src/api-impl/android/content/ContextWrapper.java +++ b/src/api-impl/android/content/ContextWrapper.java @@ -10,4 +10,9 @@ public class ContextWrapper extends Context { public Context getBaseContext() { return baseContext; } + + protected void attachBaseContext(Context baseContext) { + this.baseContext = baseContext; + } + } diff --git a/src/api-impl/android/content/DialogInterface.java b/src/api-impl/android/content/DialogInterface.java index bc42f158..28ff4934 100644 --- a/src/api-impl/android/content/DialogInterface.java +++ b/src/api-impl/android/content/DialogInterface.java @@ -19,6 +19,7 @@ public interface DialogInterface { void onClick(DialogInterface dialog, int which); } public interface OnShowListener { + void onShow(DialogInterface dialog); } public interface OnCancelListener { } diff --git a/src/api-impl/android/content/Intent.java b/src/api-impl/android/content/Intent.java index 7517f4e5..94926800 100644 --- a/src/api-impl/android/content/Intent.java +++ b/src/api-impl/android/content/Intent.java @@ -314,4 +314,8 @@ public class Intent { public ArrayList getParcelableArrayListExtra(String name) { return extras.getParcelableArrayList(name); } + + public String getPackage() { + return component.getPackageName(); + } } diff --git a/src/api-impl/android/content/IntentFilter.java b/src/api-impl/android/content/IntentFilter.java index c1205d8c..b05a161c 100644 --- a/src/api-impl/android/content/IntentFilter.java +++ b/src/api-impl/android/content/IntentFilter.java @@ -1,11 +1,14 @@ package android.content; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; public class IntentFilter { - private Set actions = new HashSet<>(); + private List actions = new ArrayList<>(); + private Set categories = new HashSet<>(); public IntentFilter() {} public IntentFilter(String action) { @@ -22,4 +25,19 @@ public class IntentFilter { public final boolean matchAction(String action) { return actions.contains(action); } + + public void addCategory(String category) { + categories.add(category); + } + public int countCategories() { + return categories.size(); + } + + public final boolean hasCategory(String category) { + return categories.contains(category); + } + + public String getAction(int index) { + return actions.get(index); + } } diff --git a/src/api-impl/android/content/pm/ApplicationInfo.java b/src/api-impl/android/content/pm/ApplicationInfo.java index da4aba69..bc8b9c8e 100644 --- a/src/api-impl/android/content/pm/ApplicationInfo.java +++ b/src/api-impl/android/content/pm/ApplicationInfo.java @@ -472,6 +472,8 @@ public class ApplicationInfo extends PackageItemInfo { */ public int installLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; + public String[] splitSourceDirs; + public void dump(Printer pw, String prefix) { super.dumpFront(pw, prefix); if (className != null) { diff --git a/src/api-impl/android/content/pm/PackageManager.java b/src/api-impl/android/content/pm/PackageManager.java index fc325c56..a3500c58 100644 --- a/src/api-impl/android/content/pm/PackageManager.java +++ b/src/api-impl/android/content/pm/PackageManager.java @@ -1670,7 +1670,12 @@ public class PackageManager { */ public ServiceInfo getServiceInfo(ComponentName component, int flags) throws NameNotFoundException { - return null; + for (PackageParser.Service s : Context.pkg.services) { + if (s.className.equals(component.getClassName())) { + return s.info; + } + } + return new ServiceInfo(); } /** diff --git a/src/api-impl/android/content/pm/PackageParser.java b/src/api-impl/android/content/pm/PackageParser.java index dbdabc99..16fa0119 100644 --- a/src/api-impl/android/content/pm/PackageParser.java +++ b/src/api-impl/android/content/pm/PackageParser.java @@ -2245,6 +2245,7 @@ public class PackageParser { return false; } XmlUtils.skipCurrentTag(parser); + outInfo.addCategory(value); } else if (nodeName.equals("data")) { XmlUtils.skipCurrentTag(parser); } else if (!RIGID_PARSER) { diff --git a/src/api-impl/android/content/res/Resources.java b/src/api-impl/android/content/res/Resources.java index 3bf64293..6fb7f400 100644 --- a/src/api-impl/android/content/res/Resources.java +++ b/src/api-impl/android/content/res/Resources.java @@ -103,7 +103,7 @@ public class Resources { /*package*/ final Object mAccessLock = new Object(); /*package*/ final Configuration mTmpConfig = new Configuration(); /*package*/ TypedValue mTmpValue = new TypedValue(); - /*package*/ final LongSparseArray> mDrawableCache = new LongSparseArray>(0); + /*package*/ final Map> mDrawableCache = new HashMap>(0); /*package*/ final LongSparseArray> mColorStateListCache = new LongSparseArray>(0); /*package*/ final LongSparseArray> mColorDrawableCache = new LongSparseArray>(0); /*package*/ boolean mPreloading; diff --git a/src/api-impl/android/graphics/Paint.java b/src/api-impl/android/graphics/Paint.java index d6ab256d..9ec1a67c 100644 --- a/src/api-impl/android/graphics/Paint.java +++ b/src/api-impl/android/graphics/Paint.java @@ -88,6 +88,8 @@ public class Paint { public float measureText(char[] text, int index, int count) { return 10; } public float measureText(String text, int start, int end) { return 10; } public float measureText(String text) { + if (skia_font == 0) + skia_font = native_create_font(); return native_measure_text(skia_font, text, 0, text.length(), skia_paint); } public float measureText(CharSequence text, int start, int end) { return 10; } diff --git a/src/api-impl/android/graphics/drawable/Drawable.java b/src/api-impl/android/graphics/drawable/Drawable.java index 16d8c03c..a6641c92 100644 --- a/src/api-impl/android/graphics/drawable/Drawable.java +++ b/src/api-impl/android/graphics/drawable/Drawable.java @@ -211,7 +211,9 @@ public class Drawable { drawable.inflate(resources, parser, attrs, null); return drawable; } else if ("layer-list".equals(parser.getName())) { - return new LayerDrawable(); + LayerDrawable drawable = new LayerDrawable(); + drawable.inflate(resources, parser, attrs); + return drawable; } return null; } diff --git a/src/api-impl/android/graphics/drawable/InsetDrawable.java b/src/api-impl/android/graphics/drawable/InsetDrawable.java index 8224e34a..4617d7d1 100644 --- a/src/api-impl/android/graphics/drawable/InsetDrawable.java +++ b/src/api-impl/android/graphics/drawable/InsetDrawable.java @@ -8,6 +8,10 @@ public class InsetDrawable extends Drawable { super(); } + public InsetDrawable(Drawable drawable, int inset) { + super(); + } + public boolean getPadding(Rect padding) { return false; } } diff --git a/src/api-impl/android/graphics/drawable/LayerDrawable.java b/src/api-impl/android/graphics/drawable/LayerDrawable.java index f0266b1d..753c31a9 100644 --- a/src/api-impl/android/graphics/drawable/LayerDrawable.java +++ b/src/api-impl/android/graphics/drawable/LayerDrawable.java @@ -162,7 +162,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { dr = Drawable.createFromXmlInner(r, parser, attrs); } - addLayer(dr, id, left, top, right, bottom); + if (dr != null) + addLayer(dr, id, left, top, right, bottom); } ensurePadding(); diff --git a/src/api-impl/android/graphics/drawable/shapes/RoundRectShape.java b/src/api-impl/android/graphics/drawable/shapes/RoundRectShape.java new file mode 100644 index 00000000..15c55eb0 --- /dev/null +++ b/src/api-impl/android/graphics/drawable/shapes/RoundRectShape.java @@ -0,0 +1,8 @@ +package android.graphics.drawable.shapes; + +import android.graphics.RectF; + +public class RoundRectShape extends Shape { + + public RoundRectShape(float[] outerR, RectF innerR, float[] cornR) {} +} diff --git a/src/api-impl/android/hardware/display/DisplayManager.java b/src/api-impl/android/hardware/display/DisplayManager.java index 68ffba0d..66ab9037 100644 --- a/src/api-impl/android/hardware/display/DisplayManager.java +++ b/src/api-impl/android/hardware/display/DisplayManager.java @@ -12,4 +12,8 @@ public final class DisplayManager { public void registerDisplayListener(DisplayListener listener, Handler handler) { } + + public Display[] getDisplays() { + return new Display[0]; + } } diff --git a/src/api-impl/android/media/MediaFormat.java b/src/api-impl/android/media/MediaFormat.java index ee44d9be..fa8b66d2 100644 --- a/src/api-impl/android/media/MediaFormat.java +++ b/src/api-impl/android/media/MediaFormat.java @@ -39,4 +39,12 @@ public class MediaFormat { public String toString() { return map.toString(); } + + public String getString(String name) { + return (String) map.get(name); + } + + public long getLong(String name) { + return (long) map.get(name); + } } diff --git a/src/api-impl/android/net/ConnectivityManager.java b/src/api-impl/android/net/ConnectivityManager.java index a9108567..0d2fa26c 100644 --- a/src/api-impl/android/net/ConnectivityManager.java +++ b/src/api-impl/android/net/ConnectivityManager.java @@ -22,4 +22,8 @@ public class ConnectivityManager { public native boolean isActiveNetworkMetered(); protected native boolean nativeGetNetworkAvailable(); + + public NetworkInfo[] getAllNetworkInfo() { + return new NetworkInfo[] { getActiveNetworkInfo() }; + } } diff --git a/src/api-impl/android/net/NetworkInfo.java b/src/api-impl/android/net/NetworkInfo.java index ae5c70f6..8755a352 100644 --- a/src/api-impl/android/net/NetworkInfo.java +++ b/src/api-impl/android/net/NetworkInfo.java @@ -31,4 +31,20 @@ public class NetworkInfo { public boolean isConnectedOrConnecting() { return false; } + + public int getSubtype() { + return 0; // NETWORK_TYPE_UNKNOWN + } + + public boolean isRoaming() { + return false; + } + + public String getTypeName() { + return "UNKNOWN"; + } + + public String getSubtypeName() { + return "UNKNOWN"; + } } diff --git a/src/api-impl/android/net/SSLSessionCache.java b/src/api-impl/android/net/SSLSessionCache.java new file mode 100644 index 00000000..f15cbdb6 --- /dev/null +++ b/src/api-impl/android/net/SSLSessionCache.java @@ -0,0 +1,9 @@ +package android.net; + +import java.io.File; + +public class SSLSessionCache { + + public SSLSessionCache(File cacheDir) {} + +} diff --git a/src/api-impl/android/net/TrafficStats.java b/src/api-impl/android/net/TrafficStats.java index 49e83bd3..af39a858 100644 --- a/src/api-impl/android/net/TrafficStats.java +++ b/src/api-impl/android/net/TrafficStats.java @@ -2,4 +2,6 @@ package android.net; public class TrafficStats { public static void setThreadStatsTag(int dummy) {} + + public static void clearThreadStatsTag() {} } diff --git a/src/api-impl/android/net/Uri.java b/src/api-impl/android/net/Uri.java index 427bb113..bb8b34aa 100644 --- a/src/api-impl/android/net/Uri.java +++ b/src/api-impl/android/net/Uri.java @@ -184,6 +184,11 @@ public class Uri implements Parcelable { return this; } + public Builder path(String path) { + this.path = "/" + path; + return this; + } + public Uri build() throws URISyntaxException { if ("content".equals(scheme)) { // hack: content providers not yet supported scheme = "file"; diff --git a/src/api-impl/android/net/UrlQuerySanitizer.java b/src/api-impl/android/net/UrlQuerySanitizer.java new file mode 100644 index 00000000..3c350558 --- /dev/null +++ b/src/api-impl/android/net/UrlQuerySanitizer.java @@ -0,0 +1,13 @@ +package android.net; + +import java.util.Collections; +import java.util.Set; + +public class UrlQuerySanitizer { + + public UrlQuerySanitizer(String url) {} + + public Set getParameterSet() { + return Collections.emptySet(); + } +} diff --git a/src/api-impl/android/os/Build.java b/src/api-impl/android/os/Build.java index 8ed4de77..8bfcaaa4 100644 --- a/src/api-impl/android/os/Build.java +++ b/src/api-impl/android/os/Build.java @@ -101,6 +101,8 @@ public class Build { */ public static final String SERIAL = getString("ro.serialno"); + public static final String[] SUPPORTED_ABIS = {CPU_ABI, CPU_ABI2}; + /** * Various version strings. */ diff --git a/src/api-impl/android/os/ConditionVariable.java b/src/api-impl/android/os/ConditionVariable.java index 346cc5d4..97d16d05 100644 --- a/src/api-impl/android/os/ConditionVariable.java +++ b/src/api-impl/android/os/ConditionVariable.java @@ -7,4 +7,6 @@ public class ConditionVariable { public void open() {} public void block() {} + + public void close() {} } diff --git a/src/api-impl/android/os/DeadObjectException.java b/src/api-impl/android/os/DeadObjectException.java new file mode 100644 index 00000000..2b4eeaa9 --- /dev/null +++ b/src/api-impl/android/os/DeadObjectException.java @@ -0,0 +1,4 @@ +package android.os; + +public class DeadObjectException extends RemoteException { +} diff --git a/src/api-impl/android/os/Debug.java b/src/api-impl/android/os/Debug.java index e7e0deae..089c6f16 100644 --- a/src/api-impl/android/os/Debug.java +++ b/src/api-impl/android/os/Debug.java @@ -11,4 +11,8 @@ public final class Debug { public InstructionCount() { } } + + public static boolean isDebuggerConnected() { + return false; + } } diff --git a/src/api-impl/android/os/Environment.java b/src/api-impl/android/os/Environment.java index a81ae0ec..3b29777c 100644 --- a/src/api-impl/android/os/Environment.java +++ b/src/api-impl/android/os/Environment.java @@ -265,7 +265,7 @@ public class Environment { * Return the user data directory. */ public static File getDataDirectory() { - return DATA_DIRECTORY; + return getExternalStorageDirectory(); } /** diff --git a/src/api-impl/android/os/Parcel.java b/src/api-impl/android/os/Parcel.java index 1da28ac6..426eba7c 100644 --- a/src/api-impl/android/os/Parcel.java +++ b/src/api-impl/android/os/Parcel.java @@ -15,4 +15,24 @@ public class Parcel { public void setDataPosition(int position) {} public void recycle() {} + + public void writeByte(byte b) { + System.out.println("Parcel.writeByte(" + b + ")"); + } + + public void writeString(String s) { + System.out.println("Parcel.writeString(" + s + ")"); + } + + public void writeLong(long l) { + System.out.println("Parcel.writeLong(" + l + ")"); + } + + public void writeInt(int i) { + System.out.println("Parcel.writeInt(" + i + ")"); + } + + public byte[] marshall() { + return new byte[0]; + } } diff --git a/src/api-impl/android/os/PowerManager.java b/src/api-impl/android/os/PowerManager.java index 95c16932..b85854ef 100644 --- a/src/api-impl/android/os/PowerManager.java +++ b/src/api-impl/android/os/PowerManager.java @@ -9,6 +9,8 @@ public final class PowerManager { public void release() {} public boolean isHeld() { return false; } + + public void acquire(long timeout) {} } public WakeLock newWakeLock(int levelAndFlags, String tag) { @@ -18,4 +20,8 @@ public final class PowerManager { public void userActivity(long dummy, boolean dummy2) {} public static final int FULL_WAKE_LOCK = 0x1a; + + public boolean isPowerSaveMode() { return false; } + + public boolean isScreenOn() { return true; } } diff --git a/src/api-impl/android/os/Process.java b/src/api-impl/android/os/Process.java index ee96a995..a5ad494e 100644 --- a/src/api-impl/android/os/Process.java +++ b/src/api-impl/android/os/Process.java @@ -785,8 +785,11 @@ public class Process { /** * @hide */ - public static final native boolean readProcFile(String file, int[] format, - String[] outStrings, long[] outLongs, float[] outFloats); + public static final /*native*/ boolean readProcFile(String file, int[] format, + String[] outStrings, long[] outLongs, float[] outFloats) { + System.out.println("readProcFile(" + file + ") called"); + return false; + } /** * @hide diff --git a/src/api-impl/android/os/StrictMode.java b/src/api-impl/android/os/StrictMode.java index 245230ab..16b0952b 100644 --- a/src/api-impl/android/os/StrictMode.java +++ b/src/api-impl/android/os/StrictMode.java @@ -3,6 +3,8 @@ package android.os; public final class StrictMode { public static void setThreadPolicy(final ThreadPolicy policy) {} public static void setVmPolicy(final VmPolicy policy) {} + public static ThreadPolicy allowThreadDiskWrites() {return null;} + public static ThreadPolicy allowThreadDiskReads() {return null;} public static final class ThreadPolicy { public static final class Builder { diff --git a/src/api-impl/android/provider/ContactsContract.java b/src/api-impl/android/provider/ContactsContract.java new file mode 100644 index 00000000..c7c27a4b --- /dev/null +++ b/src/api-impl/android/provider/ContactsContract.java @@ -0,0 +1,13 @@ +package android.provider; + +import android.net.Uri; + +public class ContactsContract { + + public static final class CommonDataKinds { + + public static class Phone { + public static final Uri CONTENT_URI = null; + } + } +} diff --git a/src/api-impl/android/telephony/TelephonyManager.java b/src/api-impl/android/telephony/TelephonyManager.java index 5eb47f0d..985a6ad5 100644 --- a/src/api-impl/android/telephony/TelephonyManager.java +++ b/src/api-impl/android/telephony/TelephonyManager.java @@ -31,4 +31,10 @@ public class TelephonyManager { public CellLocation getCellLocation() { return new CellLocation(); } + + public boolean isNetworkRoaming() { + return false; + } + + public void listen(PhoneStateListener listener, int events) {} } diff --git a/src/api-impl/android/text/method/BaseMovementMethod.java b/src/api-impl/android/text/method/BaseMovementMethod.java new file mode 100644 index 00000000..42963f97 --- /dev/null +++ b/src/api-impl/android/text/method/BaseMovementMethod.java @@ -0,0 +1,4 @@ +package android.text.method; + +public class BaseMovementMethod implements MovementMethod { +} diff --git a/src/api-impl/android/text/method/LinkMovementMethod.java b/src/api-impl/android/text/method/LinkMovementMethod.java index 92a01feb..abba0a36 100644 --- a/src/api-impl/android/text/method/LinkMovementMethod.java +++ b/src/api-impl/android/text/method/LinkMovementMethod.java @@ -1,6 +1,6 @@ package android.text.method; -public class LinkMovementMethod extends MovementMethod { +public class LinkMovementMethod extends BaseMovementMethod { public static MovementMethod getInstance() { return new LinkMovementMethod(); diff --git a/src/api-impl/android/text/method/MovementMethod.java b/src/api-impl/android/text/method/MovementMethod.java index bc453de4..46ccd11b 100644 --- a/src/api-impl/android/text/method/MovementMethod.java +++ b/src/api-impl/android/text/method/MovementMethod.java @@ -1,4 +1,4 @@ package android.text.method; -public class MovementMethod { +public interface MovementMethod { } diff --git a/src/api-impl/android/text/style/UpdateAppearance.java b/src/api-impl/android/text/style/UpdateAppearance.java new file mode 100644 index 00000000..5112f5e5 --- /dev/null +++ b/src/api-impl/android/text/style/UpdateAppearance.java @@ -0,0 +1,4 @@ +package android.text.style; + +public interface UpdateAppearance { +} diff --git a/src/api-impl/android/view/ContextThemeWrapper.java b/src/api-impl/android/view/ContextThemeWrapper.java index 63e51a2a..1b7bf503 100644 --- a/src/api-impl/android/view/ContextThemeWrapper.java +++ b/src/api-impl/android/view/ContextThemeWrapper.java @@ -6,22 +6,32 @@ import android.content.res.Resources; public class ContextThemeWrapper extends ContextWrapper { - private Resources.Theme theme = getResources().newTheme(); + private Resources.Theme theme = null; + + public ContextThemeWrapper(Context base) { + super(base); + } public ContextThemeWrapper(Context context, int themeResId) { super(context); - theme.setTo(context.getTheme()); setTheme(themeResId); } @Override public void setTheme(int resid) { + if (theme == null) { + theme = getResources().newTheme(); + theme.setTo(getBaseContext().getTheme()); + } theme.applyStyle(resid, true); } @Override public Resources.Theme getTheme() { - return theme; + if (theme != null) + return theme; + else + return super.getTheme(); } } diff --git a/src/api-impl/android/view/LayoutInflater.java b/src/api-impl/android/view/LayoutInflater.java index d66cf189..3df51988 100644 --- a/src/api-impl/android/view/LayoutInflater.java +++ b/src/api-impl/android/view/LayoutInflater.java @@ -38,6 +38,11 @@ public class LayoutInflater { } private Factory2 mFactory2; + private Context context; + + public LayoutInflater(Context context) { + this.context = context; + } public final LayoutInflater.Factory getFactory() { return null; @@ -48,7 +53,7 @@ public class LayoutInflater { } public static LayoutInflater from(Context context) { - return new LayoutInflater(); + return new LayoutInflater(context); } public final View createView(String name, String prefix, AttributeSet attrs) throws Exception { @@ -59,7 +64,7 @@ public class LayoutInflater { Constructor constructor = view_class.getConstructor(Context.class, AttributeSet.class); - Context context = Context.this_application; + Context context = this.context; final TypedArray ta = context.obtainStyledAttributes(attrs, new int[]{com.android.internal.R.attr.theme}); final int themeResId = ta.getResourceId(0, 0); if (themeResId != 0) { @@ -115,7 +120,7 @@ public class LayoutInflater { public View inflate(int layoutResID, ViewGroup root, boolean attachToRoot) { Slog.v(TAG, "inflating view from id: " + String.format("%x", layoutResID)); - XmlResourceParser xpp = Context.this_application.getResources().getLayout(layoutResID); + XmlResourceParser xpp = context.getResources().getLayout(layoutResID); try { return inflate(xpp, root, attachToRoot); @@ -252,7 +257,7 @@ public class LayoutInflater { int layout = attrs.getAttributeResourceValue(null, "layout", 0); - final XmlResourceParser childParser = Context.this_application.getResources().getLayout(layout); + final XmlResourceParser childParser = context.getResources().getLayout(layout); final AttributeSet childAttrs = Xml.asAttributeSet(childParser); while ((type = childParser.next()) != XmlPullParser.START_TAG && @@ -296,4 +301,8 @@ public class LayoutInflater { public LayoutInflater cloneInContext(Context context) { return this; } + + public Context getContext() { + return context; + } } diff --git a/src/api-impl/android/view/View.java b/src/api-impl/android/view/View.java index 58f33cca..28522577 100644 --- a/src/api-impl/android/view/View.java +++ b/src/api-impl/android/view/View.java @@ -10,6 +10,7 @@ import android.graphics.Canvas; import android.graphics.GskCanvas; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -31,6 +32,8 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +class WindowId {} + public class View implements Drawable.Callback { // --- constants from android source @@ -1757,4 +1760,14 @@ public class View implements Drawable.Callback { } public void setScrollIndicators(int indicators, int mask) {} + + public void setLayoutDirection(int layoutDirection) {} + + public ColorStateList getBackgroundTintList() {return null;} + + public PorterDuff.Mode getBackgroundTintMode() {return null;} + + public String getTransitionName() {return null;} + + public WindowId getWindowId() {return null;} } diff --git a/src/api-impl/android/view/Window.java b/src/api-impl/android/view/Window.java index aa832b76..565b3758 100644 --- a/src/api-impl/android/view/Window.java +++ b/src/api-impl/android/view/Window.java @@ -107,4 +107,8 @@ public class Window { } public void setSoftInputMode(int dummy) {} + + public int getNavigationBarColor() { + return 0xFF888888; // gray + } } diff --git a/src/api-impl/android/widget/ArrayAdapter.java b/src/api-impl/android/widget/ArrayAdapter.java index de979aa2..caaa9681 100644 --- a/src/api-impl/android/widget/ArrayAdapter.java +++ b/src/api-impl/android/widget/ArrayAdapter.java @@ -282,7 +282,7 @@ public class ArrayAdapter extends BaseAdapter /*implements Filterable*/ { } private void init(Context context, int resource, int textViewResourceId, List objects) { mContext = context; - mInflater = new LayoutInflater(); + mInflater = new LayoutInflater(context); mResource = mDropDownResource = resource; mObjects = objects; mFieldId = textViewResourceId; diff --git a/src/api-impl/android/widget/ImageView.java b/src/api-impl/android/widget/ImageView.java index 1ee5bc25..f1a1f7dc 100644 --- a/src/api-impl/android/widget/ImageView.java +++ b/src/api-impl/android/widget/ImageView.java @@ -5,7 +5,6 @@ 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; @@ -17,6 +16,7 @@ public class ImageView extends View { private Bitmap bitmap = null; private ScaleType scaleType = ScaleType.FIT_CENTER; + private Drawable drawable = null; public ImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); @@ -56,20 +56,11 @@ public class ImageView extends View { } public Drawable getDrawable() { - 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); + return drawable; } public void setImageDrawable(Drawable drawable) { + this.drawable = drawable; if (drawable instanceof BitmapDrawable) { setImageBitmap(((BitmapDrawable) drawable).getBitmap()); } else if (drawable != null && drawable.paintable != 0) { diff --git a/src/api-impl/android/widget/TextView.java b/src/api-impl/android/widget/TextView.java index a6017fbb..652a0638 100644 --- a/src/api-impl/android/widget/TextView.java +++ b/src/api-impl/android/widget/TextView.java @@ -8,9 +8,11 @@ import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.InputFilter; import android.text.Layout; +import android.text.SpannableStringBuilder; import android.text.TextPaint; import android.text.TextUtils; import android.text.TextWatcher; +import android.text.method.BaseMovementMethod; import android.text.method.KeyListener; import android.text.method.MovementMethod; import android.text.method.TransformationMethod; @@ -210,7 +212,7 @@ public class TextView extends View { } public MovementMethod getMovementMethod() { - return new MovementMethod(); + return new BaseMovementMethod(); } public CharSequence getHint() {return "HINT";} @@ -268,4 +270,12 @@ public class TextView extends View { public int length() { return getText().length(); } + + public void setHighlightColor(int color) {} + + public Editable getEditableText() { + return new SpannableStringBuilder(getText()); + } + + public int getMaxWidth() {return 1000;} } diff --git a/src/api-impl/meson.build b/src/api-impl/meson.build index 3e644c0b..30f73b90 100644 --- a/src/api-impl/meson.build +++ b/src/api-impl/meson.build @@ -51,7 +51,9 @@ hax_jar = jar('hax', [ 'android/app/job/JobService.java', 'android/app/usage/UsageStatsManager.java', 'android/appwidget/AppWidgetManager.java', + 'android/bluetooth/BluetoothAdapter.java', 'android/bluetooth/BluetoothManager.java', + 'android/bluetooth/BluetoothProfile.java', 'android/bluetooth/le/ScanCallback.java', 'android/content/ActivityNotFoundException.java', 'android/content/BroadcastReceiver.java', @@ -205,6 +207,7 @@ hax_jar = jar('hax', [ 'android/graphics/drawable/StateListDrawable.java', 'android/graphics/drawable/VectorDrawable.java', 'android/graphics/drawable/shapes/OvalShape.java', + 'android/graphics/drawable/shapes/RoundRectShape.java', 'android/graphics/drawable/shapes/Shape.java', 'android/hardware/ConsumerIrManager.java', 'android/hardware/Sensor.java', @@ -241,8 +244,10 @@ hax_jar = jar('hax', [ 'android/net/ConnectivityManager.java', 'android/net/NetworkInfo.java', 'android/net/NetworkRequest.java', + 'android/net/SSLSessionCache.java', 'android/net/TrafficStats.java', 'android/net/Uri.java', + 'android/net/UrlQuerySanitizer.java', 'android/net/http/X509TrustManagerExtensions.java', 'android/net/nsd/NsdManager.java', 'android/net/wifi/WifiInfo.java', @@ -264,6 +269,7 @@ hax_jar = jar('hax', [ 'android/os/CancellationSignal.java', 'android/os/ConditionVariable.java', 'android/os/CountDownTimer.java', + 'android/os/DeadObjectException.java', 'android/os/Debug.java', 'android/os/DropBoxManager.java', 'android/os/Environment.java', @@ -299,6 +305,7 @@ hax_jar = jar('hax', [ 'android/preference/PreferenceManager.java', 'android/print/PrintManager.java', 'android/provider/BaseColumns.java', + 'android/provider/ContactsContract.java', 'android/provider/Settings.java', 'android/telecom/TelecomManager.java', 'android/telephony/CellLocation.java', @@ -328,6 +335,7 @@ hax_jar = jar('hax', [ 'android/text/TextWatcher.java', 'android/text/format/DateFormat.java', 'android/text/format/Formatter.java', + 'android/text/method/BaseMovementMethod.java', 'android/text/method/KeyListener.java', 'android/text/method/LinkMovementMethod.java', 'android/text/method/MovementMethod.java', @@ -339,6 +347,7 @@ hax_jar = jar('hax', [ 'android/text/style/ForegroundColorSpan.java', 'android/text/style/MetricAffectingSpan.java', 'android/text/style/StyleSpan.java', + 'android/text/style/UpdateAppearance.java', 'android/text/style/URLSpan.java', 'android/text/util/Linkify.java', 'android/util/AndroidException.java', diff --git a/src/main-executable/main.c b/src/main-executable/main.c index 2f1f0a6f..56595d7c 100644 --- a/src/main-executable/main.c +++ b/src/main-executable/main.c @@ -397,6 +397,8 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h if(getenv("ATL_FORCE_FULLSCREEN")) gtk_window_fullscreen(GTK_WINDOW(window)); + prepare_main_looper(env); + // construct Application application_object = (*env)->CallStaticObjectMethod(env, handle_cache.context.class, _STATIC_METHOD(handle_cache.context.class, "createApplication", "(J)Landroid/app/Application;"), window); @@ -407,8 +409,6 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h if(!getenv("ATL_SKIP_NATIVES_EXTRACTION")) extract_from_apk("lib/" NATIVE_ARCH "/", "lib/"); - prepare_main_looper(env); - jclass content_provider = (*env)->FindClass(env, "android/content/ContentProvider"); (*env)->CallStaticVoidMethod(env, content_provider, _STATIC_METHOD(content_provider, "createContentProviders", "()V")); if((*env)->ExceptionCheck(env))