/*********************************************************************
* ____ _____ _ *
* / ___| ___ _ __ _ _ | ____|_ __(_) ___ ___ ___ ___ _ __ *
* \___ \ / _ \| '_ \| | | | | _| | '__| |/ __/ __/ __|/ _ \| '_ \ *
* ___) | (_) | | | | |_| | | |___| | | | (__\__ \__ \ (_) | | | | *
* |____/ \___/|_| |_|\__, | |_____|_| |_|\___|___/___/\___/|_| |_| *
* |___/ *
* *
*********************************************************************
* Sony Ericsson Mobile Communications AB, Lund Sweden *
* Copyright 2008 Sony Ericsson Mobile Communications AB. *
* All rights, including trade secret rights, reserved. *
*********************************************************************
*
* @file
* @ingroup JAVA
*
* @copyright_semc
* @author MIDP
*/
package com.sonyericsson.midp.wallpaper;
import java.util.Vector;
import javax.microedition.lcdui.MIDPEvent;
import javax.microedition.lcdui.MIDPEventHandler;
import javax.microedition.lcdui.Native;
import javax.microedition.lcdui.Utility;
import ojex.service.NativeInvokable;
import I.CLauncher;
import I.CMidpManager;
import I.ICBTaskListener;
import I.ICBUISettings;
import I.ICBUIStandby;
import I.ITask;
import I.IUISettings;
import I.IUIStandby;
import I.IUIStandbyQueryInterface;
import com.sonyericsson.ecm.EcmException;
import com.sonyericsson.ecm.IRoot;
import com.sonyericsson.ecm.IntParam;
import com.sonyericsson.ecm.StringParam;
import com.sonyericsson.midp.Launcher;
import com.sonyericsson.midp.Launcher.BundleNotFoundException;
import com.sonyericsson.midp.unsubscribe.UIStandbyUnsubscriber;
/**
* Thread started at start-up by the SEMC Ojex invoker. Listens to events
* related to the wallpaper application functionality.
*/
public class ApplicationEventHandler implements NativeInvokable, ICBUISettings, ICBTaskListener, ICBUIStandby {
/* Mutex */
private static final Object lock = new Object();
/* Constant for checking if application was launched to early */
private static final int MAX_NBR_INST = 0x80080000 |
Params.TLauncherUed.MaxNbrInstancesReached;
/* IDL Components */
private IUISettings settings;
private IUIStandby standby;
private ITask currentTask;
/* The bundle launcher */
private Launcher launcher;
private boolean restart = false;
private int subscription;
public Vector anchorList = new Vector(2);
public ApplicationEventHandler() {
launcher = new Launcher(CLauncher.createILauncher(), CMidpManager
.createIMidpManager());
settings = Utility.getIUISettings();
standby = Utility.getIUIStandby();
IntParam tmpParam = new IntParam();
settings.subscribeToEvents(this, 0xffff, new IntParam(0));
standby.subscribeToEvents(this, 0xffff, tmpParam);
addStandbyUnsubscribeElement(standby, tmpParam.value);
if (Native.ApplicationManagement.autoStartDisabled()) {
unsetStandbyApplication();
} else {
checkForAndStartStandbyApplication();
}
}
public void addStandbyUnsubscribeElement(IUIStandby iUIStandby, int subscriptionHandle) {
anchorList.addElement(new UIStandbyUnsubscriber(((IUIStandbyQueryInterface)iUIStandby).interfacePointer, subscriptionHandle));
}
/**
* Will run as long as the phone is running
*/
public void run() {
while (true) {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
}
}
}
}
/**
* Called when a standby application is selected.
*/
public void onStandbyApplicationSet(final String name, final String vendor, String entryPoint) {
MIDPEventHandler.scheduleMIDPEventImmediately(new MIDPEvent() {
public void handle() {
launchStandbyApplication(name, vendor);
restart = false;
}
});
}
/**
* Called when the list of possible wallpaper applications is opened.
*/
public void onApplicationListOpened() {
MIDPEventHandler.scheduleMIDPEventImmediately(new MIDPEvent() {
public void handle() {
appListMenuAction0();
}
});
}
private native void appListMenuAction0();
/**
* Called when the wallpaper has been changed.
*/
public void onWallpaperChanged() {
MIDPEventHandler.scheduleMIDPEventImmediately(new MIDPEvent() {
public void handle() {
if ((currentTask != null) && (currentTask.getState() == Params.TTaskState.Started)) {
currentTask.stop(0);
currentTask.unsubscribeFromTaskEvents(subscription);
currentTask = null;
restart = false;
}
}
});
}
/**
* Callback at state changes.
*/
public void onTaskStateChanged(IRoot task, int clientData, final byte stateData,
final byte newState) {
MIDPEventHandler.scheduleMIDPEventImmediately(new MIDPEvent() {
public void handle() {
/* Only restart if exit was successful */
if ((currentTask != null) &&
(newState == Params.TTaskState.Killed)) {
if (stateData == Params.TTaskStateData.Successfull_Exit) {
restart = true;
} else {
try {
unsetStandbyApplication();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});
}
/**
* Called when idle mode changes.
*/
public void onIdle(boolean isIdle, int clientData) {
try {
if (isIdle && restart) {
checkForAndStartStandbyApplication();
restart = false;
}
} catch (Exception e) {
/* This is a hack intented to be removed when AMS has added
finer stateData granularity */
unsetStandbyApplication();
}
}
public void onSlaveActivate(int arg0) {}
public void onUIInitiated(int arg0) {}
/* Private methods */
private void checkForAndStartStandbyApplication() {
StringParam name = new StringParam();
StringParam vendor = new StringParam();
settings.checkForStandbyApplication(name, vendor);
if (name.value != null && vendor.value != null) {
launchStandbyApplication(name.value, vendor.value);
} else if (restart) {
unsetStandbyApplication();
}
}
private void unsetStandbyApplication() {
try {
settings.unsetStandbyApplication();
} catch (Exception e) {}
}
private void launchStandbyApplication(String name, String vendor) {
try {
currentTask = launcher.launchBundle(name, vendor,
Launcher.LAUNCH_OPTIONS_BACKGROUND);
subscribeToTaskEvents();
} catch (BundleNotFoundException bnfe) {
unsetStandbyApplication();
bnfe.printStackTrace();
} catch (EcmException ecm) {
handleLaunchEcmException(ecm.getErrorCode(), name, vendor);
} catch (Exception e) {
unsetStandbyApplication();
e.printStackTrace();
}
}
private void handleLaunchEcmException(int errorCode, final String name,
final String vendor) {
if ((errorCode & MAX_NBR_INST) == MAX_NBR_INST) {
MIDPEventHandler.scheduleMIDPEventImmediately(new MIDPEvent() {
public void handle() {
try {
/* Wait a bit for application to close */
Thread.sleep(200);
} catch (Exception e) {}
launchStandbyApplication(name, vendor);
}
});
} else {
unsetStandbyApplication();
}
}
private void subscribeToTaskEvents() {
IntParam subscriptionParam = new IntParam();
currentTask.subscribeToTaskEvents(this, 0xffff, subscriptionParam);
subscription = subscriptionParam.value;
}
}
|