Merge branch 'Mis012/mr' into 'master'

misc additions

See merge request android_translation_layer/android_translation_layer!151
This commit is contained in:
Mis012 2025-03-27 12:08:17 +00:00
commit 536aa8e7ed
58 changed files with 2866 additions and 162 deletions

View file

@ -3,30 +3,34 @@
#include "../defines.h"
#include "../generated_headers/android_media_SoundPool.h"
JNIEXPORT jlong JNICALL Java_android_media_SoundPool_native_1constructor(JNIEnv *env, jclass) {
GArray *sound_pool_array = g_array_new(FALSE, FALSE, sizeof(GtkMediaStream *));
return _INTPTR(sound_pool_array);
JNIEXPORT jlong JNICALL Java_android_media_SoundPool_native_1constructor(JNIEnv *env, jclass)
{
GArray *sound_pool_array = g_array_new(FALSE, FALSE, sizeof(GtkMediaStream *));
return _INTPTR(sound_pool_array);
}
static void on_prepared(GtkMediaStream *media_stream) {
// play once muted to ensure file is fully loaded
gtk_media_stream_set_muted(media_stream, TRUE);
static void on_prepared(GtkMediaStream *media_stream)
{
// play once muted to ensure file is fully loaded
gtk_media_stream_set_muted(media_stream, TRUE);
gtk_media_stream_play(media_stream);
}
JNIEXPORT jint JNICALL Java_android_media_SoundPool_nativeLoad(JNIEnv *env, jclass, jlong pool, jstring path) {
GArray *sound_pool_array = _PTR(pool);
JNIEXPORT jint JNICALL Java_android_media_SoundPool_nativeLoad(JNIEnv *env, jclass, jlong pool, jstring path)
{
GArray *sound_pool_array = _PTR(pool);
const char* nativePath = (*env)->GetStringUTFChars(env, path, NULL);
GtkMediaStream *media_stream = gtk_media_file_new_for_filename(nativePath);
g_signal_connect(media_stream, "notify::prepared", G_CALLBACK(on_prepared), NULL);
g_signal_connect(media_stream, "notify::prepared", G_CALLBACK(on_prepared), NULL);
(*env)->ReleaseStringUTFChars(env, path, nativePath);
return g_array_append_val(sound_pool_array, media_stream)->len - 1;
}
JNIEXPORT jint JNICALL Java_android_media_SoundPool_nativePlay(JNIEnv *env, jclass, jlong pool, jint soundID) {
JNIEXPORT jint JNICALL Java_android_media_SoundPool_nativePlay(JNIEnv *env, jclass, jlong pool, jint soundID)
{
GArray *sound_pool_array = _PTR(pool);
GtkMediaStream *media_stream = g_array_index(sound_pool_array, GtkMediaStream *, soundID);
gtk_media_stream_set_muted(media_stream, FALSE);
GtkMediaStream *media_stream = g_array_index(sound_pool_array, GtkMediaStream *, soundID);
gtk_media_stream_set_muted(media_stream, FALSE);
gtk_media_stream_play(media_stream);
return 0;
}

View file

@ -114,6 +114,12 @@ JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeData(
return ResXMLParser_getAttributeData(parser, index);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeName(JNIEnv *env, jclass this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeNameID(parser, index);
}
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroyParseState(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);

View file

@ -217,7 +217,7 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadResourceBagValu
* Signature: (JJII[IIJJ)V
*/
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_applyStyle
(JNIEnv *, jclass, jlong, jlong, jint, jint, jintArray, jint, jlong, jlong);
(JNIEnv *, jobject, jlong, jlong, jint, jint, jintArray, jint, jlong, jlong);
/*
* Class: android_content_res_AssetManager
@ -225,7 +225,7 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_applyStyle
* Signature: (JII[I[I[I[I)Z
*/
JNIEXPORT jboolean JNICALL Java_android_content_res_AssetManager_resolveAttrs
(JNIEnv *, jclass, jlong, jint, jint, jintArray, jintArray, jintArray, jintArray);
(JNIEnv *, jobject, jlong, jint, jint, jintArray, jintArray, jintArray, jintArray);
/*
* Class: android_content_res_AssetManager
@ -321,7 +321,7 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_deleteTheme
* Signature: (JIZ)V
*/
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_applyThemeStyle
(JNIEnv *, jclass, jlong, jint, jboolean);
(JNIEnv *, jobject, jlong, jint, jboolean);
/*
* Class: android_content_res_AssetManager
@ -329,7 +329,7 @@ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_applyThemeStyle
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_copyTheme
(JNIEnv *, jclass, jlong, jlong);
(JNIEnv *, jobject, jlong, jlong);
/*
* Class: android_content_res_AssetManager

View file

@ -453,14 +453,6 @@ JNIEXPORT void JNICALL Java_android_view_MotionEvent_nativeGetPointerProperties
JNIEXPORT void JNICALL Java_android_view_MotionEvent_nativeScale
(JNIEnv *, jclass, jint, jfloat);
/*
* Class: android_view_MotionEvent
* Method: nativeTransform
* Signature: (ILandroid/graphics/Matrix;)V
*/
JNIEXPORT void JNICALL Java_android_view_MotionEvent_nativeTransform
(JNIEnv *, jclass, jint, jobject);
#ifdef __cplusplus
}
#endif

View file

@ -231,6 +231,14 @@ JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChildren
JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChild
(JNIEnv *, jobject, jlong, jlong, jlong);
/*
* Class: android_view_ViewGroup
* Method: native_dispatchTouchEvent
* Signature: (JLandroid/view/MotionEvent;DD)Z
*/
JNIEXPORT jboolean JNICALL Java_android_view_ViewGroup_native_1dispatchTouchEvent
(JNIEnv *, jobject, jlong, jobject, jdouble, jdouble);
#ifdef __cplusplus
}
#endif

View file

@ -39,6 +39,22 @@ JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1showAsDropDown
JNIEXPORT jboolean JNICALL Java_android_widget_PopupWindow_native_1isShowing
(JNIEnv *, jobject, jlong);
/*
* Class: android_widget_PopupWindow
* Method: native_setTouchable
* Signature: (JZ)V
*/
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setTouchable
(JNIEnv *, jobject, jlong, jboolean);
/*
* Class: android_widget_PopupWindow
* Method: native_setTouchModal
* Signature: (JZ)V
*/
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setTouchModal
(JNIEnv *, jobject, jlong, jboolean);
/*
* Class: android_widget_PopupWindow
* Method: native_dismiss
@ -65,19 +81,43 @@ JNIEXPORT void JNICALL Java_android_widget_PopupWindow_setOnDismissListener
/*
* Class: android_widget_PopupWindow
* Method: setWidth
* Signature: (I)V
* Method: native_setWidth
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_setWidth
(JNIEnv *, jobject, jint);
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setWidth
(JNIEnv *, jobject, jlong, jint);
/*
* Class: android_widget_PopupWindow
* Method: setHeight
* Signature: (I)V
* Method: native_setHeight
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_setHeight
(JNIEnv *, jobject, jint);
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setHeight
(JNIEnv *, jobject, jlong, jint);
/*
* Class: android_widget_PopupWindow
* Method: native_getWidth
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_widget_PopupWindow_native_1getWidth
(JNIEnv *, jobject, jlong);
/*
* Class: android_widget_PopupWindow
* Method: native_getHeight
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_widget_PopupWindow_native_1getHeight
(JNIEnv *, jobject, jlong);
/*
* Class: android_widget_PopupWindow
* Method: native_isTouchable
* Signature: (J)Z
*/
JNIEXPORT jboolean JNICALL Java_android_widget_PopupWindow_native_1isTouchable
(JNIEnv *, jobject, jlong);
#ifdef __cplusplus
}

View file

@ -14,12 +14,13 @@ static void location_updated (
gchar* description,
gint64 timestamp_s,
gint64 timestamp_ms,
JavaVM *jvm
) {
JavaVM *jvm)
{
JNIEnv *env;
(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6);
jclass class = (*env)->FindClass(env, "android/location/LocationManager");
(*env)->CallStaticVoidMethod(env, class, _STATIC_METHOD(class, "locationUpdated", "(DDD)V"), latitude, longitude, heading);
jlong timestamp = timestamp_s * 1000 + timestamp_ms;
(*env)->CallStaticVoidMethod(env, class, _STATIC_METHOD(class, "locationUpdated", "(DDDDDDJ)V"), latitude, longitude, altitude, accuracy, speed, heading, timestamp);
}
JNIEXPORT void JNICALL Java_android_location_LocationManager_nativeGetLocation(JNIEnv *env, jobject) {

View file

@ -132,6 +132,7 @@ void set_up_handle_cache(JNIEnv *env)
handle_cache.view.getScrollY = _METHOD(handle_cache.view.class, "getScrollY", "()I");
handle_cache.view.performClick = _METHOD(handle_cache.view.class, "performClick", "()Z");
handle_cache.view.onTouchEvent = _METHOD(handle_cache.view.class, "onTouchEvent", "(Landroid/view/MotionEvent;)Z");
handle_cache.view.onTouchEventInternal = _METHOD(handle_cache.view.class, "onTouchEventInternal", "(Landroid/view/MotionEvent;)Z");
handle_cache.view.dispatchTouchEvent = _METHOD(handle_cache.view.class, "dispatchTouchEvent", "(Landroid/view/MotionEvent;)Z");
handle_cache.view.onInterceptTouchEvent = _METHOD(handle_cache.view.class, "onInterceptTouchEvent", "(Landroid/view/MotionEvent;)Z");
handle_cache.view.layoutInternal = _METHOD(handle_cache.view.class, "layoutInternal", "(II)V");
@ -143,6 +144,9 @@ void set_up_handle_cache(JNIEnv *env)
handle_cache.view.dispatchKeyEvent = _METHOD(handle_cache.view.class, "dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z");
handle_cache.view.onKeyDown = _METHOD(handle_cache.view.class, "onKeyDown", "(ILandroid/view/KeyEvent;)Z");
handle_cache.view_group.class = _REF((*env)->FindClass(env, "android/view/ViewGroup"));
handle_cache.view_group.dispatchTouchEvent = _METHOD(handle_cache.view_group.class, "dispatchTouchEvent", "(Landroid/view/MotionEvent;)Z");
handle_cache.asset_manager.class = _REF((*env)->FindClass(env, "android/content/res/AssetManager"));
handle_cache.asset_manager.extractFromAPK = _STATIC_METHOD(handle_cache.asset_manager.class, "extractFromAPK", "(Ljava/lang/String;Ljava/lang/String;)V");

View file

@ -77,6 +77,7 @@ struct handle_cache {
jmethodID getScrollY;
jmethodID performClick;
jmethodID onTouchEvent;
jmethodID onTouchEventInternal;
jmethodID dispatchTouchEvent;
jmethodID onInterceptTouchEvent;
jmethodID layoutInternal;
@ -88,6 +89,10 @@ struct handle_cache {
jmethodID dispatchKeyEvent;
jmethodID onKeyDown;
} view;
struct {
jclass class;
jmethodID dispatchTouchEvent;
} view_group;
struct {
jclass class;
jmethodID extractFromAPK;

View file

@ -46,11 +46,40 @@ static WrapperWidget *cancel_triggerer = NULL;
static struct pointer pointers[MAX_POINTERS] = {};
bool view_dispatch_motionevent(JNIEnv *env, WrapperWidget *wrapper, GtkPropagationPhase phase, jobject motion_event, GdkEvent *event) {
int ret;
jobject this = wrapper->jobj;
if (wrapper->custom_dispatch_touch) {
ret = (*env)->CallBooleanMethod(env, this, handle_cache.view.dispatchTouchEvent, motion_event);
} else if (phase == GTK_PHASE_CAPTURE && !wrapper->intercepting_touch) {
wrapper->intercepting_touch = (*env)->CallBooleanMethod(env, this, handle_cache.view.onInterceptTouchEvent, motion_event);
if (wrapper->intercepting_touch) {
if(event) {
// store the event that was canceled and let it propagate to the child widgets
canceled_event = event;
cancel_triggerer = wrapper;
} else {
/* this function is also called to synthesize an event, in which case there is no GdkEvent so not sure what to do */
fprintf(stderr, "view_dispatch_motionevent: onInterceptTouchEvent returned true but this is a synthesized event, please investigate\n");
}
}
ret = false;
} else {
ret = (*env)->CallBooleanMethod(env, this, handle_cache.view.onTouchEventInternal, motion_event);
}
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
return ret;
}
static bool call_ontouch_callback(WrapperWidget *wrapper, int action, struct pointer pointers[MAX_POINTERS], GPtrArray *pointer_indices, GtkPropagationPhase phase, guint32 timestamp, GdkEvent *event)
{
bool ret;
JNIEnv *env = get_jni_env();
jobject this = wrapper->jobj;
int num_pointers = pointer_indices->len;
jintArray ids = (*env)->NewIntArray(env, num_pointers);
@ -62,24 +91,9 @@ static bool call_ontouch_callback(WrapperWidget *wrapper, int action, struct poi
(*env)->SetFloatArrayRegion(env, coords, 4 * i, 4, &pointer->coord_x);
}
jobject motion_event = (*env)->NewObject(env, handle_cache.motion_event.class, handle_cache.motion_event.constructor, SOURCE_TOUCHSCREEN, action, (long)timestamp, ids, coords);
jobject motion_event = (*env)->NewObject(env, handle_cache.motion_event.class, handle_cache.motion_event.constructor, SOURCE_TOUCHSCREEN, action, timestamp, ids, coords);
if (wrapper->custom_dispatch_touch) {
ret = (*env)->CallBooleanMethod(env, this, handle_cache.view.dispatchTouchEvent, motion_event);
} else if (phase == GTK_PHASE_CAPTURE && !wrapper->intercepting_touch) {
wrapper->intercepting_touch = (*env)->CallBooleanMethod(env, this, handle_cache.view.onInterceptTouchEvent, motion_event);
if (wrapper->intercepting_touch) {
// store the event that was canceled and let it propagate to the child widgets
canceled_event = event;
cancel_triggerer = wrapper;
}
ret = false;
} else {
ret = (*env)->CallBooleanMethod(env, this, handle_cache.view.onTouchEvent, motion_event);
}
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
ret = view_dispatch_motionevent(env, wrapper, phase, motion_event, event);
(*env)->DeleteLocalRef(env, motion_event);

View file

@ -63,3 +63,103 @@ JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChild(JNIEnv *env
gtk_widget_queue_draw(child); // FIXME: why didn't compose UI invalidate the child?
gtk_widget_snapshot_child(widget, child, snapshot);
}
/* FIXME: put this in a header */
G_DECLARE_FINAL_TYPE(JavaWidget, java_widget, JAVA, WIDGET, GtkWidget)
bool view_dispatch_motionevent(JNIEnv *env, WrapperWidget *wrapper, GtkPropagationPhase phase, jobject motion_event, GdkEvent *event);
static bool dispatch_motionevent_if_JavaWidget(GtkWidget *widget, GtkPropagationPhase phase, jobject motion_event)
{
if(!JAVA_IS_WIDGET(widget))
return false;
return view_dispatch_motionevent(get_jni_env(), WRAPPER_WIDGET(gtk_widget_get_parent(widget)), phase, motion_event, NULL);
}
/* used by atl_propagate_synthetic_motionevent */
#define GDK_ARRAY_ELEMENT_TYPE GtkWidget *
#define GDK_ARRAY_TYPE_NAME GtkWidgetStack
#define GDK_ARRAY_NAME gtk_widget_stack
#define GDK_ARRAY_FREE_FUNC g_object_unref
#define GDK_ARRAY_PREALLOC 16
#include "gdkarrayimpl.c"
/* based on gtk_propagate_event_internal © GTK Team */
bool atl_propagate_synthetic_motionevent(GtkWidget *widget, jobject motionevent, GtkWidget *toplevel)
{
int handled_event = false;
GtkWidgetStack widget_array;
int i;
/* First, propagate event down */
gtk_widget_stack_init(&widget_array);
gtk_widget_stack_append(&widget_array, g_object_ref(widget));
for (;;) {
widget = gtk_widget_get_parent(widget);
if (!widget)
break;
if (widget == toplevel)
break;
gtk_widget_stack_append(&widget_array, g_object_ref(widget));
}
i = gtk_widget_stack_get_size(&widget_array) - 1;
for (;;) {
widget = gtk_widget_stack_get(&widget_array, i);
if (!gtk_widget_is_sensitive(widget)) {
handled_event = true;
} else if (gtk_widget_get_realized(widget))
handled_event = dispatch_motionevent_if_JavaWidget(widget, GTK_PHASE_CAPTURE, motionevent);
handled_event |= !gtk_widget_get_realized(widget);
if (handled_event)
break;
if (i == 0)
break;
i--;
}
/* If not yet handled, also propagate back up */
if (!handled_event) {
/* Propagate event up the widget tree so that
* parents can see the button and motion
* events of the children.
*/
for (i = 0; i < gtk_widget_stack_get_size(&widget_array); i++) {
widget = gtk_widget_stack_get(&widget_array, i);
/* Scroll events are special cased here because it
* feels wrong when scrolling a GtkViewport, say,
* to have children of the viewport eat the scroll
* event
*/
if (!gtk_widget_is_sensitive(widget))
handled_event = true;
else if (gtk_widget_get_realized(widget))
handled_event = dispatch_motionevent_if_JavaWidget(widget, GTK_PHASE_BUBBLE, motionevent);
handled_event |= !gtk_widget_get_realized(widget);
if (handled_event)
break;
}
}
gtk_widget_stack_clear(&widget_array);
return handled_event;
}
JNIEXPORT jboolean JNICALL Java_android_view_ViewGroup_native_1dispatchTouchEvent(JNIEnv *env, jobject this, jlong widget_ptr, jobject motion_event, jdouble x, jdouble y)
{
GtkWidget *widget = GTK_WIDGET(_PTR(widget_ptr));
GtkWidget *picked_child = gtk_widget_pick(widget, x, y, GTK_PICK_DEFAULT);
return atl_propagate_synthetic_motionevent(picked_child, motion_event, widget);
}

View file

@ -0,0 +1,326 @@
/* lifted from Gtk for gtk_propagate_event_internal derived function */
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include <glib.h>
G_BEGIN_DECLS
#ifndef GDK_ARRAY_TYPE_NAME
#define GDK_ARRAY_TYPE_NAME GdkArray
#endif
#ifndef GDK_ARRAY_NAME
#define GDK_ARRAY_NAME gdk_array
#endif
#ifndef GDK_ARRAY_ELEMENT_TYPE
#define GDK_ARRAY_ELEMENT_TYPE gpointer
#endif
#ifdef GDK_ARRAY_PREALLOC
#if GDK_ARRAY_PREALLOC == 0
#undef GDK_ARRAY_PREALLOC
#endif
#endif
#ifdef GDK_ARRAY_NULL_TERMINATED
#define GDK_ARRAY_REAL_SIZE(_size) ((_size) + 1)
#define GDK_ARRAY_MAX_SIZE (G_MAXSIZE / sizeof(_T_) - 1)
#else
#define GDK_ARRAY_REAL_SIZE(_size) (_size)
#define GDK_ARRAY_MAX_SIZE (G_MAXSIZE / sizeof(_T_))
#endif
/* make this readable */
#define _T_ GDK_ARRAY_ELEMENT_TYPE
#define GdkArray GDK_ARRAY_TYPE_NAME
#define gdk_array_paste_more(GDK_ARRAY_NAME, func_name) GDK_ARRAY_NAME##_##func_name
#define gdk_array_paste(GDK_ARRAY_NAME, func_name) gdk_array_paste_more(GDK_ARRAY_NAME, func_name)
#define gdk_array(func_name) gdk_array_paste(GDK_ARRAY_NAME, func_name)
typedef struct GdkArray GdkArray;
struct GdkArray {
_T_ *start;
_T_ *end;
_T_ *end_allocation;
#ifdef GDK_ARRAY_PREALLOC
_T_ preallocated[GDK_ARRAY_REAL_SIZE(GDK_ARRAY_PREALLOC)];
#endif
};
/* no G_GNUC_UNUSED here, if you don't use an array type, remove it. */
static inline void
gdk_array(init)(GdkArray *self)
{
#ifdef GDK_ARRAY_PREALLOC
self->start = self->preallocated;
self->end = self->start;
self->end_allocation = self->start + GDK_ARRAY_PREALLOC;
#ifdef GDK_ARRAY_NULL_TERMINATED
*self->start = *(_T_[1]){0};
#endif
#else
self->start = NULL;
self->end = NULL;
self->end_allocation = NULL;
#endif
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_capacity)(const GdkArray *self)
{
return self->end_allocation - self->start;
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_size)(const GdkArray *self)
{
return self->end - self->start;
}
static inline void
gdk_array(free_elements)(_T_ *start,
_T_ *end)
{
#ifdef GDK_ARRAY_FREE_FUNC
_T_ *e;
for (e = start; e < end; e++)
#ifdef GDK_ARRAY_BY_VALUE
GDK_ARRAY_FREE_FUNC(e);
#else
GDK_ARRAY_FREE_FUNC(*e);
#endif
#endif
}
/* no G_GNUC_UNUSED here */
static inline void
gdk_array(clear)(GdkArray *self)
{
gdk_array(free_elements)(self->start, self->end);
#ifdef GDK_ARRAY_PREALLOC
if (self->start != self->preallocated)
#endif
g_free(self->start);
gdk_array(init)(self);
}
/*
* gdk_array_steal:
* @self: the array
*
* Steals all data in the array and clears the array.
*
* If you need to know the size of the data, you should query it
* beforehand.
*
* Returns: The array's data
**/
G_GNUC_UNUSED static inline _T_ *
gdk_array(steal)(GdkArray *self)
{
_T_ *result;
#ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated) {
gsize size = GDK_ARRAY_REAL_SIZE(gdk_array(get_size)(self));
result = g_new(_T_, size);
memcpy(result, self->preallocated, sizeof(_T_) * size);
} else
#endif
result = self->start;
gdk_array(init)(self);
return result;
}
G_GNUC_UNUSED static inline _T_ *
gdk_array(get_data)(const GdkArray *self)
{
return self->start;
}
G_GNUC_UNUSED static inline _T_ *
gdk_array(index)(const GdkArray *self,
gsize pos)
{
return self->start + pos;
}
G_GNUC_UNUSED static inline gboolean
gdk_array(is_empty)(const GdkArray *self)
{
return self->end == self->start;
}
G_GNUC_UNUSED static inline void
gdk_array(reserve)(GdkArray *self,
gsize n)
{
gsize new_capacity, size, capacity;
if (G_UNLIKELY(n > GDK_ARRAY_MAX_SIZE))
g_error("requesting array size of %zu, but maximum size is %zu", n, GDK_ARRAY_MAX_SIZE);
capacity = gdk_array(get_capacity)(self);
if (n <= capacity)
return;
size = gdk_array(get_size)(self);
/* capacity * 2 can overflow, that's why we MAX() */
new_capacity = MAX(GDK_ARRAY_REAL_SIZE(n), capacity * 2);
#ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated) {
self->start = g_new(_T_, new_capacity);
memcpy(self->start, self->preallocated, sizeof(_T_) * GDK_ARRAY_REAL_SIZE(size));
} else
#endif
#ifdef GDK_ARRAY_NULL_TERMINATED
if (self->start == NULL) {
self->start = g_new(_T_, new_capacity);
*self->start = *(_T_[1]){0};
} else
#endif
self->start = g_renew(_T_, self->start, new_capacity);
self->end = self->start + size;
self->end_allocation = self->start + new_capacity;
#ifdef GDK_ARRAY_NULL_TERMINATED
self->end_allocation--;
#endif
}
G_GNUC_UNUSED static inline void
gdk_array(splice)(GdkArray *self,
gsize pos,
gsize removed,
gboolean stolen,
#ifdef GDK_ARRAY_BY_VALUE
const _T_ *additions,
#else
_T_ *additions,
#endif
gsize added)
{
gsize size;
gsize remaining;
size = gdk_array(get_size)(self);
g_assert(pos + removed <= size);
remaining = size - pos - removed;
if (!stolen)
gdk_array(free_elements)(gdk_array(index)(self, pos),
gdk_array(index)(self, pos + removed));
gdk_array(reserve)(self, size - removed + added);
if (GDK_ARRAY_REAL_SIZE(remaining) && removed != added)
memmove(gdk_array(index)(self, pos + added),
gdk_array(index)(self, pos + removed),
GDK_ARRAY_REAL_SIZE(remaining) * sizeof(_T_));
if (added) {
if (additions)
memcpy(gdk_array(index)(self, pos),
additions,
added * sizeof(_T_));
#ifndef GDK_ARRAY_NO_MEMSET
else
memset(gdk_array(index)(self, pos), 0, added * sizeof(_T_));
#endif
}
/* might overflow, but does the right thing */
self->end += added - removed;
}
G_GNUC_UNUSED static void
gdk_array(set_size)(GdkArray *self,
gsize new_size)
{
gsize old_size = gdk_array(get_size)(self);
if (new_size > old_size)
gdk_array(splice)(self, old_size, 0, FALSE, NULL, new_size - old_size);
else
gdk_array(splice)(self, new_size, old_size - new_size, FALSE, NULL, 0);
}
G_GNUC_UNUSED static void
gdk_array(append)(GdkArray *self,
#ifdef GDK_ARRAY_BY_VALUE
_T_ *value)
#else
_T_ value)
#endif
{
gdk_array(splice)(self,
gdk_array(get_size)(self),
0,
FALSE,
#ifdef GDK_ARRAY_BY_VALUE
value,
#else
&value,
#endif
1);
}
#ifdef GDK_ARRAY_BY_VALUE
G_GNUC_UNUSED static _T_ *
gdk_array(get)(const GdkArray *self,
gsize pos)
{
return gdk_array(index)(self, pos);
}
#else
G_GNUC_UNUSED static _T_
gdk_array(get)(const GdkArray *self,
gsize pos)
{
return *gdk_array(index)(self, pos);
}
#endif
#ifndef GDK_ARRAY_NO_UNDEF
#undef _T_
#undef GdkArray
#undef gdk_array_paste_more
#undef gdk_array_paste
#undef gdk_array
#undef GDK_ARRAY_REAL_SIZE
#undef GDK_ARRAY_MAX_SIZE
#undef GDK_ARRAY_BY_VALUE
#undef GDK_ARRAY_ELEMENT_TYPE
#undef GDK_ARRAY_FREE_FUNC
#undef GDK_ARRAY_NAME
#undef GDK_ARRAY_NULL_TERMINATED
#undef GDK_ARRAY_PREALLOC
#undef GDK_ARRAY_TYPE_NAME
#undef GDK_ARRAY_NO_MEMSET
#endif
G_END_DECLS

View file

@ -23,7 +23,7 @@ static void wrapper_widget_set_property (GObject *object, guint property_id, con
}
}
static void wrapper_widget_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
static void wrapper_widget_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
WrapperWidget *self = WRAPPER_WIDGET(object);
@ -91,7 +91,7 @@ static void wrapper_widget_get_property (GObject *object, guint property_id, GVa
}
}
static void wrapper_widget_init (WrapperWidget *wrapper_widget)
static void wrapper_widget_init(WrapperWidget *wrapper_widget)
{
}
@ -386,7 +386,7 @@ void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject job
jmethodID ontouchevent_method = _METHOD(_CLASS(jobj), "onTouchEvent", "(Landroid/view/MotionEvent;)Z");
jmethodID dispatchtouchevent_method = _METHOD(_CLASS(jobj), "dispatchTouchEvent", "(Landroid/view/MotionEvent;)Z");
wrapper->custom_dispatch_touch = dispatchtouchevent_method != handle_cache.view.dispatchTouchEvent;
wrapper->custom_dispatch_touch = (dispatchtouchevent_method != handle_cache.view.dispatchTouchEvent && dispatchtouchevent_method != handle_cache.view_group.dispatchTouchEvent);
if (ontouchevent_method != handle_cache.view.onTouchEvent || wrapper->custom_dispatch_touch) {
_setOnTouchListener(env, jobj, GTK_WIDGET(wrapper));
}

View file

@ -11,6 +11,8 @@ JNIEXPORT jlong JNICALL Java_android_widget_PopupWindow_native_1constructor(JNIE
{
GtkWidget *popover = gtk_popover_new();
gtk_widget_set_name(popover, "PopupWindow");
/* autohiding works by the widget grabbing events, which is not something apps expect */
gtk_popover_set_autohide(GTK_POPOVER(popover), false);
return _INTPTR(popover);
}
@ -20,32 +22,76 @@ JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setContentView(JN
gtk_popover_set_child(GTK_POPOVER(_PTR(popover_ptr)), GTK_WIDGET(content));
}
static inline void set_offset(GtkPopover *popover, GtkWidget *anchor, int x, int y)
{
/* FIXME: assumes GTK_POS_BOTTOM */
gtk_popover_set_offset(popover, x - gtk_widget_get_width(anchor) / 2, y - gtk_widget_get_height(anchor));
}
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1showAsDropDown(JNIEnv *env, jobject this, jlong popover_ptr, jlong anchor_ptr, jint x, jint y, jint gravity)
{
GtkPopover *popover = GTK_POPOVER(_PTR(popover_ptr));
WrapperWidget *anchor = WRAPPER_WIDGET(gtk_widget_get_parent(GTK_WIDGET(_PTR(anchor_ptr))));
gtk_widget_insert_before(GTK_WIDGET(popover), GTK_WIDGET(anchor), NULL);
set_offset(popover, GTK_WIDGET(anchor), x, y);
gtk_popover_present(GTK_POPOVER(popover));
gtk_popover_popup(popover);
}
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_setWidth(JNIEnv *env, jobject this, jint width)
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setWidth(JNIEnv *env, jobject this, jlong popover_ptr, jint width)
{
int height;
GtkWidget *popover = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "popover")));
GtkWidget *popover = GTK_WIDGET(_PTR(popover_ptr));
gtk_widget_get_size_request(popover, NULL, &height);
gtk_widget_set_size_request(popover, width, height);
}
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_setHeight(JNIEnv *env, jobject this, jint height)
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setHeight(JNIEnv *env, jobject this, jlong popover_ptr, jint height)
{
int width;
GtkWidget *popover = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "popover")));
GtkWidget *popover = GTK_WIDGET(_PTR(popover_ptr));
gtk_widget_get_size_request(popover, &width, NULL);
gtk_widget_set_size_request(popover, width, height);
}
JNIEXPORT jint JNICALL Java_android_widget_PopupWindow_native_1getWidth(JNIEnv *env, jobject this, jlong popover_ptr)
{
GtkWidget *popover = GTK_WIDGET(_PTR(popover_ptr));
GtkRequisition natural_size;
gtk_widget_get_preferred_size(popover, &natural_size, NULL);
return natural_size.width;
}
JNIEXPORT jint JNICALL Java_android_widget_PopupWindow_native_1getHeight(JNIEnv *env, jobject this, jlong popover_ptr)
{
GtkWidget *popover = GTK_WIDGET(_PTR(popover_ptr));
GtkRequisition natural_size;
gtk_widget_get_preferred_size(popover, &natural_size, NULL);
return natural_size.height;
}
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setTouchable(JNIEnv *env, jobject this, jlong popover_ptr, jboolean touchable)
{
GtkWidget *popover = GTK_WIDGET(_PTR(popover_ptr));
gtk_widget_set_sensitive(popover, touchable);
}
JNIEXPORT jboolean JNICALL Java_android_widget_PopupWindow_native_1isTouchable(JNIEnv *env, jobject this, jlong popover_ptr)
{
GtkWidget *popover = GTK_WIDGET(_PTR(popover_ptr));
return gtk_widget_is_sensitive(popover);
}
JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1setTouchModal(JNIEnv *env, jobject this, jlong popover_ptr, jboolean touch_modal)
{
GtkPopover *popover = GTK_POPOVER(_PTR(popover_ptr));
/* FIXME: we should only add grab (not autohide), however we need to remove it again in umap;
* GtkPopover is not final, so we should subclass it and check whether it's modal in map/unmap
* to add/remove grab, which is the desired part of what GtkPopover does with autohide enabled */
gtk_popover_set_autohide(popover, touch_modal);
}
static void on_closed_cb(GtkPopover *popover, jobject listener)
{
JNIEnv *env = get_jni_env();
@ -74,6 +120,7 @@ JNIEXPORT void JNICALL Java_android_widget_PopupWindow_native_1update(JNIEnv *en
GtkPopover *popover = GTK_POPOVER(_PTR(popover_ptr));
WrapperWidget *anchor = WRAPPER_WIDGET(gtk_widget_get_parent(GTK_WIDGET(_PTR(anchor_ptr))));
gtk_widget_set_size_request(GTK_WIDGET(popover), width, height);
set_offset(popover, GTK_WIDGET(anchor), x, y);
gtk_widget_insert_before(GTK_WIDGET(popover), GTK_WIDGET(anchor), NULL);
gtk_popover_present(GTK_POPOVER(popover));
gtk_popover_popup(popover);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.animation;
/**
* This evaluator can be used to perform type interpolation between <code>float</code> values.
*/
public class FloatEvaluator /*implements TypeEvaluator<Number>*/ {
/**
* This function returns the result of linearly interpolating the start and end values, with
* <code>fraction</code> representing the proportion between the start and end values. The
* calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,
* where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
* and <code>t</code> is <code>fraction</code>.
*
* @param fraction The fraction from the starting to the ending values
* @param startValue The start value; should be of type <code>float</code> or
* <code>Float</code>
* @param endValue The end value; should be of type <code>float</code> or <code>Float</code>
* @return A linear interpolation between the start and end values, given the
* <code>fraction</code> parameter.
*/
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}

View file

@ -8,4 +8,8 @@ public class KeyguardManager {
public boolean isKeyguardLocked() {
return false;
}
public boolean isKeyguardSecure() {
return true;
}
}

View file

@ -0,0 +1,9 @@
package android.app.backup;
import android.content.ContextWrapper;
public abstract class BackupAgent extends ContextWrapper {
public BackupAgent() {
super(null);
}
}

View file

@ -0,0 +1,5 @@
package android.app.backup;
public class BackupAgentHelper extends BackupAgent {
}

View file

@ -0,0 +1,8 @@
package android.app.backup;
import android.content.Context;
public class BackupManager {
public BackupManager(Context context) {
}
}

View file

@ -10,15 +10,7 @@ public class JobInfo {
public static final class Builder {
public Builder(int jobId, ComponentName jobService) {}
public Builder setMinimumLatency(long minLatencyMillis) {
return this;
}
public Builder setRequiredNetworkType(int networkType) {
return this;
}
public Builder setOverrideDeadline(long a) {
public Builder setBackoffCriteria(long initialBackoffMillis, int backoffPolicy) {
return this;
}
@ -26,15 +18,15 @@ public class JobInfo {
return this;
}
public Builder setRequiresCharging(boolean requiresCharging) {
public Builder setMinimumLatency(long minLatencyMillis) {
return this;
}
public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) {
public Builder setOverrideDeadline(long a) {
return this;
}
public Builder setBackoffCriteria(long initialBackoffMillis, int backoffPolicy) {
public Builder setPeriodic(long dummy) {
return this;
}
@ -42,6 +34,18 @@ public class JobInfo {
return this;
}
public Builder setRequiredNetworkType(int networkType) {
return this;
}
public Builder setRequiresCharging(boolean requires_charging) {
return this;
}
public Builder setRequiresDeviceIdle(boolean requires_device_idle) {
return this;
}
public JobInfo build() {
return new JobInfo();
}

View file

@ -21,4 +21,7 @@ public class JobScheduler {
public int schedule(JobInfo job) {
return 1; //RESULT_SUCCESS
}
public void cancel(int dummy) {
}
}

View file

@ -16,6 +16,14 @@ public abstract class ContentProvider {
static void createContentProviders() {
for (PackageParser.Provider provider_parsed : Context.pkg.providers) {
String process_name = provider_parsed.info.processName;
if(process_name != null && process_name.contains(":")) {
/* NOTE: even if it doesn't contain `:`, if it's not null we probably
* need to check what it's requesting; `:` means it wants us to spawn
* a new process, which we currently don't support */
System.out.println("not creating provider " + provider_parsed.className + ", it wants to be started in a new process (" + process_name + ")");
continue;
}
try {
String providerName = provider_parsed.className;
System.out.println("creating " + providerName);

View file

@ -238,6 +238,8 @@ public class Context extends Object {
return new JobScheduler();
case "appops":
return new AppOpsManager();
case "user":
return new UserManager();
default:
Slog.e(TAG, "!!!!!!! getSystemService: case >" + name + "< is not implemented yet");
return null;
@ -717,4 +719,9 @@ public class Context extends Object {
return new String[0];
}
}
public Context createDeviceProtectedStorageContext() {
/* FIXME: should be a different context, and return different storage locations */
return this;
}
}

View file

@ -56,6 +56,10 @@ public class IntentFilter {
public void addDataPath(String path, int type) {}
public final void addDataSchemeSpecificPart(String ssp, int type) {
/* FIXME */
}
public boolean hasDataScheme(String dataScheme) {
return dataSchemes.contains(dataScheme);
}

View file

@ -19,6 +19,7 @@ package android.content.pm;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@ -1834,6 +1835,14 @@ public class PackageManager {
case "android.permission.READ_EXTERNAL_STORAGE":
case "com.google.android.c2dm.permission.SEND":
return PERMISSION_GRANTED;
// only tell the app that it can access location if it *actually* can
// (until we find apps that refuse to launch without being lied to anyway)
case "android.permission.ACCESS_FINE_LOCATION":
case "android.permission.ACCESS_COARSE_LOCATION":
if(System.getenv("ATL_UGLY_ENABLE_LOCATION") != null)
return PERMISSION_GRANTED;
else
return PERMISSION_DENIED;
default:
System.out.println("PackageManager.checkPermission: >" + permName + "< not handled\n");
return PERMISSION_DENIED;
@ -2142,7 +2151,34 @@ public class PackageManager {
* @see #GET_RESOLVED_FILTER
*/
public ResolveInfo resolveActivity(Intent intent, int flags) {
return new ResolveInfo();
ResolveInfo info = null;
ActivityInfo activity_info = null;
if (intent.getComponent() != null) {
for (PackageParser.Activity activity: Context.pkg.activities) {
if (intent.getComponent().getClassName() == activity.className)
activity_info = activity.info;
}
} else {
for (PackageParser.Activity activity: Context.pkg.activities) {
for (PackageParser.IntentInfo intentInfo: activity.intents) {
if (intentInfo.matchAction(intent.getAction())) {
activity_info = activity.info;
break;
}
}
}
}
if (activity_info == null) {
return null;
}
info = new ResolveInfo();
info.activityInfo.exported = true;
info.activityInfo = activity_info;
return info;
}
/**
@ -2200,9 +2236,12 @@ public class PackageManager {
*/
public List<ResolveInfo> queryIntentActivities(Intent intent,
int flags) {
ResolveInfo info = new ResolveInfo();
info.activityInfo.exported = true;
return Arrays.asList(info);
/* FIXME - we may need to return more than one */
ResolveInfo info = resolveActivity(intent, flags);
if (info != null)
return Arrays.asList(info);
else
return Collections.emptyList();
}
/**

View file

@ -1042,7 +1042,7 @@ public final class Configuration implements Comparable<Configuration> {
public void setToDefaults() {
fontScale = 1;
mcc = mnc = 0;
locale = null;
locale = new Locale("en", "US");
userSetLocale = false;
touchscreen = TOUCHSCREEN_UNDEFINED;
keyboard = KEYBOARD_UNDEFINED;

View file

@ -137,7 +137,7 @@ final class XmlBlock {
}
public String getText() {
int id = nativeGetText(mParseState);
return id >= 0 ? mStrings.get(id).toString() : null;
return id >= 0 ? (String)getPooledString(id) : null;
}
public int getLineNumber() {
return nativeGetLineNumber(mParseState);
@ -165,7 +165,7 @@ final class XmlBlock {
}
public String getNamespace() {
int id = nativeGetNamespace(mParseState);
return id >= 0 ? mStrings.get(id).toString() : "";
return id >= 0 ? (String)getPooledString(id) : "";
}
public String getName() {
return nativeGetName(mParseState);
@ -175,7 +175,7 @@ final class XmlBlock {
if (DEBUG)
System.out.println("getAttributeNamespace of " + index + " = " + id);
if (id >= 0)
return mStrings.get(id).toString();
return (String)getPooledString(id);
else if (id == -1)
return "";
throw new IndexOutOfBoundsException(String.valueOf(index));
@ -185,7 +185,7 @@ final class XmlBlock {
if (DEBUG)
System.out.println("getAttributeName of " + index + " = " + id);
if (id >= 0)
return mStrings.get(id).toString();
return (String)getPooledString(id);
throw new IndexOutOfBoundsException(String.valueOf(index));
}
public String getAttributePrefix(int index) {
@ -417,7 +417,7 @@ final class XmlBlock {
public String getIdAttribute() {
int id = nativeGetIdAttribute(mParseState);
return id >= 0 ? mStrings.get(id).toString() : null;
return id >= 0 ? (String)getPooledString(id) : null;
}
public String getClassAttribute() {
return nativeGetClassAttribute(mParseState);

View file

@ -1,5 +1,8 @@
package android.graphics;
import android.content.res.Resources;
import android.util.Log;
public class Canvas {
public static final int HAS_ALPHA_LAYER_SAVE_FLAG = (1 << 2);
@ -136,6 +139,7 @@ public class Canvas {
* @param paint The paint used for the text (e.g. color, size, style)
*/
public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
drawText(text.toString(), start, end, x, y, paint);
/*if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
native_drawText(mNativeCanvas, text.toString(), start, end, x, y,
@ -151,6 +155,11 @@ public class Canvas {
TemporaryBuffer.recycle(buf);
}*/
}
public void drawTextOnPath(String text, Path path, float x_offset, float y_offset, Paint paint) {
Log.w("Canvas", "STUB: drawTextOnPath");
}
// ---
/**
* <p>Draw the specified arc, which will be scaled to fit inside the
@ -180,6 +189,7 @@ public class Canvas {
if (oval == null) {
throw new NullPointerException();
}
Log.w("Canvas", "STUB: drawArc");
/*native_drawArc(mNativeCanvas, oval, startAngle, sweepAngle,
useCenter, paint.mNativePaint);*/
}
@ -308,7 +318,7 @@ public class Canvas {
*/
public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
int width, int height, boolean hasAlpha, Paint paint) {
System.out.println("XXXXXXX bitmap(colors, offset, ...)");
Log.w("Canvas", "STUB: drawBitmap(colors, offset, ...)");
/* // check for valid input
if (width < 0) {
throw new IllegalArgumentException("width must be >= 0");
@ -417,7 +427,9 @@ public class Canvas {
matrix.reset();
}
public void translate(float dx, float dy) {}
public void translate(float dx, float dy) {
Log.w("Canvas", "STUB: translate");
}
public void drawCircle(float cx, float cy, float radius, Paint paint) {
gsk_canvas.snapshot = bitmap.getSnapshot();
@ -425,14 +437,18 @@ public class Canvas {
}
public Rect getClipBounds() {
return new Rect(0, 0, 10, 10);
Rect rect = new Rect();
getClipBounds(rect);
return rect;
}
public boolean clipRect(Rect rect, Region.Op op) {
return false;
}
public void concat(Matrix matrix) {}
public void concat(Matrix matrix) {
Log.w("Canvas", "STUB: concat");
}
public boolean clipPath(Path path, Region.Op op) {
return false;
@ -446,21 +462,29 @@ public class Canvas {
return (bitmap == null) ? 0 : bitmap.getHeight();
}
public void drawColor(int dummy) {}
public void drawColor(int color) {
Log.w("Canvas", "STUB: drawColor("+String.format("0x%08x", color)+")");
}
public void drawARGB(int a, int r, int g, int b) {}
public void drawARGB(int a, int r, int g, int b) {
Log.w("Canvas", "STUB: drawARGB("+a+", "+r+", "+g+", "+b+")");
}
public int saveLayer(RectF bounds, Paint paint, int flags) {
return save();
}
public void drawOval(RectF oval, Paint paint) {}
public void drawOval(RectF oval, Paint paint) {
Log.w("Canvas", "STUB: drawOval");
}
public boolean clipRect(int left, int top, int right, int bottom) {
return false;
}
public void drawColor(int color, PorterDuff.Mode mode) {}
public void drawColor(int color, PorterDuff.Mode mode) {
Log.w("Canvas", "STUB: drawColor("+String.format("0x%08x", color)+", "+mode+")");
}
public boolean clipRect(Rect rect) {
return false;
@ -486,12 +510,17 @@ public class Canvas {
return false;
}
public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean includeCenter, Paint paint) {}
public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean includeCenter, Paint paint) {
Log.w("Canvas", "STUB: drawArc");
}
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) {}
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) {
Log.w("Canvas", "STUB: drawRoundRect");
}
public boolean getClipBounds(Rect outRect) {
outRect.set(0, 0, 100, 100);
/* UGLY HACK */
outRect.set(0, 0, Resources.getSystem().getDisplayMetrics().widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels);
return true;
}

View file

@ -71,6 +71,10 @@ public class GskCanvas extends Canvas {
@Override
public void drawText(String text, float x, float y, Paint paint) {
if(text == null) {
new Exception("drawText: text is null; stack trace:").printStackTrace();
return;
}
native_drawText(snapshot, text, x, y, paint != null ? paint.paint : default_paint.paint);
}

View file

@ -16,4 +16,8 @@ public class PathMeasure {
public boolean getSegment(float start, float end, Path dst, boolean forceClosed) {
return false;
}
public boolean getPosTan(float distance, float[] pos, float[] tan) {
return false;
}
}

View file

@ -14,6 +14,9 @@
* limitations under the License.
*/
package android.graphics;
import android.util.Log;
// import android.util.Pools.SynchronizedPool;
public class Region {
private static final int MAX_POOL_SIZE = 10;
@ -70,7 +73,7 @@ public class Region {
* Set the region to the empty region
*/
public void setEmpty() {
nativeSetRect(mNativeRegion, 0, 0, 0, 0);
Log.w("graphics/Region", "TODO: nativeSetRect(mNativeRegion, 0, 0, 0, 0);");
}
/**
* Set the region to the specified region.
@ -230,8 +233,8 @@ public class Region {
* true if the result of the op is not empty.
*/
public boolean op(Rect r, Op op) {
return nativeOp(mNativeRegion, r.left, r.top, r.right, r.bottom,
op.nativeInt);
Log.w("graphics/Region", "TODO: return nativeOp(mNativeRegion, r.left, r.top, r.right, r.bottom, op.nativeInt);");
return true;
}
/**
* Perform the specified Op on this region and the specified rect. Return

View file

@ -66,22 +66,24 @@ public class DrawableContainer extends Drawable {
@Override
public void draw(Canvas canvas) {
state.drawables[curIndex].draw(canvas);
if (curIndex != -1)
state.drawables[curIndex].draw(canvas);
}
@Override
public int getIntrinsicHeight() {
return state.drawables[curIndex].getIntrinsicHeight();
return curIndex != -1 ? state.drawables[curIndex].getIntrinsicHeight() : -1;
}
@Override
public int getIntrinsicWidth() {
return state.drawables[curIndex].getIntrinsicWidth();
return curIndex != -1 ? state.drawables[curIndex].getIntrinsicWidth() : -1;
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
state.drawables[curIndex].setBounds(left, top, right, bottom);
if (curIndex != -1)
state.drawables[curIndex].setBounds(left, top, right, bottom);
}
public void setEnterFadeDuration(int duration) {}

View file

@ -0,0 +1,388 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Estimates magnetic field at a given point on
* Earth, and in particular, to compute the magnetic declination from true
* north.
*
* <p>This uses the World Magnetic Model produced by the United States National
* Geospatial-Intelligence Agency. More details about the model can be found at
* <a href="http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml">http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml</a>.
* This class currently uses WMM-2020 which is valid until 2025, but should
* produce acceptable results for several years after that. Future versions of
* Android may use a newer version of the model.
*/
public class GeomagneticField {
// The magnetic field at a given point, in nanoteslas in geodetic
// coordinates.
private float mX;
private float mY;
private float mZ;
// Geocentric coordinates -- set by computeGeocentricCoordinates.
private float mGcLatitudeRad;
private float mGcLongitudeRad;
private float mGcRadiusKm;
// Constants from WGS84 (the coordinate system used by GPS)
static private final float EARTH_SEMI_MAJOR_AXIS_KM = 6378.137f;
static private final float EARTH_SEMI_MINOR_AXIS_KM = 6356.7523142f;
static private final float EARTH_REFERENCE_RADIUS_KM = 6371.2f;
// These coefficients and the formulae used below are from:
// NOAA Technical Report: The US/UK World Magnetic Model for 2020-2025
static private final float[][] G_COEFF = new float[][] {
{0.0f},
{-29404.5f, -1450.7f},
{-2500.0f, 2982.0f, 1676.8f},
{1363.9f, -2381.0f, 1236.2f, 525.7f},
{903.1f, 809.4f, 86.2f, -309.4f, 47.9f},
{-234.4f, 363.1f, 187.8f, -140.7f, -151.2f, 13.7f},
{65.9f, 65.6f, 73.0f, -121.5f, -36.2f, 13.5f, -64.7f},
{80.6f, -76.8f, -8.3f, 56.5f, 15.8f, 6.4f, -7.2f, 9.8f},
{23.6f, 9.8f, -17.5f, -0.4f, -21.1f, 15.3f, 13.7f, -16.5f, -0.3f},
{5.0f, 8.2f, 2.9f, -1.4f, -1.1f, -13.3f, 1.1f, 8.9f, -9.3f, -11.9f},
{-1.9f, -6.2f, -0.1f, 1.7f, -0.9f, 0.6f, -0.9f, 1.9f, 1.4f, -2.4f, -3.9f},
{3.0f, -1.4f, -2.5f, 2.4f, -0.9f, 0.3f, -0.7f, -0.1f, 1.4f, -0.6f, 0.2f, 3.1f},
{-2.0f, -0.1f, 0.5f, 1.3f, -1.2f, 0.7f, 0.3f, 0.5f, -0.2f, -0.5f, 0.1f, -1.1f, -0.3f}};
static private final float[][] H_COEFF = new float[][] {
{0.0f},
{0.0f, 4652.9f},
{0.0f, -2991.6f, -734.8f},
{0.0f, -82.2f, 241.8f, -542.9f},
{0.0f, 282.0f, -158.4f, 199.8f, -350.1f},
{0.0f, 47.7f, 208.4f, -121.3f, 32.2f, 99.1f},
{0.0f, -19.1f, 25.0f, 52.7f, -64.4f, 9.0f, 68.1f},
{0.0f, -51.4f, -16.8f, 2.3f, 23.5f, -2.2f, -27.2f, -1.9f},
{0.0f, 8.4f, -15.3f, 12.8f, -11.8f, 14.9f, 3.6f, -6.9f, 2.8f},
{0.0f, -23.3f, 11.1f, 9.8f, -5.1f, -6.2f, 7.8f, 0.4f, -1.5f, 9.7f},
{0.0f, 3.4f, -0.2f, 3.5f, 4.8f, -8.6f, -0.1f, -4.2f, -3.4f, -0.1f, -8.8f},
{0.0f, 0.0f, 2.6f, -0.5f, -0.4f, 0.6f, -0.2f, -1.7f, -1.6f, -3.0f, -2.0f, -2.6f},
{0.0f, -1.2f, 0.5f, 1.3f, -1.8f, 0.1f, 0.7f, -0.1f, 0.6f, 0.2f, -0.9f, 0.0f, 0.5f}};
static private final float[][] DELTA_G = new float[][] {
{0.0f},
{6.7f, 7.7f},
{-11.5f, -7.1f, -2.2f},
{2.8f, -6.2f, 3.4f, -12.2f},
{-1.1f, -1.6f, -6.0f, 5.4f, -5.5f},
{-0.3f, 0.6f, -0.7f, 0.1f, 1.2f, 1.0f},
{-0.6f, -0.4f, 0.5f, 1.4f, -1.4f, 0.0f, 0.8f},
{-0.1f, -0.3f, -0.1f, 0.7f, 0.2f, -0.5f, -0.8f, 1.0f},
{-0.1f, 0.1f, -0.1f, 0.5f, -0.1f, 0.4f, 0.5f, 0.0f, 0.4f},
{-0.1f, -0.2f, 0.0f, 0.4f, -0.3f, 0.0f, 0.3f, 0.0f, 0.0f, -0.4f},
{0.0f, 0.0f, 0.0f, 0.2f, -0.1f, -0.2f, 0.0f, -0.1f, -0.2f, -0.1f, 0.0f},
{0.0f, -0.1f, 0.0f, 0.0f, 0.0f, -0.1f, 0.0f, 0.0f, -0.1f, -0.1f, -0.1f, -0.1f},
{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.1f}};
static private final float[][] DELTA_H = new float[][] {
{0.0f},
{0.0f, -25.1f},
{0.0f, -30.2f, -23.9f},
{0.0f, 5.7f, -1.0f, 1.1f},
{0.0f, 0.2f, 6.9f, 3.7f, -5.6f},
{0.0f, 0.1f, 2.5f, -0.9f, 3.0f, 0.5f},
{0.0f, 0.1f, -1.8f, -1.4f, 0.9f, 0.1f, 1.0f},
{0.0f, 0.5f, 0.6f, -0.7f, -0.2f, -1.2f, 0.2f, 0.3f},
{0.0f, -0.3f, 0.7f, -0.2f, 0.5f, -0.3f, -0.5f, 0.4f, 0.1f},
{0.0f, -0.3f, 0.2f, -0.4f, 0.4f, 0.1f, 0.0f, -0.2f, 0.5f, 0.2f},
{0.0f, 0.0f, 0.1f, -0.3f, 0.1f, -0.2f, 0.1f, 0.0f, -0.1f, 0.2f, 0.0f},
{0.0f, 0.0f, 0.1f, 0.0f, 0.2f, 0.0f, 0.0f, 0.1f, 0.0f, -0.1f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, -0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, -0.1f}};
static private final long BASE_TIME = new Calendar.Builder()
.setTimeZone(TimeZone.getTimeZone("UTC"))
.setDate(2020, Calendar.JANUARY, 1)
.build()
.getTimeInMillis();
// The ratio between the Gauss-normalized associated Legendre functions and
// the Schmid quasi-normalized ones. Compute these once staticly since they
// don't depend on input variables at all.
static private final float[][] SCHMIDT_QUASI_NORM_FACTORS =
computeSchmidtQuasiNormFactors(G_COEFF.length);
/**
* Estimate the magnetic field at a given point and time.
*
* @param gdLatitudeDeg
* Latitude in WGS84 geodetic coordinates -- positive is east.
* @param gdLongitudeDeg
* Longitude in WGS84 geodetic coordinates -- positive is north.
* @param altitudeMeters
* Altitude in WGS84 geodetic coordinates, in meters.
* @param timeMillis
* Time at which to evaluate the declination, in milliseconds
* since January 1, 1970. (approximate is fine -- the declination
* changes very slowly).
*/
public GeomagneticField(float gdLatitudeDeg,
float gdLongitudeDeg,
float altitudeMeters,
long timeMillis) {
final int MAX_N = G_COEFF.length; // Maximum degree of the coefficients.
// We don't handle the north and south poles correctly -- pretend that
// we're not quite at them to avoid crashing.
gdLatitudeDeg = Math.min(90.0f - 1e-5f,
Math.max(-90.0f + 1e-5f, gdLatitudeDeg));
computeGeocentricCoordinates(gdLatitudeDeg,
gdLongitudeDeg,
altitudeMeters);
assert G_COEFF.length == H_COEFF.length;
// Note: LegendreTable computes associated Legendre functions for
// cos(theta). We want the associated Legendre functions for
// sin(latitude), which is the same as cos(PI/2 - latitude), except the
// derivate will be negated.
LegendreTable legendre =
new LegendreTable(MAX_N - 1,
(float)(Math.PI / 2.0 - mGcLatitudeRad));
// Compute a table of (EARTH_REFERENCE_RADIUS_KM / radius)^n for i in
// 0..MAX_N-2 (this is much faster than calling Math.pow MAX_N+1 times).
float[] relativeRadiusPower = new float[MAX_N + 2];
relativeRadiusPower[0] = 1.0f;
relativeRadiusPower[1] = EARTH_REFERENCE_RADIUS_KM / mGcRadiusKm;
for (int i = 2; i < relativeRadiusPower.length; ++i) {
relativeRadiusPower[i] = relativeRadiusPower[i - 1] *
relativeRadiusPower[1];
}
// Compute tables of sin(lon * m) and cos(lon * m) for m = 0..MAX_N --
// this is much faster than calling Math.sin and Math.com MAX_N+1 times.
float[] sinMLon = new float[MAX_N];
float[] cosMLon = new float[MAX_N];
sinMLon[0] = 0.0f;
cosMLon[0] = 1.0f;
sinMLon[1] = (float)Math.sin(mGcLongitudeRad);
cosMLon[1] = (float)Math.cos(mGcLongitudeRad);
for (int m = 2; m < MAX_N; ++m) {
// Standard expansions for sin((m-x)*theta + x*theta) and
// cos((m-x)*theta + x*theta).
int x = m >> 1;
sinMLon[m] = sinMLon[m - x] * cosMLon[x] + cosMLon[m - x] * sinMLon[x];
cosMLon[m] = cosMLon[m - x] * cosMLon[x] - sinMLon[m - x] * sinMLon[x];
}
float inverseCosLatitude = 1.0f / (float)Math.cos(mGcLatitudeRad);
float yearsSinceBase =
(timeMillis - BASE_TIME) / (365f * 24f * 60f * 60f * 1000f);
// We now compute the magnetic field strength given the geocentric
// location. The magnetic field is the derivative of the potential
// function defined by the model. See NOAA Technical Report: The US/UK
// World Magnetic Model for 2020-2025 for the derivation.
float gcX = 0.0f; // Geocentric northwards component.
float gcY = 0.0f; // Geocentric eastwards component.
float gcZ = 0.0f; // Geocentric downwards component.
for (int n = 1; n < MAX_N; n++) {
for (int m = 0; m <= n; m++) {
// Adjust the coefficients for the current date.
float g = G_COEFF[n][m] + yearsSinceBase * DELTA_G[n][m];
float h = H_COEFF[n][m] + yearsSinceBase * DELTA_H[n][m];
// Negative derivative with respect to latitude, divided by
// radius. This looks like the negation of the version in the
// NOAA Technical report because that report used
// P_n^m(sin(theta)) and we use P_n^m(cos(90 - theta)), so the
// derivative with respect to theta is negated.
gcX += relativeRadiusPower[n + 2] * (g * cosMLon[m] + h * sinMLon[m]) * legendre.mPDeriv[n][m] * SCHMIDT_QUASI_NORM_FACTORS[n][m];
// Negative derivative with respect to longitude, divided by
// radius.
gcY += relativeRadiusPower[n + 2] * m * (g * sinMLon[m] - h * cosMLon[m]) * legendre.mP[n][m] * SCHMIDT_QUASI_NORM_FACTORS[n][m] * inverseCosLatitude;
// Negative derivative with respect to radius.
gcZ -= (n + 1) * relativeRadiusPower[n + 2] * (g * cosMLon[m] + h * sinMLon[m]) * legendre.mP[n][m] * SCHMIDT_QUASI_NORM_FACTORS[n][m];
}
}
// Convert back to geodetic coordinates. This is basically just a
// rotation around the Y-axis by the difference in latitudes between the
// geocentric frame and the geodetic frame.
double latDiffRad = Math.toRadians(gdLatitudeDeg) - mGcLatitudeRad;
mX = (float)(gcX * Math.cos(latDiffRad) + gcZ * Math.sin(latDiffRad));
mY = gcY;
mZ = (float)(-gcX * Math.sin(latDiffRad) + gcZ * Math.cos(latDiffRad));
}
/**
* @return The X (northward) component of the magnetic field in nanoteslas.
*/
public float getX() {
return mX;
}
/**
* @return The Y (eastward) component of the magnetic field in nanoteslas.
*/
public float getY() {
return mY;
}
/**
* @return The Z (downward) component of the magnetic field in nanoteslas.
*/
public float getZ() {
return mZ;
}
/**
* @return The declination of the horizontal component of the magnetic
* field from true north, in degrees (i.e. positive means the
* magnetic field is rotated east that much from true north).
*/
public float getDeclination() {
return (float)Math.toDegrees(Math.atan2(mY, mX));
}
/**
* @return The inclination of the magnetic field in degrees -- positive
* means the magnetic field is rotated downwards.
*/
public float getInclination() {
return (float)Math.toDegrees(Math.atan2(mZ,
getHorizontalStrength()));
}
/**
* @return Horizontal component of the field strength in nanoteslas.
*/
public float getHorizontalStrength() {
return (float)Math.hypot(mX, mY);
}
/**
* @return Total field strength in nanoteslas.
*/
public float getFieldStrength() {
return (float)Math.sqrt(mX * mX + mY * mY + mZ * mZ);
}
/**
* @param gdLatitudeDeg
* Latitude in WGS84 geodetic coordinates.
* @param gdLongitudeDeg
* Longitude in WGS84 geodetic coordinates.
* @param altitudeMeters
* Altitude above sea level in WGS84 geodetic coordinates.
* @return Geocentric latitude (i.e. angle between closest point on the
* equator and this point, at the center of the earth.
*/
private void computeGeocentricCoordinates(float gdLatitudeDeg,
float gdLongitudeDeg,
float altitudeMeters) {
float altitudeKm = altitudeMeters / 1000.0f;
float a2 = EARTH_SEMI_MAJOR_AXIS_KM * EARTH_SEMI_MAJOR_AXIS_KM;
float b2 = EARTH_SEMI_MINOR_AXIS_KM * EARTH_SEMI_MINOR_AXIS_KM;
double gdLatRad = Math.toRadians(gdLatitudeDeg);
float clat = (float)Math.cos(gdLatRad);
float slat = (float)Math.sin(gdLatRad);
float tlat = slat / clat;
float latRad =
(float)Math.sqrt(a2 * clat * clat + b2 * slat * slat);
mGcLatitudeRad = (float)Math.atan(tlat * (latRad * altitudeKm + b2) / (latRad * altitudeKm + a2));
mGcLongitudeRad = (float)Math.toRadians(gdLongitudeDeg);
float radSq = altitudeKm * altitudeKm + 2 * altitudeKm * (float)Math.sqrt(a2 * clat * clat + b2 * slat * slat) + (a2 * a2 * clat * clat + b2 * b2 * slat * slat) / (a2 * clat * clat + b2 * slat * slat);
mGcRadiusKm = (float)Math.sqrt(radSq);
}
/**
* Utility class to compute a table of Gauss-normalized associated Legendre
* functions P_n^m(cos(theta))
*/
static private class LegendreTable {
// These are the Gauss-normalized associated Legendre functions -- that
// is, they are normal Legendre functions multiplied by
// (n-m)!/(2n-1)!! (where (2n-1)!! = 1*3*5*...*2n-1)
public final float[][] mP;
// Derivative of mP, with respect to theta.
public final float[][] mPDeriv;
/**
* @param maxN
* The maximum n- and m-values to support
* @param thetaRad
* Returned functions will be Gauss-normalized
* P_n^m(cos(thetaRad)), with thetaRad in radians.
*/
public LegendreTable(int maxN, float thetaRad) {
// Compute the table of Gauss-normalized associated Legendre
// functions using standard recursion relations. Also compute the
// table of derivatives using the derivative of the recursion
// relations.
float cos = (float)Math.cos(thetaRad);
float sin = (float)Math.sin(thetaRad);
mP = new float[maxN + 1][];
mPDeriv = new float[maxN + 1][];
mP[0] = new float[] {1.0f};
mPDeriv[0] = new float[] {0.0f};
for (int n = 1; n <= maxN; n++) {
mP[n] = new float[n + 1];
mPDeriv[n] = new float[n + 1];
for (int m = 0; m <= n; m++) {
if (n == m) {
mP[n][m] = sin * mP[n - 1][m - 1];
mPDeriv[n][m] = cos * mP[n - 1][m - 1] + sin * mPDeriv[n - 1][m - 1];
} else if (n == 1 || m == n - 1) {
mP[n][m] = cos * mP[n - 1][m];
mPDeriv[n][m] = -sin * mP[n - 1][m] + cos * mPDeriv[n - 1][m];
} else {
assert n > 1 && m < n - 1;
float k = ((n - 1) * (n - 1) - m * m) / (float)((2 * n - 1) * (2 * n - 3));
mP[n][m] = cos * mP[n - 1][m] - k * mP[n - 2][m];
mPDeriv[n][m] = -sin * mP[n - 1][m] + cos * mPDeriv[n - 1][m] - k * mPDeriv[n - 2][m];
}
}
}
}
}
/**
* Compute the ration between the Gauss-normalized associated Legendre
* functions and the Schmidt quasi-normalized version. This is equivalent to
* sqrt((m==0?1:2)*(n-m)!/(n+m!))*(2n-1)!!/(n-m)!
*/
private static float[][] computeSchmidtQuasiNormFactors(int maxN) {
float[][] schmidtQuasiNorm = new float[maxN + 1][];
schmidtQuasiNorm[0] = new float[] {1.0f};
for (int n = 1; n <= maxN; n++) {
schmidtQuasiNorm[n] = new float[n + 1];
schmidtQuasiNorm[n][0] =
schmidtQuasiNorm[n - 1][0] * (2 * n - 1) / (float)n;
for (int m = 1; m <= n; m++) {
schmidtQuasiNorm[n][m] = schmidtQuasiNorm[n][m - 1] * (float)Math.sqrt((n - m + 1) * (m == 1 ? 2 : 1) / (float)(n + m));
}
}
return schmidtQuasiNorm;
}
}

View file

@ -23,7 +23,7 @@ public class SensorManager {
new LocationManager().requestLocationUpdates(null, 0, 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
listener.onSensorChanged(new SensorEvent(new float[]{(float)location.getBearing()}, sensor));
listener.onSensorChanged(new SensorEvent(new float[]{location.getBearing()}, sensor));
}
});
return true;

View file

@ -4,12 +4,27 @@ public class Location {
private double latitude;
private double longitude;
private double altitude;
private double accuracy;
private double speed;
private double bearing;
private long timestamp;
public Location (double latitude, double longitude, double bearing) {
/* for internal use */
public Location (double latitude,
double longitude,
double altitude,
double accuracy,
double speed,
double bearing,
long timestamp) {
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
this.accuracy = accuracy;
this.speed = speed;
this.bearing = bearing;
this.timestamp = timestamp;
}
public double getLatitude() {
@ -20,8 +35,43 @@ public class Location {
return longitude;
}
public double getBearing() {
return bearing;
public boolean hasAltitude() {
return altitude != -Double.MAX_VALUE;
}
public double getAltitude() {
return altitude;
}
public boolean hasAccuracy() {
return true;
}
public float getAccuracy() {
return (float)accuracy;
}
public boolean hasSpeed() {
return speed != -1;
}
public float getSpeed() {
return (float)speed;
}
public boolean hasBearing() {
return bearing != -1;
}
public float getBearing() {
return (float)bearing;
}
public long getTime() {
return timestamp;
}
public String getProvider() {
return "fused";
}
}

View file

@ -1,7 +1,10 @@
package android.location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import java.lang.Runnable;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@ -26,9 +29,15 @@ public class LocationManager {
private native void nativeGetLocation();
private static void locationUpdated(double latitude, double longitude, double heading) {
private static void locationUpdated(double latitude,
double longitude,
double altitude,
double accuracy,
double speed,
double bearing,
long timestamp) {
for (LocationListener locationListener : listeners) {
locationListener.onLocationChanged(new Location(latitude, longitude, heading));
locationListener.onLocationChanged(new Location(latitude, longitude, altitude, accuracy, speed, bearing, timestamp));
}
}
@ -42,4 +51,21 @@ public class LocationManager {
public List<String> getAllProviders() {
return Collections.emptyList();
}
public List<String> getProviders(boolean enabledOnly) {
return Collections.emptyList();
}
public boolean registerGnssStatusCallback(GnssStatus.Callback callback, Handler handler) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.onSatelliteStatusChanged(new GnssStatus());
}
});
return true;
}
public void unregisterGnssStatusCallback(GnssStatus.Callback callback) {
}
}

View file

@ -2,8 +2,6 @@ package android.net;
import android.os.Handler;
class NetworkCapabilities {}
public class ConnectivityManager {
public class NetworkCallback {
@ -35,10 +33,14 @@ public class ConnectivityManager {
return new Network();
}
public void registerDefaultNetworkCallback(NetworkCallback cb, Handler hdl) {}
public Network[] getAllNetworks() {
return new Network[] { getActiveNetwork() };
}
public NetworkCapabilities getNetworkCapabilities(Network network) {
return null;
}
public void registerDefaultNetworkCallback(NetworkCallback cb, Handler hdl) {}
}

View file

@ -0,0 +1,7 @@
package android.net;
public final class NetworkCapabilities {
public boolean hasCapability(int capability) {
return false;
}
}

View file

@ -12,7 +12,12 @@ public class BaseBundle {
// Invariant - exactly one of mMap / mParcelledData will be null
// (except inside a call to unparcel)
/* package */ ArrayMap<String, Object> mMap = new ArrayMap<>();
/* package */ ArrayMap<String, Object> mMap;
public BaseBundle() {
mMap = new ArrayMap<String, Object>();
}
// Log a message if the value was non-null but not of the expected type
void typeWarning(String key, Object value, String className,

View file

@ -107,6 +107,11 @@ public class Build {
* Various version strings.
*/
public static class VERSION {
static {
String SDK_INT_str = System.getProperty("Build.VERSION.SDK_INT");
SDK_INT = (SDK_INT_str != null) ? Integer.parseInt(SDK_INT_str) : Build.VERSION_CODES.GINGERBREAD;
}
/**
* The internal value used by the underlying source control to
* represent this build. E.g., a perforce changelist number
@ -123,7 +128,7 @@ public class Build {
* The user-visible SDK version of the framework; its possible
* values are defined in {@link Build.VERSION_CODES}.
*/
public static final int SDK_INT = Build.VERSION_CODES.GINGERBREAD;
public static final int SDK_INT;
/**
* The user-visible SDK version of the framework in its raw String

View file

@ -57,7 +57,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
* Constructs a new, empty Bundle.
*/
public Bundle() {
mMap = new ArrayMap<String, Object>();
super();
mClassLoader = getClass().getClassLoader();
}

View file

@ -2,12 +2,27 @@ package android.os;
public class SystemProperties {
public static String get(String prop) {
android.util.Log.i("SystemProperties", "Grabbing prop " + prop);
return null;
android.util.Log.i("SystemProperties", "Grabbing String prop " + prop);
return "";
}
public static String get(String prop, String def) {
android.util.Log.i("SystemProperties", "Grabbing String prop " + prop + ", default " + def);
return def;
}
public boolean getBoolean(String prop, boolean def) {
android.util.Log.i("SystemProperties", "Grabbing prop " + prop + ", default " + def);
android.util.Log.i("SystemProperties", "Grabbing boolean prop " + prop + ", default " + def);
return def;
}
public static int getInt(String prop, int def) {
android.util.Log.i("SystemProperties", "Grabbing int prop " + prop + ", default " + def);
return def;
}
public static long getLong(String prop, long def) {
android.util.Log.i("SystemProperties", "Grabbing long prop " + prop + ", default " + def);
return def;
}
}

View file

@ -1,3 +1,6 @@
package android.provider;
public interface BaseColumns {}
public interface BaseColumns {
public static final String _ID = "_id";
public static final String _COUNT = "_count";
}

View file

@ -6,9 +6,13 @@ public class ContactsContract {
public static final class CommonDataKinds {
public static class Phone {
public static final class Phone {
public static final Uri CONTENT_URI = Uri.parse("content://com.android.contacts/phones");
}
public static final class Email {
public static final Uri CONTENT_URI = Uri.parse("content://com.android.contacts/emails");
}
}
public static final class Profile {

View file

@ -6,6 +6,12 @@ import android.util.AndroidException;
public class Settings {
public static final class Secure {
public static final Uri CONTENT_URI = Uri.parse("content://settings/secure");
public static Uri getUriFor(String name) {
return Uri.withAppendedPath(CONTENT_URI, name);
}
public static String getString(ContentResolver content_resolver, String key) {
switch (key) {
case "android_id":
@ -25,6 +31,8 @@ public class Settings {
switch (key) {
case "limit_ad_tracking":
return 1; // obviously, duh
case "user_setup_complete":
return 1;
default:
java.lang.System.out.println("!!!! Settings$Secure.getInt: unknown key: >" + key + "<");
return def;

View file

@ -0,0 +1,191 @@
/*
* Copyright (C) 2008 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.provider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import java.util.Locale;
/**
* A provider of user defined words for input methods to use for predictive text input.
* Applications and input methods may add words into the dictionary. Words can have associated
* frequency information and locale information.
*
* <p><strong>NOTE: </strong>Starting on API 23, the user dictionary is only accessible through
* IME and spellchecker.
*/
public class UserDictionary {
/**
* Authority string for this provider.
*/
public static final String AUTHORITY = "user_dictionary";
/**
* The content:// style URL for this provider
*/
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY);
private static final int FREQUENCY_MIN = 0;
private static final int FREQUENCY_MAX = 255;
/**
* Contains the user defined words.
*/
public static class Words implements BaseColumns {
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/words");
/**
* The MIME type of {@link #CONTENT_URI} providing a directory of words.
*/
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.userword";
/**
* The MIME type of a {@link #CONTENT_URI} sub-directory of a single word.
*/
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.userword";
public static final String _ID = BaseColumns._ID;
/**
* The word column.
* <p>TYPE: TEXT</p>
*/
public static final String WORD = "word";
/**
* The frequency column. A value between 1 and 255. Higher values imply higher frequency.
* <p>TYPE: INTEGER</p>
*/
public static final String FREQUENCY = "frequency";
/**
* The locale that this word belongs to. Null if it pertains to all
* locales. Locale is as defined by the string returned by Locale.toString().
* <p>TYPE: TEXT</p>
*/
public static final String LOCALE = "locale";
/**
* The uid of the application that inserted the word.
* <p>TYPE: INTEGER</p>
*/
public static final String APP_ID = "appid";
/**
* An optional shortcut for this word. When the shortcut is typed, supporting IMEs should
* suggest the word in this row as an alternate spelling too.
*/
public static final String SHORTCUT = "shortcut";
/**
* @deprecated Use {@link #addWord(Context, String, int, String, Locale)}.
*/
@Deprecated
public static final int LOCALE_TYPE_ALL = 0;
/**
* @deprecated Use {@link #addWord(Context, String, int, String, Locale)}.
*/
@Deprecated
public static final int LOCALE_TYPE_CURRENT = 1;
/**
* Sort by descending order of frequency.
*/
public static final String DEFAULT_SORT_ORDER = FREQUENCY + " DESC";
/**
* Adds a word to the dictionary, with the given frequency and the specified
* specified locale type.
*
* @deprecated Please use
* {@link #addWord(Context, String, int, String, Locale)} instead.
*
* @param context the current application context
* @param word the word to add to the dictionary. This should not be null or
* empty.
* @param localeType the locale type for this word. It should be one of
* {@link #LOCALE_TYPE_ALL} or {@link #LOCALE_TYPE_CURRENT}.
*/
@Deprecated
public static void addWord(Context context, String word,
int frequency, int localeType) {
if (localeType != LOCALE_TYPE_ALL && localeType != LOCALE_TYPE_CURRENT) {
return;
}
final Locale locale;
if (localeType == LOCALE_TYPE_CURRENT) {
locale = Locale.getDefault();
} else {
locale = null;
}
addWord(context, word, frequency, null, locale);
}
/**
* Adds a word to the dictionary, with the given frequency and the specified
* locale type.
*
* @param context the current application context
* @param word the word to add to the dictionary. This should not be null or
* empty.
* @param shortcut optional shortcut spelling for this word. When the shortcut
* is typed, the word may be suggested by applications that support it. May be null.
* @param locale the locale to insert the word for, or null to insert the word
* for all locales.
*/
public static void addWord(Context context, String word,
int frequency, String shortcut, Locale locale) {
final ContentResolver resolver = context.getContentResolver();
if (TextUtils.isEmpty(word)) {
return;
}
if (frequency < FREQUENCY_MIN)
frequency = FREQUENCY_MIN;
if (frequency > FREQUENCY_MAX)
frequency = FREQUENCY_MAX;
final int COLUMN_COUNT = 5;
ContentValues values = new ContentValues(COLUMN_COUNT);
values.put(WORD, word);
values.put(FREQUENCY, frequency);
values.put(LOCALE, null == locale ? null : locale.toString());
values.put(APP_ID, 0); // TODO: Get App UID
values.put(SHORTCUT, shortcut);
Uri result = resolver.insert(CONTENT_URI, values);
// It's ok if the insert doesn't succeed because the word
// already exists.
}
}
}

View file

@ -0,0 +1,10 @@
package android.text;
import android.view.View;
public class AutoText {
public static String get(CharSequence src, final int start, final int end, View view) {
return null;
}
}

View file

@ -1,6 +1,6 @@
/*
* most of this file:
*
*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,11 +18,11 @@
package android.text;
import com.android.internal.util.ArrayUtils;
import java.util.Iterator;
import java.util.Locale;
import java.util.regex.Pattern;
import com.android.internal.util.ArrayUtils;
public class TextUtils {
public static int getLayoutDirectionFromLocale(Locale locale) {
return 0 /*LTR*/; // FIXME
@ -255,7 +255,7 @@ public class TextUtils {
}
if (buf == null || buf.length < len)
buf = ArrayUtils.newUnpaddedCharArray(len);
buf = ArrayUtils.newUnpaddedCharArray(len);
return buf;
}
@ -377,4 +377,80 @@ public class TextUtils {
}
return true;
}
/**
* An interface for splitting strings according to rules that are opaque to the user of this
* interface. This also has less overhead than split, which uses regular expressions and
* allocates an array to hold the results.
*
* <p>The most efficient way to use this class is:
*
* <pre>
* // Once
* TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(delimiter);
*
* // Once per string to split
* splitter.setString(string);
* for (String s : splitter) {
* ...
* }
* </pre>
*/
public interface StringSplitter extends Iterable<String> {
public void setString(String string);
}
/**
* A simple string splitter.
*
* <p>If the final character in the string to split is the delimiter then no empty string will
* be returned for the empty string after that delimeter. That is, splitting <tt>"a,b,"</tt> on
* comma will return <tt>"a", "b"</tt>, not <tt>"a", "b", ""</tt>.
*/
public static class SimpleStringSplitter implements StringSplitter, Iterator<String> {
private String mString;
private char mDelimiter;
private int mPosition;
private int mLength;
/**
* Initializes the splitter. setString may be called later.
* @param delimiter the delimeter on which to split
*/
public SimpleStringSplitter(char delimiter) {
mDelimiter = delimiter;
}
/**
* Sets the string to split
* @param string the string to split
*/
public void setString(String string) {
mString = string;
mPosition = 0;
mLength = mString.length();
}
public Iterator<String> iterator() {
return this;
}
public boolean hasNext() {
return mPosition < mLength;
}
public String next() {
int end = mString.indexOf(mDelimiter, mPosition);
if (end == -1) {
end = mLength;
}
String nextString = mString.substring(mPosition, end);
mPosition = end + 1; // Skip the delimiter.
return nextString;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}

View file

@ -1,5 +1,5 @@
package android.text.style;
public class BackgroundColorSpan {
public class BackgroundColorSpan extends CharacterStyle {
public BackgroundColorSpan(int color) {}
}

View file

@ -1,4 +1,4 @@
package android.text.style;
public class UnderlineSpan {
public class UnderlineSpan extends CharacterStyle {
}

View file

@ -398,6 +398,23 @@ public class TypedValue {
return res;
}
public int getComplexUnit() {
return (data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK;
}
/**
* Return the complex unit type for the given complex dimension. For example, a dimen type
* with value 12sp will return {@link #COMPLEX_UNIT_SP}. Use with values created with {@link
* #createComplexDimension(int, int)} etc.
*
* @return The complex unit type.
*
* @hide
*/
public static int getUnitFromComplexDimension(int complexDimension) {
return COMPLEX_UNIT_MASK & (complexDimension >> TypedValue.COMPLEX_UNIT_SHIFT);
}
/**
* Converts an unpacked complex data value holding a dimension to its final floating
* point value. The two parameters <var>unit</var> and <var>value</var>
@ -572,8 +589,4 @@ public class TypedValue {
sb.append("}");
return sb.toString();
}
public int getComplexUnit() {
return (data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK;
}
};

View file

@ -60,7 +60,7 @@ public class LayoutInflater {
return mFactory;
}
public final void setFactory(LayoutInflater.Factory factory){
public void setFactory(LayoutInflater.Factory factory){
mFactory = factory;
}

View file

@ -1075,13 +1075,22 @@ public class View implements Drawable.Callback {
}
private OnTouchListener on_touch_listener = null;
public boolean onTouchEvent(MotionEvent event) {
public boolean onTouchEventInternal(MotionEvent event) {
boolean handled = false;
if (on_touch_listener != null)
handled = on_touch_listener.onTouch(this, event);
if (!handled)
handled = onTouchEvent(event);
return handled;
}
public boolean onTouchEvent(MotionEvent event) {
return false;
}
public void setOnTouchListener(OnTouchListener l) {
nativeSetOnTouchListener(widget);
on_touch_listener = l;
@ -1206,12 +1215,21 @@ public class View implements Drawable.Callback {
public native void setBackgroundColor(int color);
public native void native_setVisibility(long widget, int visibility, float alpha);
protected void onVisibilityChanged(View changedView, int visibility) {
}
protected void dispatchVisibilityChanged(View changedView, int visibility) {
onVisibilityChanged(changedView, visibility);
}
public void setVisibility(int visibility) {
native_setVisibility(widget, visibility, alpha);
if ((visibility == View.GONE) != (this.visibility == View.GONE)) {
requestLayout();
}
this.visibility = visibility;
dispatchVisibilityChanged(this, visibility);
}
public void setPadding(int left, int top, int right, int bottom) {

View file

@ -61,6 +61,10 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
addView(child, params);
}
public void addView(View child, int index, LayoutParams params) {
addViewInternal(child, index, params);
}
protected void addViewInternal(View child, int index, LayoutParams params) {
if (child.parent == this)
return;
@ -81,10 +85,13 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
requestLayout();
}
public void addView(View child, int index, LayoutParams params) {
addViewInternal(child, index, params);
/* We never call this ourselves */
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
return native_dispatchTouchEvent(widget, event, event.getX(), event.getY());
}
protected boolean addViewInLayout(View child, int index, LayoutParams params) {
addViewInternal(child, index, params);
return true;
@ -169,6 +176,16 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
}
}
@Override
protected void dispatchVisibilityChanged(View changedView, int visibility) {
if (children == null) // happens if this gets called during super constructor
return;
for (View child: children) {
child.dispatchVisibilityChanged(changedView, visibility);
}
}
protected native void native_addView(long widget, long child, int index, LayoutParams params);
protected native void native_removeView(long widget, long child);
@Override
@ -636,4 +653,6 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
}
public void requestChildFocus(View child, View focused) {}
public native boolean native_dispatchTouchEvent(long widget, MotionEvent event, double x, double y);
}

View file

@ -10,6 +10,8 @@ import android.view.View;
public class PopupWindow {
int input_method_mode = 0;
public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
popover = native_constructor();
}
@ -41,23 +43,25 @@ public class PopupWindow {
public void onDismiss();
}
protected native long native_constructor();
protected native void native_setContentView(long widget, long contentView);
protected native void native_showAsDropDown(long widget, long anchor, int xoff, int yoff, int gravity);
protected native boolean native_isShowing(long widget);
protected native void native_dismiss(long widget);
protected native void native_update(long widget, long anchor, int xoff, int yoff, int width, int height);
public void setBackgroundDrawable(Drawable background) {
/* FIXME: use a decorview? */
if(contentView != null) {
contentView.setBackgroundDrawable(background);
}
}
public void setBackgroundDrawable(Drawable background) {}
public void setInputMethodMode(int mode) {
input_method_mode = mode;
}
public void setInputMethodMode(int mode) {}
public int getInputMethodMode() {
return input_method_mode;
}
public boolean isShowing() {
return native_isShowing(popover);
}
public native void setOnDismissListener(OnDismissListener listener);
public void setFocusable(boolean focusable) {}
public Drawable getBackground() {return null;}
@ -70,17 +74,16 @@ public class PopupWindow {
native_setContentView(popover, view == null ? 0 : view.widget);
}
public int getInputMethodMode() {return 0;}
public int getMaxAvailableHeight(View anchor, int yOffset) {return 500;}
public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreKeyboard) {return 500;}
public native void setWidth(int width);
public native void setHeight(int height);
public void setOutsideTouchable(boolean touchable) {}
public void setOutsideTouchable(boolean touchable) {
/* FIXME: the semantics are different, this seems to specifically exist for cases
* where the popup is *not* modal, so that in addition to the window behind getting
* the real event, the popup gets a special MotionEvent.ACTION_OUTSIDE event */
native_setTouchModal(popover, touchable);
}
public void setTouchInterceptor(View.OnTouchListener listener) {}
@ -88,9 +91,13 @@ public class PopupWindow {
native_showAsDropDown(popover, anchor.widget, xoff, yoff, gravity);
}
public View getContentView() {return contentView;}
public View getContentView() {
return contentView;
}
public void setTouchable(boolean touchable) {}
public void setTouchable(boolean touchable) {
native_setTouchable(popover, touchable);
}
public void showAsDropDown(View anchor, int xoff, int yoff) {
if (!anchor.isAttachedToWindow()) {
@ -110,7 +117,9 @@ public class PopupWindow {
public void setAnimationStyle(int animationStyle) {}
public void setTouchModal(boolean touchModal) {}
public void setTouchModal(boolean touchModal) {
native_setTouchModal(popover, touchModal);
}
public void setElevation(float elevation) {}
@ -123,4 +132,53 @@ public class PopupWindow {
public void setIsClippedToScreen(boolean isClippedToScreen) {}
public void setEpicenterBounds(Rect bounds) {}
public void setClippingEnabled(boolean enabled) {}
/* TODO: handle LayoutParams.WRAP_CONTENT and LayoutParams.MATCH_PARENT */
public void setWidth(int width) {
if(width < 0)
return;
native_setWidth(popover, width);
}
public void setHeight(int height) {
if(height < 0)
return;
native_setHeight(popover, height);
}
public int getWidth() {
return native_getWidth(popover);
}
public int getHeight() {
return native_getHeight(popover);
}
public void update(int x, int y, int width, int height) {}
public void setWindowLayoutMode(int widthSpec, int heightSpec) {}
public boolean isTouchable() {
return native_isTouchable(popover);
}
protected native long native_constructor();
protected native void native_setContentView(long widget, long contentView);
protected native void native_showAsDropDown(long widget, long anchor, int xoff, int yoff, int gravity);
protected native boolean native_isShowing(long widget);
protected native void native_setTouchable(long widget, boolean touchable);
protected native void native_setTouchModal(long widget, boolean touchable);
protected native void native_dismiss(long widget);
protected native void native_update(long widget, long anchor, int xoff, int yoff, int width, int height);
public native void setOnDismissListener(OnDismissListener listener);
public native void native_setWidth(long widget, int width);
public native void native_setHeight(long widget, int height);
public native int native_getWidth(long widget);
public native int native_getHeight(long widget);
public native boolean native_isTouchable(long widget);
}

View file

@ -87,7 +87,15 @@ public class TextView extends View {
@Override
protected native long native_constructor(Context context, AttributeSet attrs);
public void setText(int resId) {
setText(getContext().getResources().getText(resId));
}
public void setText(CharSequence text) {
setText(text, null);
}
public void setText(CharSequence text, BufferType type) {
this.text = text;
native_setText(text != null ? text.toString() : null);
@ -97,10 +105,6 @@ public class TextView extends View {
requestLayout();
}
public void setText(int resId) {
setText(getContext().getResources().getText(resId));
}
private native final void native_set_markup(int bool);
public native final void native_setText(String text);
@ -264,10 +268,6 @@ public class TextView extends View {
public void setTextIsSelectable(boolean selectable) {}
public void setText(CharSequence text, BufferType type) {
setText(text);
}
public MovementMethod getMovementMethod() {
return new BaseMovementMethod();
}
@ -368,6 +368,10 @@ public class TextView extends View {
return 10; // FIXME
}
public int getMaxHeight() {
return -1;
}
public boolean isAllCaps() { return false; }
public int getAutoSizeStepGranularity() {

View file

@ -9,6 +9,7 @@ srcs = [
'android/animation/AnimatorListenerAdapter.java',
'android/animation/AnimatorSet.java',
'android/animation/ArgbEvaluator.java',
'android/animation/FloatEvaluator.java',
'android/animation/LayoutTransition.java',
'android/animation/ObjectAnimator.java',
'android/animation/PropertyValuesHolder.java',
@ -59,6 +60,8 @@ srcs = [
'android/app/UiModeManager.java',
'android/app/WallpaperManager.java',
'android/app/admin/DevicePolicyManager.java',
'android/app/backup/BackupAgentHelper.java',
'android/app/backup/BackupManager.java',
'android/app/job/JobInfo.java',
'android/app/job/JobScheduler.java',
'android/app/job/JobService.java',
@ -226,6 +229,7 @@ srcs = [
'android/graphics/drawable/Animatable.java',
'android/graphics/drawable/AnimationDrawable.java',
'android/graphics/drawable/BitmapDrawable.java',
'android/graphics/drawable/ClipDrawable.java',
'android/graphics/drawable/ColorDrawable.java',
'android/graphics/drawable/ColorStateListDrawable.java',
'android/graphics/drawable/Drawable.java',
@ -246,6 +250,7 @@ srcs = [
'android/graphics/drawable/shapes/RoundRectShape.java',
'android/graphics/drawable/shapes/Shape.java',
'android/hardware/ConsumerIrManager.java',
'android/hardware/GeomagneticField.java',
'android/hardware/Sensor.java',
'android/hardware/SensorEvent.java',
'android/hardware/SensorEventListener.java',
@ -255,6 +260,7 @@ srcs = [
'android/hardware/input/InputManager.java',
'android/hardware/usb/UsbManager.java',
'android/location/Criteria.java',
'android/location/GnssStatus.java',
'android/location/Location.java',
'android/location/LocationListener.java',
'android/location/LocationManager.java',
@ -282,6 +288,7 @@ srcs = [
'android/media/tv/TvInputManager.java',
'android/net/ConnectivityManager.java',
'android/net/Network.java',
'android/net/NetworkCapabilities.java',
'android/net/NetworkInfo.java',
'android/net/NetworkRequest.java',
'android/net/SSLCertificateSocketFactory.java',
@ -357,8 +364,10 @@ srcs = [
'android/provider/ContactsContract.java',
'android/provider/MediaStore.java',
'android/provider/Settings.java',
'android/provider/UserDictionary.java',
'android/security/keystore/AndroidKeyStore.java',
'android/service/media/MediaBrowserService.java',
'android/speech/tts/TextToSpeech.java',
'android/telecom/ConnectionService.java',
'android/telecom/TelecomManager.java',
'android/telephony/CellLocation.java',
@ -366,6 +375,7 @@ srcs = [
'android/telephony/PhoneStateListener.java',
'android/telephony/SubscriptionManager.java',
'android/telephony/TelephonyManager.java',
'android/text/AutoText.java',
'android/text/BoringLayout.java',
'android/text/ClipboardManager.java',
'android/text/Editable.java',