From 55a1ff2cc5f9a21cc390e9c9f5a3989e8e1dd800 Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Wed, 13 Sep 2023 21:34:24 +0200 Subject: [PATCH] create ContentProvider from AndroidManifest.xml This is required for androidx startup library. Only onCreate method is called for now. --- .../android/content/ContentProvider.java | 31 +++++++++++++++++++ src/api-impl/android/content/Context.java | 2 +- .../android/content/pm/PackageManager.java | 27 +++++++++++++++- src/api-impl/meson.build | 1 + src/main-executable/main.c | 5 +++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/api-impl/android/content/ContentProvider.java diff --git a/src/api-impl/android/content/ContentProvider.java b/src/api-impl/android/content/ContentProvider.java new file mode 100644 index 00000000..232208eb --- /dev/null +++ b/src/api-impl/android/content/ContentProvider.java @@ -0,0 +1,31 @@ +package android.content; + +import java.util.List; + +import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; +import com.reandroid.arsc.chunk.xml.ResXmlElement; + +public class ContentProvider { + + static void createContentProviders() throws ReflectiveOperationException { + List providers = Context.manifest.getApplicationElement().listElements(AndroidManifestBlock.TAG_provider); + System.out.println(providers); + for (ResXmlElement providerElement : providers) { + String providerName = providerElement.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(); + if (providerName.startsWith(".")) { + providerName = Context.manifest.getPackageName() + providerName; + } + System.out.println("creating " + providerName); + Class providerCls = Class.forName(providerName).asSubclass(ContentProvider.class); + ContentProvider provider = providerCls.getConstructor().newInstance(); + provider.onCreate(); + } + } + + public boolean onCreate() {return false;} + + public Context getContext() { + return Context.this_application; + } + +} diff --git a/src/api-impl/android/content/Context.java b/src/api-impl/android/content/Context.java index f58e9c38..8ac2f0d5 100644 --- a/src/api-impl/android/content/Context.java +++ b/src/api-impl/android/content/Context.java @@ -54,7 +54,7 @@ public class Context extends Object { public static final String DISPLAY_SERVICE = "display"; public static final String MEDIA_ROUTER_SERVICE = "media_router"; public static final String WINDOW_SERVICE = "window"; - private static AndroidManifestBlock manifest = null; + public static AndroidManifestBlock manifest = null; static AssetManager assets; static DisplayMetrics dm; diff --git a/src/api-impl/android/content/pm/PackageManager.java b/src/api-impl/android/content/pm/PackageManager.java index 28a99d0d..8263cd73 100644 --- a/src/api-impl/android/content/pm/PackageManager.java +++ b/src/api-impl/android/content/pm/PackageManager.java @@ -27,6 +27,7 @@ import android.content.res.Resources; import android.content.res.XmlResourceParser; // import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Bundle; import android.os.Environment; import android.os.UserHandle; import android.util.AndroidException; @@ -35,6 +36,9 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; +import com.reandroid.arsc.chunk.xml.ResXmlElement; + class IPackageInstallObserver {} class VerificationParams {} class ContainerEncryptionParams {} @@ -1690,7 +1694,28 @@ public class PackageManager { */ public ProviderInfo getProviderInfo(ComponentName component, int flags) throws NameNotFoundException { - return null; + ProviderInfo providerInfo = new ProviderInfo(); + if ((flags & GET_META_DATA) == GET_META_DATA) { + String cls = component.getClassName(); + List providers = Context.manifest.getApplicationElement().listElements(AndroidManifestBlock.TAG_provider); + for (ResXmlElement providerElement : providers) { + String providerName = providerElement.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(); + if (providerName.startsWith(".")) { + providerName = Context.manifest.getPackageName() + providerName; + } + if (providerName.equals(cls)) { + List metaDatas = providerElement.listElements(AndroidManifestBlock.TAG_meta_data); + Bundle bundle = new Bundle(metaDatas.size()); + for (ResXmlElement metaData : metaDatas) { + bundle.putString(metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(), + metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_value).getValueAsString()); + } + providerInfo.metaData = bundle; + break; + } + } + } + return providerInfo; } /** diff --git a/src/api-impl/meson.build b/src/api-impl/meson.build index d7f6bb21..8ee8bced 100644 --- a/src/api-impl/meson.build +++ b/src/api-impl/meson.build @@ -51,6 +51,7 @@ hax_jar = jar('hax', [ 'android/content/ComponentCallbacks.java', 'android/content/ComponentCallbacks2.java', 'android/content/ComponentName.java', + 'android/content/ContentProvider.java', 'android/content/ContentResolver.java', 'android/content/ContentValues.java', 'android/content/Context.java', diff --git a/src/main-executable/main.c b/src/main-executable/main.c index 6df8f27c..ea779d33 100644 --- a/src/main-executable/main.c +++ b/src/main-executable/main.c @@ -357,6 +357,11 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h prepare_main_looper(env); + jclass content_provider = (*env)->FindClass(env, "android/content/ContentProvider"); + (*env)->CallStaticObjectMethod(env, content_provider, _STATIC_METHOD(content_provider, "createContentProviders", "()V")); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); + (*env)->CallVoidMethod(env, application_object, _METHOD(handle_cache.application.class, "onCreate", "()V")); if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env);