2022-10-02 23:06:56 +02:00
package android.app ;
2023-08-17 10:46:24 +02:00
import android.R ;
2023-09-01 12:34:57 +02:00
import android.content.BroadcastReceiver ;
2022-10-02 23:06:56 +02:00
import android.content.ComponentName ;
2023-06-22 11:45:46 +02:00
import android.content.Context ;
2024-02-10 20:37:28 +01:00
import android.content.ContextWrapper ;
2022-10-02 23:06:56 +02:00
import android.content.Intent ;
2022-11-04 19:21:45 +01:00
import android.content.res.Configuration ;
2023-05-20 12:38:34 +02:00
import android.content.res.XmlResourceParser ;
2022-10-02 23:06:56 +02:00
import android.os.Bundle ;
2023-07-25 14:26:29 +02:00
import android.os.Handler ;
import android.os.Looper ;
2023-06-22 11:45:46 +02:00
import android.view.LayoutInflater ;
2023-09-01 12:34:57 +02:00
import android.view.Menu ;
import android.view.MenuInflater ;
import android.view.MenuItem ;
2022-10-02 23:06:56 +02:00
import android.view.View ;
2023-06-18 11:03:43 +02:00
import android.view.ViewGroup ;
2022-10-02 23:06:56 +02:00
import android.view.Window ;
import android.view.WindowManager ;
import android.view.WindowManagerImpl ;
2023-05-20 19:23:40 +02:00
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock ;
import java.io.IOException ;
import java.io.InputStream ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.InvocationTargetException ;
2023-08-22 13:29:44 +02:00
import java.util.ArrayList ;
import java.util.List ;
2022-10-02 23:06:56 +02:00
2024-02-10 20:37:28 +01:00
public class Activity extends ContextWrapper implements Window . Callback {
2022-10-02 23:06:56 +02:00
LayoutInflater layout_inflater ;
2023-09-01 12:34:57 +02:00
Window window = new Window ( this ) ;
2022-10-26 18:39:04 +02:00
int requested_orientation = - 1 /*ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED*/ ; // dummy
2023-09-19 23:09:58 +02:00
public Intent intent ;
2023-08-22 13:23:34 +02:00
private Activity resultActivity ;
private int resultRequestCode ;
private int pendingRequestCode ;
private int pendingResultCode ;
private Intent pendingData ;
2024-03-05 17:07:21 +01:00
private boolean paused = false ;
2023-08-22 13:29:44 +02:00
List < Fragment > fragments = new ArrayList < > ( ) ;
2022-10-02 23:06:56 +02:00
2023-05-20 19:23:40 +02:00
/ * *
* 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
* /
2023-08-08 10:16:17 +02:00
private static Activity createMainActivity ( String className , long native_window ) throws ClassNotFoundException , NoSuchMethodException , SecurityException , InstantiationException , IllegalAccessException , IllegalArgumentException , InvocationTargetException , IOException {
2023-05-20 19:23:40 +02:00
if ( className = = null ) {
InputStream inStream = ClassLoader . getSystemClassLoader ( ) . getResourceAsStream ( " AndroidManifest.xml " ) ;
AndroidManifestBlock block = AndroidManifestBlock . load ( inStream ) ;
className = block . getMainActivity ( ) . searchAttributeByResourceId ( AndroidManifestBlock . ID_name ) . getValueAsString ( ) ;
if ( className . startsWith ( " . " ) ) {
className = block . getPackageName ( ) + className ;
}
} else {
className = className . replace ( '/' , '.' ) ;
}
Class < ? extends Activity > cls = Class . forName ( className ) . asSubclass ( Activity . class ) ;
Constructor < ? extends Activity > constructor = cls . getConstructor ( ) ;
2023-08-08 10:16:17 +02:00
Activity activity = constructor . newInstance ( ) ;
activity . window . native_window = native_window ;
return activity ;
2022-10-02 23:06:56 +02:00
}
public Activity ( ) {
2024-02-10 20:37:28 +01:00
super ( null ) ;
2022-10-02 23:06:56 +02:00
layout_inflater = new LayoutInflater ( ) ;
2023-08-11 18:09:17 +02:00
intent = new Intent ( ) ;
2022-10-02 23:06:56 +02:00
}
public View root_view ;
2023-06-22 11:45:46 +02:00
public final Application getApplication ( ) {
2022-10-02 23:06:56 +02:00
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.
}
2022-10-02 23:06:56 +02:00
public ComponentName getComponentName ( ) {
return null ;
}
public Intent getIntent ( ) {
2023-08-11 18:09:17 +02:00
return intent ;
2022-10-02 23:06:56 +02:00
}
2022-10-26 18:39:04 +02:00
public int getRequestedOrientation ( ) {
2023-06-22 11:45:46 +02:00
return requested_orientation ;
2022-10-26 18:39:04 +02:00
}
2023-06-22 11:45:46 +02:00
public void setRequestedOrientation ( int orientation ) {
2022-10-26 18:39:04 +02:00
requested_orientation = orientation ;
}
2022-10-02 23:06:56 +02:00
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! " ) ;
2023-08-17 10:46:24 +02:00
new ViewGroup ( this ) . setId ( R . id . content ) ;
2022-10-02 23:06:56 +02:00
2023-08-22 13:29:44 +02:00
for ( Fragment fragment : fragments ) {
fragment . onCreate ( savedInstanceState ) ;
}
2022-10-02 23:06:56 +02:00
return ;
}
protected void onStart ( ) {
System . out . println ( " - onStart - yay! " ) ;
2023-08-22 13:20:04 +02:00
if ( window . contentView ! = null )
window . setContentView ( window . contentView ) ;
2022-10-02 23:06:56 +02:00
2023-08-22 13:29:44 +02:00
for ( Fragment fragment : fragments ) {
fragment . onStart ( ) ;
}
2022-10-02 23:06:56 +02:00
return ;
}
protected void onRestart ( ) {
System . out . println ( " - onRestart - yay! " ) ;
return ;
}
protected void onResume ( ) {
System . out . println ( " - onResume - yay! " ) ;
2023-08-22 13:23:34 +02:00
if ( pendingData ! = null ) {
onActivityResult ( pendingRequestCode , pendingResultCode , pendingData ) ;
pendingData = null ;
}
2022-10-02 23:06:56 +02:00
2023-08-22 13:29:44 +02:00
for ( Fragment fragment : fragments ) {
fragment . onResume ( ) ;
}
2024-03-05 17:07:21 +01:00
paused = false ;
2022-10-02 23:06:56 +02:00
return ;
}
protected void onPause ( ) {
System . out . println ( " - onPause - yay! " ) ;
2023-08-22 13:29:44 +02:00
for ( Fragment fragment : fragments ) {
fragment . onPause ( ) ;
}
2024-03-05 17:07:21 +01:00
paused = true ;
2022-10-02 23:06:56 +02:00
return ;
}
protected void onStop ( ) {
System . out . println ( " - onStop - yay! " ) ;
2023-08-22 13:29:44 +02:00
for ( Fragment fragment : fragments ) {
fragment . onStop ( ) ;
}
2022-10-02 23:06:56 +02:00
return ;
}
protected void onDestroy ( ) {
System . out . println ( " - onDestroy - yay! " ) ;
2023-08-22 13:29:44 +02:00
for ( Fragment fragment : fragments ) {
fragment . onDestroy ( ) ;
}
2022-10-02 23:06:56 +02:00
return ;
}
public void onWindowFocusChanged ( boolean hasFocus ) {
2023-06-22 11:45:46 +02:00
System . out . println ( " - onWindowFocusChanged - yay! (hasFocus: " + hasFocus + " ) " ) ;
2022-10-02 23:06:56 +02:00
return ;
}
2022-11-04 19:21:45 +01:00
protected void onSaveInstanceState ( Bundle outState ) {
}
void onConfigurationChanged ( Configuration newConfig ) {
}
public void onLowMemory ( ) {
}
2022-10-02 23:06:56 +02:00
/* --- */
2023-06-22 11:45:46 +02:00
public void setContentView ( int layoutResID ) throws Exception {
2022-10-02 23:06:56 +02:00
System . out . println ( " - setContentView - yay! " ) ;
2023-05-20 12:38:34 +02:00
XmlResourceParser xpp = Context . this_application . getResources ( ) . getLayout ( layoutResID ) ;
2022-10-02 23:06:56 +02:00
root_view = layout_inflater . inflate ( xpp , null , false ) ;
System . out . println ( " ~~~~~~~~~~~ " ) ;
System . out . println ( root_view ) ;
System . out . println ( root_view . widget ) ;
System . out . println ( " ~~~~~~~~~~~ " ) ;
setContentView ( root_view ) ;
/ * Window w = new Window ( ) ;
w . setTitle ( this . toString ( ) ) ;
w . setDefaultSize ( 540 , 960 ) ;
w . add ( root_view . widget ) ;
w . showAll ( ) ;
2023-06-22 11:45:46 +02:00
w . connect ( new Window . DeleteEvent ( ) {
public boolean onDeleteEvent ( Widget source , Event event ) {
Gtk . mainQuit ( ) ;
return false ;
}
} ) ; * /
}
2022-10-02 23:06:56 +02:00
2023-06-18 11:03:43 +02:00
public void setContentView ( View view , ViewGroup . LayoutParams layoutParams ) {
setContentView ( view ) ;
}
2022-10-02 23:06:56 +02:00
public void setContentView ( View view ) {
window . setContentView ( view ) ;
}
public < T extends android . view . View > T findViewById ( int id ) {
System . out . println ( " - findViewById - asked for view with id: " + id ) ;
2024-02-11 12:33:58 +01:00
View view = null ;
if ( window . contentView ! = null )
view = window . contentView . findViewById ( id ) ;
2022-10-02 23:06:56 +02:00
System . out . println ( " - findViewById - found this: " + view ) ;
2023-06-22 11:45:46 +02:00
return ( T ) view ;
2022-10-02 23:06:56 +02:00
}
public void invalidateOptionsMenu ( ) {
System . out . println ( " invalidateOptionsMenu() called, should we do something? " ) ;
}
public Window getWindow ( ) {
return this . window ;
}
2023-06-22 11:45:46 +02:00
public final void runOnUiThread ( Runnable action ) {
2023-07-25 14:26:29 +02:00
if ( Looper . myLooper ( ) = = Looper . getMainLooper ( ) ) {
action . run ( ) ;
} else {
new Handler ( Looper . getMainLooper ( ) ) . post ( action ) ;
}
2023-06-22 11:45:46 +02:00
}
2023-01-09 12:08:23 +01:00
2023-06-22 11:45:46 +02:00
protected void onActivityResult ( int requestCode , int resultCode , Intent data ) { }
2023-01-09 12:08:23 +01:00
2023-06-22 11:45:46 +02:00
public void startActivityForResult ( Intent intent , int requestCode ) {
System . out . println ( " startActivityForResult( " + intent + " , " + requestCode + " ) called, but we don't currently support multiple activities " ) ;
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 ;
2023-08-22 13:20:04 +02:00
activity . getWindow ( ) . native_window = getWindow ( ) . native_window ;
2023-08-22 13:23:34 +02:00
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 ( ) ) ; // RESULT_CANCELED is the only pre-defined return value, so hopefully it works out for us
}
}
else {
onActivityResult ( requestCode , 0 /*RESULT_CANCELED*/ , new Intent ( ) ) ; // RESULT_CANCELED is the only pre-defined return value, so hopefully it works out for us
}
}
2023-08-22 13:23:34 +02:00
public void setResult ( int resultCode , Intent data ) {
if ( resultActivity ! = null ) {
resultActivity . pendingRequestCode = resultRequestCode ;
resultActivity . pendingResultCode = resultCode ;
resultActivity . pendingData = data ;
}
}
2023-09-01 12:55:04 +02:00
public void setResult ( int resultCode ) {
setResult ( resultCode , null ) ;
}
2023-07-25 14:29:43 +02:00
public final void showDialog ( int id ) {
System . out . println ( " Activity.showDialog( " + id + " ) called " ) ;
}
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 ( ) {
nativeFinish ( getWindow ( ) . native_window ) ;
}
} ) ;
2023-08-11 18:09:17 +02:00
}
2023-08-17 10:46:24 +02:00
public Object getLastNonConfigurationInstance ( ) {
return null ;
}
public FragmentManager getFragmentManager ( ) {
2023-08-22 13:29:44 +02:00
return new FragmentManager ( this ) ;
2023-08-17 10:46:24 +02:00
}
public LayoutInflater getLayoutInflater ( ) {
return layout_inflater ;
}
public CharSequence getTitle ( ) {
return " Title " ;
}
2023-08-22 14:41:01 +02:00
public boolean isChangingConfigurations ( ) { return false ; }
2023-09-01 12:34:57 +02:00
@Override
public void onContentChanged ( ) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException ( " Unimplemented method 'onContentChanged' " ) ;
}
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 ) ;
}
}
2023-09-01 12:55:04 +02:00
public void setTitle ( CharSequence title ) { }
public void onBackPressed ( ) {
finish ( ) ;
}
2023-10-29 22:47:57 +01:00
public void setIntent ( Intent newIntent ) { }
2023-09-01 12:55:04 +02:00
public void unregisterReceiver ( BroadcastReceiver receiver ) { }
2024-02-10 20:37:28 +01:00
2024-02-15 21:09:47 +01:00
public Intent getParentActivityIntent ( ) {
return null ;
}
2024-02-17 15:15:05 +01:00
@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 ) ;
nativeRecreateActivity ( activity ) ;
} catch ( NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e ) {
System . out . println ( " exception in Activity.recreate, this is kinda sus " ) ;
e . printStackTrace ( ) ;
}
}
2024-02-10 20:37:28 +01:00
private native void nativeFinish ( long native_window ) ;
2024-02-19 16:29:09 +01:00
public static native void nativeRecreateActivity ( Activity activity ) ;
2024-02-10 20:37:28 +01:00
public static native void nativeStartActivity ( Activity activity ) ;
public static native void nativeOpenURI ( String uri ) ;
public static native void nativeShare ( String text ) ;
2022-10-02 23:06:56 +02:00
}