2022-10-02 23:06:56 +02:00
|
|
|
package android.content;
|
|
|
|
|
2023-09-19 23:09:58 +02:00
|
|
|
import android.app.Activity;
|
2023-06-22 11:45:46 +02:00
|
|
|
import android.app.ActivityManager;
|
|
|
|
import android.app.AlarmManager;
|
|
|
|
import android.app.Application;
|
|
|
|
import android.app.KeyguardManager;
|
|
|
|
import android.app.NotificationManager;
|
2023-09-19 23:11:56 +02:00
|
|
|
import android.app.Service;
|
2023-06-22 11:45:46 +02:00
|
|
|
import android.app.SharedPreferencesImpl;
|
2023-08-17 10:46:24 +02:00
|
|
|
import android.app.UiModeManager;
|
2022-10-26 18:39:04 +02:00
|
|
|
import android.content.pm.ApplicationInfo;
|
2023-06-22 11:45:46 +02:00
|
|
|
import android.content.pm.PackageManager;
|
2022-10-02 23:06:56 +02:00
|
|
|
import android.content.res.AssetManager;
|
|
|
|
import android.content.res.Configuration;
|
|
|
|
import android.content.res.Resources;
|
|
|
|
import android.content.res.TypedArray;
|
2023-09-12 23:18:47 +02:00
|
|
|
import android.graphics.drawable.Drawable;
|
2023-07-25 14:29:43 +02:00
|
|
|
import android.hardware.input.InputManager;
|
2023-06-22 11:45:46 +02:00
|
|
|
import android.hardware.SensorManager;
|
|
|
|
import android.hardware.display.DisplayManager;
|
|
|
|
import android.hardware.usb.UsbManager;
|
2023-07-14 20:02:34 +02:00
|
|
|
import android.location.LocationManager;
|
2023-06-22 11:45:46 +02:00
|
|
|
import android.media.AudioManager;
|
|
|
|
import android.media.MediaRouter;
|
|
|
|
import android.net.ConnectivityManager;
|
2024-03-16 12:49:28 +01:00
|
|
|
import android.net.Uri;
|
|
|
|
import android.net.wifi.WifiManager;
|
|
|
|
import android.os.Environment;
|
|
|
|
import android.os.Handler;
|
2022-10-02 23:06:56 +02:00
|
|
|
import android.os.Looper;
|
2022-11-24 16:05:38 +01:00
|
|
|
import android.os.PowerManager;
|
2023-06-22 11:45:46 +02:00
|
|
|
import android.os.Vibrator;
|
|
|
|
import android.telephony.TelephonyManager;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.DisplayMetrics;
|
2023-09-06 17:42:24 +02:00
|
|
|
import android.util.Slog;
|
2024-02-04 08:08:49 +01:00
|
|
|
import android.view.LayoutInflater;
|
2022-10-02 23:06:56 +02:00
|
|
|
import android.view.WindowManagerImpl;
|
2023-09-01 12:55:04 +02:00
|
|
|
import android.view.accessibility.AccessibilityManager;
|
|
|
|
import android.view.inputmethod.InputMethodManager;
|
|
|
|
|
2023-08-12 13:05:34 +02:00
|
|
|
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
2023-08-17 10:09:07 +02:00
|
|
|
import com.reandroid.arsc.chunk.xml.ResXmlAttribute;
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
2023-07-25 14:26:29 +02:00
|
|
|
import java.io.FileNotFoundException;
|
2022-10-02 23:06:56 +02:00
|
|
|
import java.io.FileOutputStream;
|
2023-08-12 13:05:34 +02:00
|
|
|
import java.io.InputStream;
|
2023-08-17 10:09:07 +02:00
|
|
|
import java.lang.reflect.Constructor;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
2023-09-19 23:11:56 +02:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
2023-08-12 13:05:34 +02:00
|
|
|
import java.io.IOException;
|
2022-10-02 23:06:56 +02:00
|
|
|
|
|
|
|
public class Context extends Object {
|
2022-11-04 19:21:45 +01:00
|
|
|
private final static String TAG = "Context";
|
2022-10-02 23:06:56 +02:00
|
|
|
|
2022-12-27 17:21:21 +01:00
|
|
|
public static final int MODE_PRIVATE = 0;
|
|
|
|
public static final String LOCATION_SERVICE = "location";
|
|
|
|
public static final String AUDIO_SERVICE = "audio";
|
|
|
|
public static final String DISPLAY_SERVICE = "display";
|
|
|
|
public static final String MEDIA_ROUTER_SERVICE = "media_router";
|
2023-08-12 13:05:34 +02:00
|
|
|
public static final String WINDOW_SERVICE = "window";
|
2024-03-16 17:11:11 +00:00
|
|
|
public static final String INPUT_METHOD_SERVICE = "input";
|
2023-09-13 21:34:24 +02:00
|
|
|
public static AndroidManifestBlock manifest = null;
|
2022-12-27 17:21:21 +01:00
|
|
|
|
2024-03-22 14:04:04 +01:00
|
|
|
public static Vibrator vibrator;
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
static AssetManager assets;
|
|
|
|
static DisplayMetrics dm;
|
|
|
|
static Resources r;
|
2022-11-24 23:10:27 +01:00
|
|
|
static ApplicationInfo application_info;
|
2023-08-17 10:00:50 +02:00
|
|
|
static Resources.Theme theme;
|
2023-09-19 23:11:56 +02:00
|
|
|
private static Map<Class<? extends Service>,Service> runningServices = new HashMap<>();
|
2022-10-02 23:06:56 +02:00
|
|
|
|
2022-11-24 16:05:38 +01:00
|
|
|
static String apk_path = "/tmp/APK_PATH_SHOULD_HAVE_BEEN_FILLED_IN_BY_CODE_IN_main.c/";
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
public /*← FIXME?*/ static Application this_application;
|
|
|
|
|
|
|
|
File data_dir = null;
|
|
|
|
File prefs_dir = null;
|
|
|
|
File files_dir = null;
|
2022-11-04 19:21:45 +01:00
|
|
|
File obb_dir = null;
|
2022-10-02 23:06:56 +02:00
|
|
|
File cache_dir = null;
|
|
|
|
|
2024-03-17 11:05:42 +01:00
|
|
|
private static Map<IntentFilter, BroadcastReceiver> receiverMap = new HashMap<IntentFilter, BroadcastReceiver>();
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
static {
|
|
|
|
assets = new AssetManager();
|
|
|
|
dm = new DisplayMetrics();
|
2024-03-10 12:05:33 +01:00
|
|
|
Configuration config = new Configuration();
|
|
|
|
native_updateConfig(config);
|
2022-10-02 23:06:56 +02:00
|
|
|
r = new Resources(assets, dm, config);
|
2023-08-17 10:00:50 +02:00
|
|
|
theme = r.newTheme();
|
2022-11-24 23:10:27 +01:00
|
|
|
application_info = new ApplicationInfo();
|
2024-03-16 12:49:28 +01:00
|
|
|
application_info.dataDir = Environment.getExternalStorageDirectory().getAbsolutePath();
|
2023-08-12 13:05:34 +02:00
|
|
|
InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml");
|
|
|
|
try {
|
|
|
|
manifest = AndroidManifestBlock.load(inStream);
|
2023-11-04 17:47:43 +01:00
|
|
|
Integer targetSdkVersion = manifest.getTargetSdkVersion();
|
|
|
|
if (targetSdkVersion != null)
|
|
|
|
application_info.targetSdkVersion = targetSdkVersion;
|
2023-08-12 13:05:34 +02:00
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
2024-03-10 12:05:33 +01:00
|
|
|
protected static native void native_updateConfig(Configuration config);
|
|
|
|
|
2023-09-19 23:09:58 +02:00
|
|
|
static Application createApplication(long native_window) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException {
|
2023-08-17 10:09:07 +02:00
|
|
|
Application application;
|
|
|
|
ResXmlAttribute application_name = manifest.getApplicationElement().searchAttributeByResourceId(AndroidManifestBlock.ID_name);
|
|
|
|
String className = (application_name != null) ? application_name.getValueAsString() : "android.app.Application";
|
2024-03-07 15:44:21 +01:00
|
|
|
if(className.indexOf('.') == -1)
|
|
|
|
className = "." + className;
|
|
|
|
if (className.startsWith("."))
|
2023-08-17 10:09:07 +02:00
|
|
|
className = manifest.getPackageName() + className;
|
|
|
|
Class<? extends Application> cls = Class.forName(className).asSubclass(Application.class);
|
|
|
|
Constructor<? extends Application> constructor = cls.getConstructor();
|
|
|
|
application = constructor.newInstance();
|
2023-08-22 13:27:28 +02:00
|
|
|
ResXmlAttribute application_theme = manifest.getApplicationElement().searchAttributeByResourceId(AndroidManifestBlock.ID_theme);
|
|
|
|
if (application_theme != null)
|
|
|
|
application.setTheme(application_theme.getData());
|
2023-09-19 23:09:58 +02:00
|
|
|
application.native_window = native_window;
|
2023-08-17 10:09:07 +02:00
|
|
|
this_application = application;
|
|
|
|
return application;
|
|
|
|
}
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
public Context() {
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.v(TAG, "new Context! this one is: " + this);
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
2023-06-22 11:45:46 +02:00
|
|
|
public int checkPermission(String permission, int pid, int uid) {
|
2022-12-27 17:21:21 +01:00
|
|
|
return getPackageManager().checkPermission(permission, "dummy");
|
|
|
|
}
|
|
|
|
|
2022-11-24 23:10:27 +01:00
|
|
|
public Resources.Theme getTheme() {
|
2023-08-17 10:00:50 +02:00
|
|
|
return theme;
|
2022-11-24 23:10:27 +01:00
|
|
|
}
|
|
|
|
|
2023-06-22 11:45:46 +02:00
|
|
|
public ApplicationInfo getApplicationInfo() {
|
2022-11-24 23:10:27 +01:00
|
|
|
// TODO: do this somewhere saner?
|
|
|
|
application_info.nativeLibraryDir = (new File(getDataDirFile(), "lib")).getAbsolutePath();
|
|
|
|
return application_info;
|
2022-10-26 18:39:04 +02:00
|
|
|
}
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
public Context getApplicationContext() {
|
|
|
|
return (Context)this_application;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ContentResolver getContentResolver() {
|
|
|
|
return new ContentResolver();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Object getSystemService(String name) {
|
|
|
|
switch (name) {
|
|
|
|
case "window":
|
|
|
|
return new WindowManagerImpl();
|
|
|
|
case "clipboard":
|
|
|
|
return new ClipboardManager();
|
|
|
|
case "sensor":
|
|
|
|
return new SensorManager();
|
|
|
|
case "connectivity":
|
|
|
|
return new ConnectivityManager();
|
|
|
|
case "keyguard":
|
|
|
|
return new KeyguardManager();
|
|
|
|
case "phone":
|
|
|
|
return new TelephonyManager();
|
|
|
|
case "audio":
|
|
|
|
return new AudioManager();
|
|
|
|
case "activity":
|
|
|
|
return new ActivityManager();
|
2022-10-26 18:39:04 +02:00
|
|
|
case "usb":
|
|
|
|
return new UsbManager();
|
|
|
|
case "vibrator":
|
2024-03-22 14:04:04 +01:00
|
|
|
return (vibrator != null) ? vibrator : (vibrator = new Vibrator());
|
2022-11-24 16:05:38 +01:00
|
|
|
case "power":
|
|
|
|
return new PowerManager();
|
2022-12-27 17:21:21 +01:00
|
|
|
case "display":
|
|
|
|
return new DisplayManager();
|
2022-12-31 16:59:15 +01:00
|
|
|
case "media_router":
|
|
|
|
return new MediaRouter();
|
2023-01-14 14:32:37 +01:00
|
|
|
case "notification":
|
|
|
|
return new NotificationManager();
|
|
|
|
case "alarm":
|
|
|
|
return new AlarmManager();
|
2023-07-25 14:29:43 +02:00
|
|
|
case "input":
|
|
|
|
return new InputManager();
|
2023-07-14 20:02:34 +02:00
|
|
|
case "location":
|
|
|
|
return new LocationManager();
|
2023-08-17 10:46:24 +02:00
|
|
|
case "uimode":
|
|
|
|
return new UiModeManager();
|
2023-09-01 12:55:04 +02:00
|
|
|
case "input_method":
|
|
|
|
return new InputMethodManager();
|
|
|
|
case "accessibility":
|
|
|
|
return new AccessibilityManager();
|
2024-02-04 08:08:49 +01:00
|
|
|
case "layout_inflater":
|
|
|
|
return new LayoutInflater();
|
2024-03-16 12:49:28 +01:00
|
|
|
case "wifi":
|
|
|
|
return new WifiManager();
|
2022-10-02 23:06:56 +02:00
|
|
|
default:
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.e(TAG, "!!!!!!! getSystemService: case >" + name + "< is not implemented yet");
|
2022-10-02 23:06:56 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-26 18:39:04 +02:00
|
|
|
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
|
2024-03-17 11:05:42 +01:00
|
|
|
receiverMap.put(filter, receiver);
|
2022-10-26 18:39:04 +02:00
|
|
|
return new Intent();
|
|
|
|
}
|
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
public Looper getMainLooper() {
|
2023-07-25 14:26:29 +02:00
|
|
|
/* TODO: this is not what AOSP does, which could be a problem */
|
|
|
|
Looper looper = Looper.myLooper();
|
|
|
|
if(looper == null) {
|
|
|
|
Looper.prepare();
|
|
|
|
looper = Looper.myLooper();
|
|
|
|
}
|
|
|
|
|
|
|
|
return looper;
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public String getPackageName() {
|
2023-08-12 13:05:34 +02:00
|
|
|
return manifest.getPackageName();
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
2022-11-24 16:05:38 +01:00
|
|
|
public String getPackageCodePath() {
|
|
|
|
return apk_path;
|
|
|
|
}
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
public final String getString(int resId) {
|
|
|
|
return r.getString(resId);
|
|
|
|
}
|
|
|
|
|
2023-07-14 20:12:41 +02:00
|
|
|
public final String getString (int resId, Object... formatArgs) {
|
|
|
|
return r.getString(resId, formatArgs);
|
|
|
|
}
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
public PackageManager getPackageManager() {
|
|
|
|
return new PackageManager();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Resources getResources() {
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
public AssetManager getAssets() {
|
|
|
|
return assets;
|
|
|
|
}
|
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
private File makeFilename(File base, String name) {
|
|
|
|
if (name.indexOf(File.separatorChar) < 0) {
|
|
|
|
return new File(base, name);
|
|
|
|
}
|
|
|
|
throw new IllegalArgumentException(
|
2023-06-22 11:45:46 +02:00
|
|
|
"File " + name + " contains a path separator");
|
2022-11-04 19:21:45 +01:00
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
private File getDataDirFile() {
|
2023-06-22 11:45:46 +02:00
|
|
|
if (data_dir == null) {
|
2022-10-12 17:23:19 +02:00
|
|
|
data_dir = android.os.Environment.getExternalStorageDirectory();
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
return data_dir;
|
2022-11-04 19:21:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public File getFilesDir() {
|
|
|
|
if (files_dir == null) {
|
|
|
|
files_dir = new File(getDataDirFile(), "files");
|
|
|
|
}
|
|
|
|
if (!files_dir.exists()) {
|
2023-06-22 11:45:46 +02:00
|
|
|
if (!files_dir.mkdirs()) {
|
2022-11-04 19:21:45 +01:00
|
|
|
if (files_dir.exists()) {
|
|
|
|
// spurious failure; probably racing with another process for this app
|
|
|
|
return files_dir;
|
|
|
|
}
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.w(TAG, "Unable to create files directory " + files_dir.getPath());
|
2022-11-04 19:21:45 +01:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return files_dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
public File getExternalFilesDir(String type) {
|
|
|
|
return getFilesDir();
|
|
|
|
}
|
|
|
|
|
2023-09-18 14:12:38 +02:00
|
|
|
public File[] getExternalFilesDirs(String type) {
|
|
|
|
return new File[] {getExternalFilesDir(type)};
|
|
|
|
}
|
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
public File getObbDir() {
|
2023-06-22 11:45:46 +02:00
|
|
|
if (obb_dir == null) {
|
2023-09-18 13:54:12 +02:00
|
|
|
obb_dir = new File(getDataDirFile(), "Android/obb/" + getPackageName());
|
|
|
|
}
|
|
|
|
if (!obb_dir.exists()) {
|
|
|
|
if (!obb_dir.mkdirs()) {
|
|
|
|
if (obb_dir.exists()) {
|
|
|
|
// spurious failure; probably racing with another process for this app
|
|
|
|
return obb_dir;
|
|
|
|
}
|
|
|
|
Slog.w(TAG, "Unable to create obb directory >" + obb_dir.getPath() + "<");
|
|
|
|
return null;
|
|
|
|
}
|
2022-11-04 19:21:45 +01:00
|
|
|
}
|
|
|
|
return obb_dir;
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
2022-12-27 17:21:21 +01:00
|
|
|
public File[] getObbDirs() {
|
2023-06-22 11:45:46 +02:00
|
|
|
return new File[] {getObbDir()};
|
2022-12-27 17:21:21 +01:00
|
|
|
}
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
// FIXME: should be something like /tmp/cache, but may need to create that directory
|
|
|
|
public File getCacheDir() {
|
2023-06-22 11:45:46 +02:00
|
|
|
if (cache_dir == null) {
|
|
|
|
cache_dir = new File("/tmp/");
|
|
|
|
}
|
|
|
|
return cache_dir;
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
2023-06-22 14:40:09 +02:00
|
|
|
public File getExternalCacheDir() {
|
|
|
|
return getCacheDir();
|
|
|
|
}
|
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
private File getPreferencesDir() {
|
2023-06-22 11:45:46 +02:00
|
|
|
if (prefs_dir == null) {
|
|
|
|
prefs_dir = new File(getDataDirFile(), "shared_prefs");
|
|
|
|
}
|
|
|
|
return prefs_dir;
|
2022-11-04 19:21:45 +01:00
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
public File getSharedPrefsFile(String name) {
|
|
|
|
return makeFilename(getPreferencesDir(), name + ".xml");
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
2022-11-04 19:21:45 +01:00
|
|
|
public SharedPreferences getSharedPreferences(String name, int mode) {
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.v(TAG, "\n\n...> getSharedPreferences(" + name + ")\n\n");
|
2022-11-04 19:21:45 +01:00
|
|
|
File prefsFile = getSharedPrefsFile(name);
|
|
|
|
return new SharedPreferencesImpl(prefsFile, mode);
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
|
|
|
public ClassLoader getClassLoader() {
|
|
|
|
// not perfect, but it's what we use for now as well, and it works
|
|
|
|
return ClassLoader.getSystemClassLoader();
|
|
|
|
}
|
|
|
|
|
2023-09-19 23:11:56 +02:00
|
|
|
public ComponentName startService(Intent intent) {
|
|
|
|
ComponentName component = intent.getComponent();
|
2023-11-23 15:29:03 +01:00
|
|
|
if(component == null) {
|
|
|
|
Slog.w(TAG, "startService: component is null");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-09-19 23:11:56 +02:00
|
|
|
try {
|
|
|
|
Class<? extends Service> cls = Class.forName(component.getClassName()).asSubclass(Service.class);
|
|
|
|
if (!runningServices.containsKey(cls)) {
|
|
|
|
Service service = cls.getConstructor().newInstance();
|
|
|
|
service.onCreate();
|
|
|
|
runningServices.put(cls, service);
|
|
|
|
}
|
|
|
|
runningServices.get(cls).onStartCommand(intent, 0, 0);
|
|
|
|
} catch (ReflectiveOperationException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
return component;
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
2023-07-25 14:26:29 +02:00
|
|
|
// TODO: do these both work? make them look more alike
|
|
|
|
public FileInputStream openFileInput(String name) throws FileNotFoundException {
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.v(TAG, "openFileInput called for: '" + name + "'");
|
2023-07-25 14:26:29 +02:00
|
|
|
File file = new File(getFilesDir(), name);
|
|
|
|
|
|
|
|
return new FileInputStream(file);
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public FileOutputStream openFileOutput(String name, int mode) throws java.io.FileNotFoundException {
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.v(TAG, "openFileOutput called for: '" + name + "'");
|
2022-10-12 17:23:19 +02:00
|
|
|
return new FileOutputStream(android.os.Environment.getExternalStorageDirectory().getPath() + "/files/" + name);
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public int checkCallingOrSelfPermission(String permission) {
|
2023-09-06 17:42:24 +02:00
|
|
|
Slog.w(TAG, "!!! app wants to know if it has a permission: >" + permission + "< (returning PREMISSION_DENIED)");
|
2022-10-02 23:06:56 +02:00
|
|
|
|
|
|
|
return -1; // PackageManager.PERMISSION_DENIED
|
|
|
|
}
|
|
|
|
|
2023-01-14 14:32:37 +01:00
|
|
|
public void registerComponentCallbacks(ComponentCallbacks callbacks) {}
|
|
|
|
|
2024-03-16 12:49:28 +01:00
|
|
|
public boolean bindService(final Intent intent, final ServiceConnection serviceConnection, int dummy3) {
|
|
|
|
if(intent.getComponent() == null) {
|
|
|
|
Slog.w(TAG, "Context.bindService: intent.getComponent() is null");
|
|
|
|
return false;
|
|
|
|
}
|
2023-10-17 21:33:59 +02:00
|
|
|
|
2024-03-16 12:49:28 +01:00
|
|
|
new Handler().post(new Runnable() { // run this asynchron so the caller can finish its setup before onServiceConnected is called
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
try {
|
|
|
|
Class<? extends Service> cls = Class.forName(intent.getComponent().getClassName()).asSubclass(Service.class);
|
|
|
|
if (!runningServices.containsKey(cls)) {
|
|
|
|
Service service = cls.getConstructor().newInstance();
|
|
|
|
service.onCreate();
|
|
|
|
runningServices.put(cls, service);
|
|
|
|
}
|
|
|
|
serviceConnection.onServiceConnected(intent.getComponent(), runningServices.get(cls).onBind(intent));
|
|
|
|
} catch (ReflectiveOperationException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2023-09-19 23:11:56 +02:00
|
|
|
}
|
2024-03-16 12:49:28 +01:00
|
|
|
});
|
|
|
|
return true;
|
2023-08-12 13:05:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void startActivity(Intent intent) {
|
2023-09-19 23:09:58 +02:00
|
|
|
Slog.i(TAG, "startActivity(" + intent + ") called");
|
2024-02-10 20:37:28 +01:00
|
|
|
if (intent.getAction() != null && intent.getAction().equals("android.intent.action.CHOOSER")) {
|
2023-09-19 23:09:58 +02:00
|
|
|
intent = (Intent) intent.getExtras().get("android.intent.extra.INTENT");
|
|
|
|
}
|
|
|
|
if (intent.getComponent() == null) {
|
2024-02-10 20:37:28 +01:00
|
|
|
if(intent.getAction() != null && intent.getAction().equals("android.intent.action.SEND")) {
|
|
|
|
Slog.i(TAG, "starting extern activity with intent: " + intent);
|
2024-03-20 23:05:17 +01:00
|
|
|
String text = intent.getStringExtra("android.intent.extra.TEXT");
|
|
|
|
if (text == null)
|
|
|
|
text = String.valueOf(intent.getExtras().get("android.intent.extra.STREAM"));
|
|
|
|
if (text != null)
|
|
|
|
ClipboardManager.native_set_clipboard(text);
|
2024-02-10 20:37:28 +01:00
|
|
|
} else if (intent.getData() != null) {
|
|
|
|
Slog.i(TAG, "starting extern activity with intent: " + intent);
|
|
|
|
Activity.nativeOpenURI(String.valueOf(intent.getData()));
|
|
|
|
}
|
2023-09-19 23:09:58 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
Class<? extends Activity> cls = Class.forName(intent.getComponent().getClassName()).asSubclass(Activity.class);
|
|
|
|
Constructor<? extends Activity> constructor = cls.getConstructor();
|
|
|
|
Activity activity = constructor.newInstance();
|
|
|
|
activity.intent = intent;
|
|
|
|
activity.getWindow().native_window = this_application.native_window;
|
|
|
|
Activity.nativeStartActivity(activity);
|
|
|
|
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2023-08-12 13:05:34 +02:00
|
|
|
}
|
|
|
|
|
2023-08-17 10:00:50 +02:00
|
|
|
public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
|
|
|
|
return getTheme().obtainStyledAttributes(set, attrs, 0, 0);
|
|
|
|
}
|
|
|
|
public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
|
|
|
|
return getTheme().obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes);
|
|
|
|
}
|
|
|
|
public final TypedArray obtainStyledAttributes(int resid, int[] attrs) {
|
|
|
|
return getTheme().obtainStyledAttributes(resid, attrs);
|
|
|
|
}
|
|
|
|
public final TypedArray obtainStyledAttributes(int[] attrs) {
|
|
|
|
return getTheme().obtainStyledAttributes(attrs);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setTheme(int resId) {
|
|
|
|
theme.applyStyle(resId, true);
|
|
|
|
}
|
2023-08-17 10:46:24 +02:00
|
|
|
|
|
|
|
public final CharSequence getText(int resId) {
|
|
|
|
return getResources().getText(resId);
|
|
|
|
}
|
2023-08-22 14:41:01 +02:00
|
|
|
|
2023-09-12 23:18:47 +02:00
|
|
|
public final Drawable getDrawable(int resId) {
|
|
|
|
return getResources().getDrawable(resId);
|
|
|
|
}
|
|
|
|
|
2023-08-22 14:41:01 +02:00
|
|
|
public boolean isRestricted() {return false;}
|
2023-08-24 12:43:13 +02:00
|
|
|
|
|
|
|
public File getDatabasePath(String dbName) {
|
|
|
|
File databaseDir = new File(getDataDirFile(), "databases");
|
|
|
|
if (!databaseDir.exists())
|
|
|
|
databaseDir.mkdirs();
|
|
|
|
return new File(databaseDir, dbName);
|
|
|
|
}
|
2023-09-01 12:55:04 +02:00
|
|
|
|
2024-03-17 11:05:42 +01:00
|
|
|
public void sendBroadcast(Intent intent) {
|
|
|
|
for (IntentFilter filter : receiverMap.keySet()) {
|
|
|
|
if (filter.matchAction(intent.getAction())) {
|
|
|
|
receiverMap.get(filter).onReceive(this, intent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-01 12:55:04 +02:00
|
|
|
|
|
|
|
public boolean stopService(Intent intent) {return false;}
|
|
|
|
|
|
|
|
public void unbindService(ServiceConnection serviceConnection) {}
|
2023-09-19 23:11:56 +02:00
|
|
|
|
|
|
|
public void unregisterReceiver(BroadcastReceiver receiver) {}
|
2023-10-29 22:47:57 +01:00
|
|
|
|
|
|
|
public Context createPackageContext(String dummy, int dummy2) {
|
|
|
|
return this; // FIXME?
|
|
|
|
}
|
2024-03-16 12:49:28 +01:00
|
|
|
|
|
|
|
public void grantUriPermission(String dummy, Uri dummy2, int dummy3) {
|
|
|
|
System.out.println("grantUriPermission(" + dummy + ", " + dummy2 + ", " + dummy3 + ") called");
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
}
|