/*
* Copyright (c) 2004-2009 XMLVM --- An XML-based Programming Language
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA.
*
* For more information, visit the XMLVM Home Page at http://www.xmlvm.org
*/
package android.app;
import org.xmlvm.iphone.NSObject;
import org.xmlvm.iphone.UIApplication;
import org.xmlvm.iphone.UIInterfaceOrientation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.internal.ActivityManager;
import android.internal.Assert;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
/**
* IPhone implementation of Android's Activity class.
*
* @see http://developer.android.com/reference/android/app/Activity.html}
*/
public class Activity extends ContextThemeWrapper {
public static final int RESULT_CANCELED = 0;
public static final int RESULT_OK = -1;
/*
* States according to {@link
* http://developer.motorola.com/docstools/library
* /Android_Applications_for_Java_ME_Developers/}
*/
private static final int STATE_UNINITIALIZED = 0;
private static final int STATE_ACTIVE = 1;
private static final int STATE_PAUSED = 2;
private static final int STATE_STOPPED = 3;
private static final int STATE_DESTROYED = 4;
private int state = STATE_UNINITIALIZED;
private Activity parent;
private Activity child;
private Intent intent;
private ComponentName componentName;
private int requestCode;
private int childRequestCode;
private int childResultCode;
private Intent childData;
private Window window;
private int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
public void xmlvmSetParent(Activity parent) {
this.parent = parent;
}
public Activity xmlvmGetParent() {
return this.parent;
}
public void xmlvmSetRequestCode(int requestCode) {
this.requestCode = requestCode;
}
public void xmlvmSetChild(Activity child) {
this.child = child;
}
public void xmlvmSetIntent(Intent intent) {
this.intent = intent;
}
public void xmlvmSetComponentName(ComponentName componentName) {
this.componentName = componentName;
}
private void xmlvmUnlinkActivity() {
if (child == null) {
// We have no child so set the parent as the new top activity
ActivityManager.setTopActivity(parent);
}
if (parent != null) {
parent.child = child;
}
if (child != null) {
child.parent = parent;
}
parent = null;
child = null;
}
public void xmlvmTransitToStateActive(Object savedInstanceState) {
switch (state) {
case STATE_UNINITIALIZED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnCreate", savedInstanceState, false);
NSObject.performSelectorOnMainThread(this, "xmlvmOnStart", null, false);
NSObject.performSelectorOnMainThread(this, "xmlvmOnResume", null, false);
break;
case STATE_PAUSED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnResume", null, false);
break;
case STATE_STOPPED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnRestart", null, false);
NSObject.performSelectorOnMainThread(this, "xmlvmOnStart", null, false);
NSObject.performSelectorOnMainThread(this, "xmlvmOnResume", null, false);
break;
default:
Assert.FAIL("Bad transition from state: " + state);
break;
}
state = STATE_ACTIVE;
}
public void xmlvmTransitToStatePaused() {
switch (state) {
case STATE_ACTIVE:
NSObject.performSelectorOnMainThread(this, "xmlvmOnPause", null, false);
break;
case STATE_STOPPED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnRestart", null, false);
NSObject.performSelectorOnMainThread(this, "xmlvmOnStart", null, false);
break;
default:
Assert.FAIL("Bad transition from state: " + state);
break;
}
state = STATE_PAUSED;
}
public void xmlvmTransitToStateStopped() {
switch (state) {
case STATE_ACTIVE:
NSObject.performSelectorOnMainThread(this, "xmlvmOnPause", null, false);
NSObject.performSelectorOnMainThread(this, "xmlvmOnStop", null, false);
break;
case STATE_PAUSED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnStop", null, false);
break;
default:
Assert.FAIL("Bad transition from state: " + state);
break;
}
state = STATE_STOPPED;
}
public void xmlvmTransitToStateDestroyed(boolean waitUntilDone) {
switch (state) {
case STATE_ACTIVE:
NSObject.performSelectorOnMainThread(this, "xmlvmOnPause", null, waitUntilDone);
NSObject.performSelectorOnMainThread(this, "xmlvmOnStop", null, waitUntilDone);
NSObject.performSelectorOnMainThread(this, "xmlvmOnDestroy", null, waitUntilDone);
break;
case STATE_PAUSED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnStop", null, waitUntilDone);
NSObject.performSelectorOnMainThread(this, "xmlvmOnDestroy", null, waitUntilDone);
break;
case STATE_STOPPED:
NSObject.performSelectorOnMainThread(this, "xmlvmOnDestroy", null, waitUntilDone);
break;
default:
Assert.FAIL("Bad transition from state: " + state);
break;
}
state = STATE_DESTROYED;
}
/**
*
* @param savedInstanceState
* unused as of now
*/
protected void onCreate(Bundle savedInstanceState) {
window = new Window(this);
onContentChanged();
}
public void xmlvmOnCreate(Object savedInstanceState) {
setRequestedOrientation(screenOrientation);
setResult(RESULT_CANCELED);
onCreate((Bundle) savedInstanceState);
}
protected void onStart() {
window.xmlvmSetHidden(false);
}
public void xmlvmOnStart(Object arg) {
onStart();
}
protected void onRestart() {
}
public void xmlvmOnRestart(Object arg) {
onRestart();
}
protected void onResume() {
}
public void xmlvmOnResume(Object arg) {
onResume();
window.xmlvmSetHidden(false);
}
protected void onPause() {
}
public void xmlvmOnPause(Object arg) {
onPause();
}
protected void onStop() {
}
public void xmlvmOnStop(Object arg) {
onStop();
window.xmlvmSetHidden(true);
}
/**
* Perform any final cleanup before an activity is destroyed. Can be
* overridden by subclasses.
*/
protected void onDestroy() {
}
public void xmlvmOnDestroy(Object arg) {
onDestroy();
Activity theParent = parent;
Activity theChild = child;
window.xmlvmRemoveWindow();
window = null;
xmlvmUnlinkActivity();
if (theParent != null) {
NSObject.performSelectorOnMainThread(theParent, "xmlvmOnActivityResult", null, false);
// Transition the parent to active only if there is no child
if (theChild == null) {
theParent.xmlvmTransitToStateActive(null);
}
}
}
/**
*
* @param requestCode
* @param resultCode
* unused as of now
* @param data
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
/**
*
* @param result
* unused as of now
*/
public void xmlvmOnActivityResult(Object result) {
onActivityResult(childRequestCode, childResultCode, childData);
}
protected void onSaveInstanceState(Bundle bundle) {
}
public void xmlvmOnSaveInstanceState(Object bundle) {
onSaveInstanceState((Bundle) bundle);
}
public void setContentView(View view) {
window.setContentView(view);
}
public void setContentView(int id) {
window.setContentView(id);
}
public void addContentView(View view, LayoutParams params) {
window.addContentView(view, params);
}
public View findViewById(int id) {
return window.findViewById(id);
}
/**
* Unimplemented on iPhone
*
* @param streamType
* unused
*/
public final void setVolumeControlStream(int streamType) {
// There's nothing appropriate on the iPhone so this implementation
// will remain empty
}
/**
* TODO: Implement for real.
*/
public WindowManager getWindowManager() {
return new WindowManager();
}
/**
* Can be overridden by subclasses.
*/
public void onContentChanged() {
}
public void showDialog(int id) {
Dialog dialog = onCreateDialog(id);
if (dialog != null)
dialog.show();
}
protected Dialog onCreateDialog(int id) {
return null;
}
/**
* Can be overridden by subclasses that want to create a menu.
*/
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
/**
* Can be overridden by subclasses that want to handle menu button presses.
*/
public boolean onOptionsItemSelected(MenuItem item) {
return true;
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return false;
}
public void startActivity(Intent intent) {
ActivityManager.startActivity(this, intent);
}
public void startActivityForResult(Intent intent, int requestCode) {
ActivityManager.startActivityForResult(this, intent, requestCode);
}
public final void setResult(int resultCode) {
setResult(resultCode, null);
}
public final void setResult(int resultCode, Intent data) {
if (parent != null) {
parent.childRequestCode = requestCode;
parent.childResultCode = resultCode;
parent.childData = data;
}
}
public void requestWindowFeature(int feature) {
switch (feature) {
case Window.FEATURE_NO_TITLE:
// TODO: This will remove the title
// bar, but not get rid of the status bar. On the iPhone we don't
// have a title, but maybe we should implement this as a
// compatibility feature. Once we have it, this is the place to
// disable it.
break;
default:
Assert.NOT_IMPLEMENTED();
}
}
/**
* Retrieve the current {@link Window} for the activity.
*/
public Window getWindow() {
return window;
}
/**
* Change the desired orientation of this activity.
*/
public void setRequestedOrientation(int requestedOrientation) {
screenOrientation = requestedOrientation;
switch (requestedOrientation) {
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
UIApplication.sharedApplication().setStatusBarOrientation(
UIInterfaceOrientation.LandscapeLeft);
break;
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
UIApplication.sharedApplication().setStatusBarOrientation(
UIInterfaceOrientation.Portrait);
break;
}
}
public void xmlvmSetRequestedOrientation(int requestedOrientation) {
screenOrientation = requestedOrientation;
}
public int getRequestedOrientation() {
return screenOrientation;
}
/**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity.
*
* @param mode
* Operating mode. Use {@link Context#MODE_PRIVATE} for the
* default operation, {@link Context#MODE_WORLD_READABLE} and
* {@link Context#MODE_WORLD_WRITEABLE} to control permissions.
*
* @return Returns the single SharedPreferences instance that can be used to
* retrieve and modify the preference values.
*/
public SharedPreferences getPreferences(int mode) {
return getSharedPreferences(this.getClass().getName(), mode);
}
/**
* @return
*/
protected Intent getIntent() {
return intent;
}
public ComponentName getComponentName() {
return componentName;
}
public LayoutInflater getLayoutInflater() {
return (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
public void finish() {
this.xmlvmTransitToStateDestroyed(false);
}
public void onConfigurationChanged(Configuration newConfig) {
Assert.NOT_IMPLEMENTED();
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
Assert.NOT_IMPLEMENTED();
return false;
}
public MenuInflater getMenuInflater() {
Assert.NOT_IMPLEMENTED();
return null;
}
public void setTitle(CharSequence title) {
Assert.NOT_IMPLEMENTED();
}
public String getString(int id) {
return this.getResources().getText(id);
}
}