android_translation_layer/src/api-impl/android/app/Activity.java

575 lines
15 KiB
Java
Raw Normal View History

package android.app;
import android.R;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageParser;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Activity extends ContextThemeWrapper implements Window.Callback {
LayoutInflater layout_inflater;
Window window = new Window(this, this);
int requested_orientation = -1 /*ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED*/; // dummy
public Intent intent;
private Activity resultActivity;
private int resultRequestCode;
2024-03-05 17:07:21 +01:00
private boolean paused = false;
private CharSequence title = null;
List<Fragment> fragments = new ArrayList<>();
2024-06-13 21:00:06 +02:00
boolean destroyed = false;
/**
* Helper function to be called from native code to construct main activity
*
* @param className class name of activity or null
* @return instance of main activity class
* @throws Exception
*/
private static Activity createMainActivity(String className, long native_window, String uriString) throws Exception {
Uri uri = uriString != null ? Uri.parse(uriString) : null;
if (className == null) {
for (PackageParser.Activity activity: pkg.activities) {
for (PackageParser.IntentInfo intent: activity.intents) {
if ((uri == null && intent.hasCategory("android.intent.category.LAUNCHER")) ||
(uri != null && intent.hasDataScheme(uri.getScheme()))) {
className = activity.className;
break;
}
}
if (className != null)
break;
}
} else {
className = className.replace('/', '.');
}
if (className == null) {
System.err.println("Failed to find Activity to launch URI: " + uri);
System.exit(1);
}
Class<? extends Activity> cls = Class.forName(className).asSubclass(Activity.class);
Constructor<? extends Activity> constructor = cls.getConstructor();
Activity activity = constructor.newInstance();
activity.window.native_window = native_window;
if (uri != null)
activity.setIntent(new Intent("android.intent.action.VIEW", uri));
return activity;
}
public Activity() {
super(null);
layout_inflater = new LayoutInflater(this);
2023-08-11 18:09:17 +02:00
intent = new Intent();
CharSequence label = null;
CharSequence app_label = null;
int themeResId = 0;
for (PackageParser.Activity activity: pkg.activities) {
if (getClass().getName().equals(activity.className)) {
label = r.getText(activity.info.labelRes);
themeResId = activity.info.getThemeResource();
break;
}
}
app_label = r.getText(pkg.applicationInfo.labelRes);
if (label != null) {
setTitle(label);
} else if (app_label != null) {
setTitle(app_label);
}
attachBaseContext(new Context());
setTheme(themeResId);
}
public View root_view;
public final Application getApplication() {
return (Application)getApplicationContext();
}
public WindowManager getWindowManager() {
return new WindowManagerImpl();
}
2022-12-31 16:59:15 +01:00
public String getCallingPackage() {
return null; // [from api reference] Note: if the calling activity is not expecting a result (that is it did not use the startActivityForResult(Intent, int) form that includes a request code), then the calling package will be null.
}
public ComponentName getComponentName() {
return null;
}
public Intent getIntent() {
2023-08-11 18:09:17 +02:00
return intent;
}
public int getRequestedOrientation() {
return requested_orientation;
}
public void setRequestedOrientation(int orientation) {
requested_orientation = orientation;
}
public boolean isFinishing() {
return false; // FIXME
}
public final boolean requestWindowFeature(int featureId) {
return false; // whatever feature it is, it's probably not supported
}
public final void setVolumeControlStream(int streamType) {}
protected void onCreate(Bundle savedInstanceState) {
System.out.println("- onCreate - yay!");
new ViewGroup(this).setId(R.id.content);
for (Fragment fragment : fragments) {
fragment.onCreate(savedInstanceState);
}
return;
}
protected void onPostCreate(Bundle savedInstanceState) {
System.out.println("- onPostCreate - yay!");
return;
}
protected void onStart() {
System.out.println("- onStart - yay!");
if (window.contentView != null)
window.setContentView(window.contentView);
for (Fragment fragment : fragments) {
fragment.onStart();
}
TypedArray ta = obtainStyledAttributes(new int[] {R.attr.windowBackground});
Drawable background = ta.getDrawable(0);
if (background != null)
window.setBackgroundDrawable(background);
ta.recycle();
return;
}
protected void onRestart() {
System.out.println("- onRestart - yay!");
return;
}
protected void onResume() {
System.out.println("- onResume - yay!");
for (Fragment fragment : fragments) {
fragment.onResume();
}
2024-03-05 17:07:21 +01:00
paused = false;
return;
}
protected void onPostResume() {
System.out.println("- onPostResume - yay!");
return;
}
protected void onPause() {
System.out.println("- onPause - yay!");
for (Fragment fragment : fragments) {
fragment.onPause();
}
2024-03-05 17:07:21 +01:00
paused = true;
return;
}
protected void onStop() {
System.out.println("- onStop - yay!");
for (Fragment fragment : fragments) {
fragment.onStop();
}
return;
}
protected void onDestroy() {
System.out.println("- onDestroy - yay!");
for (Fragment fragment : fragments) {
fragment.onDestroy();
}
2024-06-13 21:00:06 +02:00
destroyed = true;
return;
}
public void onWindowFocusChanged(boolean hasFocus) {
System.out.println("- onWindowFocusChanged - yay! (hasFocus: " + hasFocus + ")");
return;
}
protected void onSaveInstanceState(Bundle outState) {
}
void onConfigurationChanged(Configuration newConfig) {
}
public void onLowMemory() {
}
/* --- */
public void setContentView(int layoutResID) throws Exception {
System.out.println("- setContentView - yay!");
root_view = layout_inflater.inflate(layoutResID, null, false);
System.out.println("~~~~~~~~~~~");
System.out.println(root_view);
System.out.printf("%x\n", root_view.id);
System.out.println("~~~~~~~~~~~");
setContentView(root_view);
}
public void setContentView(View view, ViewGroup.LayoutParams layoutParams) {
setContentView(view);
}
public void setContentView(View view) {
window.setContentView(view);
onContentChanged();
}
public <T extends android.view.View> T findViewById(int id) {
System.out.printf("- findViewById - asked for view with id: %x\n", id);
View view = null;
if (window.contentView != null)
view = window.contentView.findViewById(id);
System.out.println("- findViewById - found this: " + view);
return (T)view;
}
public void invalidateOptionsMenu() {
System.out.println("invalidateOptionsMenu() called, should we do something?");
}
public Window getWindow() {
return this.window;
}
public final void runOnUiThread(Runnable action) {
if(Looper.myLooper() == Looper.getMainLooper()) {
action.run();
} else {
new Handler(Looper.getMainLooper()).post(action);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {}
// the order must match GtkFileChooserAction enum
private static final List<String> FILE_CHOOSER_ACTIONS = Arrays.asList(
"android.intent.action.OPEN_DOCUMENT", // (0) GTK_FILE_CHOOSER_ACTION_OPEN
"android.intent.action.CREATE_DOCUMENT", // (1) GTK_FILE_CHOOSER_ACTION_SAVE
"android.intent.action.OPEN_DOCUMENT_TREE" // (2) GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
);
// callback from native code
protected void fileChooserResultCallback(int requestCode, int resultCode, int action, String uri) {
onActivityResult(requestCode, resultCode, new Intent(FILE_CHOOSER_ACTIONS.get(action), uri != null ? Uri.parse(uri) : null));
}
2024-03-16 12:49:28 +01:00
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
System.out.println("startActivityForResult(" + intent + ", " + requestCode + ") called");
2023-08-11 18:09:17 +02:00
if (intent.getComponent() != null) {
try {
Class<? extends Activity> cls = Class.forName(intent.getComponent().getClassName()).asSubclass(Activity.class);
Constructor<? extends Activity> constructor = cls.getConstructor();
2024-03-05 17:07:21 +01:00
final Activity activity = constructor.newInstance();
2023-08-11 18:09:17 +02:00
activity.intent = intent;
activity.getWindow().native_window = getWindow().native_window;
activity.resultRequestCode = requestCode;
activity.resultActivity = this;
2024-03-05 17:07:21 +01:00
runOnUiThread(new Runnable() {
@Override
public void run() {
nativeStartActivity(activity);
}
});
2023-08-11 18:09:17 +02:00
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
onActivityResult(requestCode, 0 /*RESULT_CANCELED*/, new Intent());
2023-08-11 18:09:17 +02:00
}
} else if (FILE_CHOOSER_ACTIONS.contains(intent.getAction())) {
nativeFileChooser(FILE_CHOOSER_ACTIONS.indexOf(intent.getAction()), intent.getType(), intent.getStringExtra("android.intent.extra.TITLE"), requestCode);
2023-08-11 18:09:17 +02:00
}
else {
2024-03-16 12:49:28 +01:00
System.out.println("startActivityForResult: intent was not handled. Calling onActivityResult(RESULT_CANCELED).");
onActivityResult(requestCode, 0 /*RESULT_CANCELED*/, new Intent());
2023-08-11 18:09:17 +02:00
}
}
2024-03-16 12:49:28 +01:00
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
2023-08-11 18:09:17 +02:00
public void setResult(int resultCode, Intent data) {
if (resultActivity != null) {
resultActivity.onActivityResult(resultRequestCode, resultCode, data);
}
}
public void setResult(int resultCode) {
setResult(resultCode, null);
}
protected Dialog onCreateDialog(int id) {
System.out.println("Activity.onCreateDialog(" + id + ") called");
return null;
}
protected void onPrepareDialog(int id, Dialog dialog) {
System.out.println("Activity.onPrepareDialog(" + id + ") called");
}
private Map<Integer, Dialog> dialogs = new HashMap<Integer, Dialog>();
public final void showDialog(int id) {
System.out.println("Activity.showDialog(" + id + ") called");
Dialog dialog = dialogs.get(id);
if (dialog == null)
dialogs.put(id, dialog = onCreateDialog(id));
onPrepareDialog(id, dialog);
dialog.show();
}
public void removeDialog(int id) {
Dialog dialog = dialogs.remove(id);
if (dialog != null)
dialog.dismiss();
}
2023-08-11 18:09:17 +02:00
public void finish() {
2024-03-05 17:07:21 +01:00
runOnUiThread(new Runnable() {
@Override
public void run() {
if (window != null) {
nativeFinish(getWindow().native_window);
window = null;
}
2024-03-05 17:07:21 +01:00
}
});
2023-08-11 18:09:17 +02:00
}
public Object getLastNonConfigurationInstance() {
return null;
}
public FragmentManager getFragmentManager() {
return new FragmentManager(this);
}
public LayoutInflater getLayoutInflater() {
return layout_inflater;
}
public boolean isChangingConfigurations() {return false;}
@Override
public void onContentChanged() {
System.out.println("- onContentChanged - yay!");
}
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
return onCreateOptionsMenu(menu);
}
return false;
}
@Override
public View onCreatePanelView(int featureId) {
return null;
}
public MenuInflater getMenuInflater() {
return new MenuInflater(this);
}
public boolean onPrepareOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
return onPrepareOptionsMenu(menu);
}
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
return onOptionsItemSelected(item);
}
return false;
}
public boolean onOptionsItemSelected(MenuItem item) {
return false;
}
public void onOptionsMenuClosed(Menu menu) {}
@Override
public void onPanelClosed(int featureId, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
onOptionsMenuClosed(menu);
}
}
public void setTitle(CharSequence title) {
this.title = title;
}
public void setTitle(int titleId) {
this.title = getText(titleId);
}
public CharSequence getTitle() {
return title;
}
public void onBackPressed() {
finish();
}
public void setIntent(Intent newIntent) {
this.intent = newIntent;
}
public void unregisterReceiver(BroadcastReceiver receiver) {}
public Intent getParentActivityIntent() {
return null;
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
System.out.println("onMenuOpened(" + featureId + ", " + menu + ") called");
return false;
}
2024-02-19 16:29:09 +01:00
public void recreate() {
try {
/* TODO: check if this is a toplevel activity */
Class<? extends Activity> cls = this.getClass();
Constructor<? extends Activity> constructor = cls.getConstructor();
Activity activity = constructor.newInstance();
activity.getWindow().native_window = getWindow().native_window;
System.out.println("activity.getWindow().native_window >"+activity.getWindow().native_window+"<");
nativeFinish(0);
nativeStartActivity(activity);
2024-02-19 16:29:09 +01:00
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
System.out.println("exception in Activity.recreate, this is kinda sus");
e.printStackTrace();
}
}
public String getLocalClassName() {
final String pkg = getPackageName();
final String cls = this.getClass().getName();
int packageLen = pkg.length();
if (!cls.startsWith(pkg) || cls.length() <= packageLen || cls.charAt(packageLen) != '.') {
return cls;
}
return cls.substring(packageLen+1);
}
public SharedPreferences getPreferences(int mode) {
return getSharedPreferences(getLocalClassName(), mode);
}
protected void onNewIntent(Intent intent) {}
public final Activity getParent() {
return null;
}
public boolean hasWindowFocus() {
return true; // FIXME?
}
2024-06-13 21:00:06 +02:00
public boolean isDestroyed() {
return destroyed;
}
public void finishAffinity() {
finish();
}
public void overridePendingTransition(int enterAnim, int exitAnim) {}
public boolean isTaskRoot() {
return false;
}
public void postponeEnterTransition() {}
public void startPostponedEnterTransition() {}
public boolean isChild() {
return false;
}
public void setTaskDescription(ActivityManager.TaskDescription description) {}
private native void nativeFinish(long native_window);
public static native void nativeStartActivity(Activity activity);
public static native void nativeOpenURI(String uri);
public native void nativeFileChooser(int action, String type, String title, int requestCode);
2024-10-12 14:53:30 +03:00
public void reportFullyDrawn() {}
public void setVisible(boolean visible) {}
public Uri getReferrer() { return null; }
}