/** * MicroEmulator * Copyright (C) 2008 Bartek Teodorczyk <barteo@barteo.net> * * It is licensed under the following two licenses as alternatives: * 1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version * 2. Apache License (the "AL") Version 2.0 * * You may not use this file except in compliance with at least one of * the above two licenses. * * You may obtain a copy of the LGPL at * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt * * You may obtain a copy of the AL at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the LGPL or the AL for the specific language governing permissions and * limitations. * */ package ru.net.jimm; import android.app.AlertDialog; import android.app.KeyguardManager; import android.os.*; import android.view.*; import jimm.Jimm; import jimm.JimmMidlet; import jimmui.view.base.KeyEmulator; import jimmui.view.base.NativeCanvas; import jimmui.view.menu.Select; import org.microemu.DisplayAccess; import org.microemu.MIDletAccess; import org.microemu.MIDletBridge; import org.microemu.android.device.AndroidDevice; import org.microemu.android.device.AndroidInputMethod; import org.microemu.android.device.ui.*; import org.microemu.android.util.AndroidRecordStoreManager; import org.microemu.app.Common; import org.microemu.device.Device; import org.microemu.device.DeviceFactory; import org.microemu.device.ui.CommandUI; import android.media.AudioManager; import org.microemu.android.MicroEmulatorActivity; import android.content.Intent; import android.util.Log; import org.microemu.cldc.file.FileSystem; import ru.net.jimm.client.JimmServiceCommands; public class JimmActivity extends MicroEmulatorActivity { public static final String LOG_TAG = "JimmActivity"; public static String PACKAGE_NAME = null; public Common common; private boolean isVisible = false; private static JimmActivity instance; private NetworkStateReceiver networkStateReceiver = new NetworkStateReceiver(); private boolean ignoreBackKeyUp = false; public static JimmActivity getInstance() { return instance; } /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_NO_TITLE); setVolumeControlStream(AudioManager.STREAM_MUSIC); clipboard.setActivity(this); externalApi.setActivity(this); addActivityResultListener(externalApi); instance = this; PACKAGE_NAME = getApplicationContext().getPackageName(); Environment.initLogger(); MIDletInit(); } @Override protected void onPause() { isVisible = false; super.onPause(); try { if (isFinishing()) { Log.i(LOG_TAG, "onPause(); with isFinishing() == true."); Log.i(LOG_TAG, "Stopping service..."); // ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancelAll(); // stopService(new Intent(this, JimmService.class)); return; } Log.i(LOG_TAG, "onPause(); with isFinishing() == false."); MIDletAccess ma = MIDletBridge.getMIDletAccess(); if (null != ma) { ma.pauseApp(); DisplayAccess da = ma.getDisplayAccess(); if (null != da) { da.hideNotify(); } } } catch (Exception e) { error(e); } } @Override protected void onResume() { super.onResume(); isVisible = true; Log.i(LOG_TAG, "onResume();"); new Thread(new Runnable() { public void run() { MIDletStart(); } }).start(); } public final boolean isVisible() { if (isVisible) { KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE); return !keyguardManager.inKeyguardRestrictedInputMode(); } return false; } @Override protected void onDestroy() { Jimm.getJimm().releaseUI(); // TODO: hide // if (null != Jimm.getJimm()) Jimm.getJimm().quit(); Log.i(LOG_TAG, "onDestroy();"); super.onDestroy(); } @Override protected void onRestart() { super.onRestart(); isVisible = true; Log.i(LOG_TAG, "onRestart();"); } @Override protected void onStop() { isVisible = false; Log.i(LOG_TAG, "onStop();"); super.onStop(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (getDisplayable() instanceof AndroidCanvasUI) { ((AndroidCanvasUI) getDisplayable()).getCanvasView().resetScrolling(); if (ignoreKey(keyCode)) { return super.onKeyDown(keyCode, event); } if (!KeyEmulator.isMain() || (KeyEvent.KEYCODE_BACK != keyCode)) { Device device = DeviceFactory.getDevice(); ((AndroidInputMethod) device.getInputMethod()).buttonPressed(event); // isFirstBack = true; return true; } } if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR && keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { // Take care of calling this method on earlier versions of // the platform where it doesn't exist. onBackPressed(); return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && ignoreBackKeyUp) { ignoreBackKeyUp = false; return true; } if (getDisplayable() instanceof AndroidCanvasUI) { if (ignoreKey(keyCode)) { return super.onKeyUp(keyCode, event); } if (!KeyEmulator.isMain() || (KeyEvent.KEYCODE_BACK != keyCode)) { Device device = DeviceFactory.getDevice(); ((AndroidInputMethod) device.getInputMethod()).buttonReleased(event); return true; } } return super.onKeyUp(keyCode, event); } private boolean ignoreKey(int keyCode) { switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_HEADSETHOOK: return true; case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_BACK: return false; default: return true; } } private AndroidDisplayableUI getDisplayable() { MIDletAccess ma = MIDletBridge.getMIDletAccess(); if (ma == null) { return null; } final DisplayAccess da = ma.getDisplayAccess(); if (da == null) { return null; } return (AndroidDisplayableUI) da.getDisplayableUI(da.getCurrent()); } private Commands getCommandsUI() { AndroidDisplayableUI ui = getDisplayable(); if (ui == null) { return null; } if (ui instanceof AndroidTextBoxUI) { return ((AndroidTextBoxUI) ui).getCommandsUI(); } return null; } @Override public void onBackPressed() { if (KeyEmulator.isMain()) { minimizeApp(); return; } Commands commands = getCommandsUI(); if (null == commands) { return; } CommandUI cmd = commands.getBackCommand(); if (cmd == null) { return; } AndroidDisplayableUI ui = getDisplayable(); if (ui.getCommandListener() != null) { ignoreBackKeyUp = true; MIDletBridge.getMIDletAccess().getDisplayAccess().commandAction(cmd.getCommand(), ui.getDisplayable()); } } @Override public boolean onPrepareOptionsMenu(Menu menu) { Commands commands = getCommandsUI(); if (null == commands) { if (Jimm.getJimm().getDisplay().getCurrentDisplay() instanceof Select) { KeyEmulator.emulateKey(NativeCanvas.JIMM_BACK); } else { KeyEmulator.emulateKey(NativeCanvas.LEFT_SOFT); } return false; } menu.clear(); boolean result = false; CommandUI back = commands.getBackCommand(); for (int i = 0; i < commands.size(); i++) { AndroidCommandUI cmd = commands.get(i); if (back == cmd) continue; result = true; SubMenu item = menu.addSubMenu(Menu.NONE, i + MENU_TEXTBOX_FIRST, Menu.NONE, cmd.getCommand().getLabel()); item.setIcon(cmd.getDrawable()); } return result; } private static final int MENU_TEXTBOX_FIRST = 10 + Menu.FIRST; @Override public boolean onOptionsItemSelected(MenuItem item) { try { final DisplayAccess da = MIDletBridge.getMIDletAccess().getDisplayAccess(); CommandUI c = getCommandsUI().get(item.getItemId() - MENU_TEXTBOX_FIRST); da.commandAction(c.getCommand(), da.getCurrent()); return true; } catch (Exception ignored) { } return false; } private void error(Exception e) { final StringBuilder sb = new StringBuilder(); sb.append(e.getMessage()).append("\n"); for (StackTraceElement ste : e.getStackTrace()) { sb.append(String.format("%s.%s %d\n", ste.getClassName(), ste.getMethodName(), ste.getLineNumber())); } post(new Runnable() { @Override public void run() { AlertDialog alertDialog = new AlertDialog.Builder(JimmActivity.this).create(); alertDialog.setTitle("Jimm Error"); alertDialog.setMessage(sb.toString()); alertDialog.show(); } }); } private void MIDletInit() { try { common = new Common(emulatorContext); MIDletBridge.setMicroEmulator(common); common.setRecordStoreManager(new AndroidRecordStoreManager(this)); common.setDevice(new AndroidDevice(emulatorContext, this)); Environment.setup(this); /* JSR-75 */ FileSystem fs = new FileSystem(); fs.registerImplementation(); common.extensions.add(fs); /* JimmInitialization and Service */ JimmInitialization init = new JimmInitialization(); init.registerImplementation(); common.extensions.add(init); startService(); networkStateReceiver.updateNetworkState(this); common.initMIDlet(); JimmMidlet jimm = JimmMidlet.getMidlet(); if (null == jimm) jimm = new JimmMidlet(); jimm.initMidlet(); common.notifyImplementationMIDletStart(); } catch (Exception e) { error(e); } } private void MIDletStart() { try { MIDletBridge.getMIDletAccess().startApp(); if (contentView != null) { post(new Runnable() { public void run() { contentView.invalidate(); } }); } } catch (Exception e) { error(e); } } private void startService() { try { startService(new Intent(this, ru.net.jimm.service.JimmService.class)); registerReceiver(networkStateReceiver, networkStateReceiver.getFilter()); bindService(new Intent(this, ru.net.jimm.service.JimmService.class), service.connection, BIND_AUTO_CREATE); } catch (Exception e) { error(e); } } public void notifyMIDletDestroyed() { try { unbindService(service.connection); } catch (Exception e) { // do nothing } try { unregisterReceiver(networkStateReceiver); } catch (Exception e) { // do nothing } } public void minimizeApp() { // TODO: hide // super.onBackPressed(); Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); } public boolean isNetworkAvailable() { return networkStateReceiver.isNetworkAvailable(); } public final ExternalApi externalApi = new ExternalApi(); public final Clipboard clipboard = new Clipboard(); public final JimmServiceCommands service = new JimmServiceCommands(); }