зеркало из https://github.com/mozilla/pluotsorbet.git
Merge branch 'master' of https://github.com/mozilla/j2me.js into mbebenita-preempt
This commit is contained in:
Коммит
816bad3464
|
@ -55,3 +55,4 @@ java/custom/javax/microedition/lcdui/Display.java
|
|||
# These files are generated by java_cup
|
||||
tools/jasmin-2.4/src/jasmin/parser.java
|
||||
tools/jasmin-2.4/src/jasmin/sym.java
|
||||
tools/closure.jar
|
||||
|
|
7
Makefile
7
Makefile
|
@ -61,8 +61,11 @@ build/tests.jar.js: tests/tests.jar build/jsc.js aot-methods.txt
|
|||
build/program.jar.js: program.jar build/jsc.js aot-methods.txt
|
||||
js build/jsc.js -cp java/classes.jar program.jar -d -jf program.jar -mff aot-methods.txt > build/program.jar.js
|
||||
|
||||
closure: build/classes.jar.js build/j2me.js
|
||||
java -jar tools/closure.jar --language_in ECMASCRIPT5 -O SHUMWAY_OPTIMIZATIONS build/j2me.js > build/j2me.cc.js \
|
||||
tools/closure.jar:
|
||||
wget -O $@ https://github.com/mykmelez/closure-compiler/releases/download/v0.1/closure.jar
|
||||
|
||||
closure: build/classes.jar.js build/j2me.js tools/closure.jar
|
||||
java -jar tools/closure.jar --language_in ECMASCRIPT5 -O J2ME_OPTIMIZATIONS build/j2me.js > build/j2me.cc.js \
|
||||
&& mv build/j2me.cc.js build/j2me.js
|
||||
java -jar tools/closure.jar --language_in ECMASCRIPT5 -O SIMPLE build/classes.jar.js > build/classes.jar.cc.js \
|
||||
&& mv build/classes.jar.cc.js build/classes.jar.js
|
||||
|
|
29
README.md
29
README.md
|
@ -1,4 +1,4 @@
|
|||
# j2me.js [![Build Status](https://travis-ci.org/andreasgal/j2me.js.svg)](https://travis-ci.org/andreasgal/j2me.js)
|
||||
# j2me.js [![Build Status](https://travis-ci.org/mozilla/j2me.js.svg)](https://travis-ci.org/mozilla/j2me.js)
|
||||
|
||||
j2me.js is a J2ME virtual machine in JavaScript.
|
||||
|
||||
|
@ -11,9 +11,9 @@ The current goals of j2me.js are:
|
|||
|
||||
Make sure you have a [JRE](http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html) installed
|
||||
|
||||
Get the [j2me.js repo](https://github.com/andreasgal/j2me.js) if you don't have it already
|
||||
Get the [j2me.js repo](https://github.com/mozilla/j2me.js) if you don't have it already
|
||||
|
||||
git clone https://github.com/andreasgal/j2me.js
|
||||
git clone https://github.com/mozilla/j2me.js
|
||||
|
||||
Build using make:
|
||||
|
||||
|
@ -143,25 +143,6 @@ Modelines for JS files:
|
|||
|
||||
One way to profile j2me.js is to use the JS profiler available in Firefox Dev Tools. This will tell us how well the JVM is working and how well natives work. This type of profiling will not measure time that is taken waiting for async callbacks to be called (for example, when using the native JS filesystem API).
|
||||
|
||||
When debugging using the WebIDE, enable the option "select an iframe as the currently targeted document" and select the iframe containing main.html as the debugging target. NB: you need to connect to a target device running FxOS 2.1 or up to use this feature in WebIDE.
|
||||
|
||||
Use these JS calls within the console to start and stop profiling (TODO: I haven't actually gotten these to work):
|
||||
|
||||
Instrument.startProfile()
|
||||
Instrument.stopProfile()
|
||||
|
||||
It can be helpful to increase this `about:config` option: `devtools.hud.loglimit.console`
|
||||
|
||||
Alternatively, use the "Performance" tab of the Firefox Developer Tools.
|
||||
|
||||
### Java profiling
|
||||
|
||||
j2me.js includes its own profiler that is capable of measuring the performance of Java methods running inside its JVM.
|
||||
|
||||
When running j2me.js in Desktop Firefox, click the "profile" button that appears below the output iframe. Press the button again to stop profiling. You should get output including the total time taken inside each method and the number of times each method was called.
|
||||
|
||||
Add "&profile=1" to your URL parameter list to enable profile immediately upon loading j2me.js (index.html).
|
||||
|
||||
## Filesystem
|
||||
|
||||
midp/fs.js contains native implementations of various midp filesystem APIs.
|
||||
|
@ -224,8 +205,8 @@ To use it, first install a recent version of the
|
|||
|
||||
`make closure` compiles some JavaScript code with the Closure compiler.
|
||||
|
||||
To use it, first download Shumway's version of the compiler to tools/closure.jar:
|
||||
To use it, first download this custom version of the compiler to tools/closure.jar:
|
||||
|
||||
```
|
||||
wget https://github.com/mozilla/shumway/raw/master/utils/closure.jar -P tools/
|
||||
wget https://github.com/mykmelez/closure-compiler/releases/download/v0.1/closure.jar -P tools/
|
||||
```
|
||||
|
|
|
@ -76,8 +76,6 @@ module J2ME {
|
|||
*/
|
||||
_lock: Lock;
|
||||
|
||||
waiting: Context [];
|
||||
|
||||
clone(): java.lang.Object;
|
||||
equals(obj: java.lang.Object): boolean;
|
||||
finalize(): void;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
* icc_mcc
|
||||
* icc_mnc
|
||||
* icc_msisdn
|
||||
* instrument
|
||||
* jad
|
||||
* jars
|
||||
* logConsole
|
||||
|
@ -21,8 +20,6 @@
|
|||
* network_mcc
|
||||
* network_mnc
|
||||
* platform
|
||||
* profile
|
||||
* fgMidletClass
|
||||
* autosize
|
||||
* fontSize
|
||||
*
|
||||
|
|
36
context.ts
36
context.ts
|
@ -10,7 +10,6 @@ module J2ME {
|
|||
import assert = Debug.assert;
|
||||
import Bytecodes = Bytecode.Bytecodes;
|
||||
declare var VM;
|
||||
declare var Instrument;
|
||||
declare var setZeroTimeout;
|
||||
|
||||
export enum WriterFlags {
|
||||
|
@ -554,7 +553,6 @@ module J2ME {
|
|||
}
|
||||
|
||||
execute() {
|
||||
var start = performance.now();
|
||||
this.setAsCurrentContext();
|
||||
do {
|
||||
VM.execute();
|
||||
|
@ -584,16 +582,14 @@ module J2ME {
|
|||
}
|
||||
|
||||
block(obj, queue, lockLevel) {
|
||||
if (!obj[queue])
|
||||
obj[queue] = [];
|
||||
obj[queue].push(this);
|
||||
obj._lock[queue].push(this);
|
||||
this.lockLevel = lockLevel;
|
||||
$.pause("block");
|
||||
}
|
||||
|
||||
unblock(obj, queue, notifyAll) {
|
||||
while (obj[queue] && obj[queue].length) {
|
||||
var ctx = obj[queue].pop();
|
||||
while (obj._lock[queue].length) {
|
||||
var ctx = obj._lock[queue].pop();
|
||||
if (!ctx)
|
||||
continue;
|
||||
ctx.wakeup(obj)
|
||||
|
@ -607,10 +603,8 @@ module J2ME {
|
|||
window.clearTimeout(this.lockTimeout);
|
||||
this.lockTimeout = null;
|
||||
}
|
||||
if (obj._lock) {
|
||||
if (!obj.ready)
|
||||
obj.ready = [];
|
||||
obj.ready.push(this);
|
||||
if (obj._lock.level !== 0) {
|
||||
obj._lock.ready.push(this);
|
||||
} else {
|
||||
while (this.lockLevel-- > 0) {
|
||||
this.monitorEnter(obj);
|
||||
|
@ -624,6 +618,11 @@ module J2ME {
|
|||
|
||||
monitorEnter(object: java.lang.Object) {
|
||||
var lock = object._lock;
|
||||
if (lock && lock.level === 0) {
|
||||
lock.thread = this.thread;
|
||||
lock.level = 1;
|
||||
return;
|
||||
}
|
||||
if (!lock) {
|
||||
object._lock = new Lock(this.thread, 1);
|
||||
return;
|
||||
|
@ -637,12 +636,15 @@ module J2ME {
|
|||
|
||||
monitorExit(object: java.lang.Object) {
|
||||
var lock = object._lock;
|
||||
if (lock.level === 1 && lock.ready.length === 0) {
|
||||
lock.level = 0;
|
||||
return;
|
||||
}
|
||||
if (lock.thread !== this.thread)
|
||||
throw $.newIllegalMonitorStateException();
|
||||
if (--lock.level > 0) {
|
||||
return;
|
||||
}
|
||||
object._lock = null;
|
||||
this.unblock(object, "ready", false);
|
||||
}
|
||||
|
||||
|
@ -653,17 +655,19 @@ module J2ME {
|
|||
if (!lock || lock.thread !== this.thread)
|
||||
throw $.newIllegalMonitorStateException();
|
||||
var lockLevel = lock.level;
|
||||
while (lock.level > 0)
|
||||
for (var i = lockLevel; i > 0; i--) {
|
||||
this.monitorExit(object);
|
||||
}
|
||||
if (timeout) {
|
||||
var self = this;
|
||||
this.lockTimeout = window.setTimeout(function () {
|
||||
object.waiting.forEach(function (ctx, n) {
|
||||
for (var i = 0; i < lock.waiting.length; i++) {
|
||||
var ctx = lock.waiting[i];
|
||||
if (ctx === self) {
|
||||
object.waiting[n] = null;
|
||||
lock.waiting[i] = null;
|
||||
ctx.wakeup(object);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, timeout);
|
||||
} else {
|
||||
this.lockTimeout = null;
|
||||
|
|
15
index.js
15
index.js
|
@ -22,6 +22,15 @@
|
|||
});
|
||||
})();
|
||||
|
||||
var childOrigin = document.location.origin;
|
||||
document.getElementById("mozbrowser").addEventListener("mozbrowserlocationchange", function(event) {
|
||||
childOrigin = new URL(event.detail).origin;
|
||||
var parentOrigin = document.location.origin;
|
||||
if (childOrigin !== parentOrigin) {
|
||||
console.warn("on location change: child origin " + childOrigin + " !== parent origin " + parentOrigin);
|
||||
}
|
||||
});
|
||||
|
||||
var DumbPipe = {
|
||||
// Functions that handle requests to open a pipe, indexed by type.
|
||||
openers: {},
|
||||
|
@ -38,6 +47,12 @@ var DumbPipe = {
|
|||
},
|
||||
|
||||
handleEvent: function(event) {
|
||||
var parentOrigin = document.location.origin;
|
||||
if (childOrigin !== parentOrigin) {
|
||||
console.error("on show modal prompt: child origin " + childOrigin + " !== parent origin " + parentOrigin);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.detail.promptType == "custom-prompt") {
|
||||
console.warn("unresponsive script warning; figure out how to handle");
|
||||
return;
|
||||
|
|
193
instrument.js
193
instrument.js
|
@ -1,193 +0,0 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
var Instrument = {
|
||||
enter: {},
|
||||
exit: {},
|
||||
|
||||
profiling: false,
|
||||
profile: null,
|
||||
asyncProfile: null,
|
||||
|
||||
enabled: "instrument" in config && !/no|0/.test(config.instrument),
|
||||
|
||||
callEnterHooks: function(methodInfo, caller, callee) {
|
||||
if (this.enabled) {
|
||||
var key = methodInfo.implKey;
|
||||
if (Instrument.enter[key]) {
|
||||
Instrument.enter[key](caller, callee);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.profiling) {
|
||||
var now = performance.now();
|
||||
|
||||
if (caller.profileData && caller.profileData.then) {
|
||||
caller.profileData.cost += now - caller.profileData.then;
|
||||
caller.profileData.then = null;
|
||||
}
|
||||
|
||||
callee.profileData = {
|
||||
cost: 0,
|
||||
then: now,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
callExitHooks: function(methodInfo, caller, callee) {
|
||||
var key = methodInfo.implKey;
|
||||
|
||||
if (this.profiling) {
|
||||
var now = performance.now();
|
||||
|
||||
if (callee.profileData) {
|
||||
if (callee.profileData.then) {
|
||||
callee.profileData.cost += now - callee.profileData.then;
|
||||
callee.profileData.then = null;
|
||||
}
|
||||
|
||||
var methodProfileData = this.profile[key] || (this.profile[key] = { count: 0, cost: 0 });
|
||||
methodProfileData.count++;
|
||||
methodProfileData.cost += callee.profileData.cost;
|
||||
}
|
||||
|
||||
if (caller.profileData) {
|
||||
caller.profileData.then = now;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.enabled) {
|
||||
if (Instrument.exit[key]) {
|
||||
Instrument.exit[key](caller, callee);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
callPauseHooks: function(frame) {
|
||||
if (this.profiling && frame.profileData && frame.profileData.then) {
|
||||
frame.profileData.cost += performance.now() - frame.profileData.then;
|
||||
frame.profileData.then = null;
|
||||
}
|
||||
},
|
||||
|
||||
callResumeHooks: function(frame) {
|
||||
if (this.profiling && frame.profileData) {
|
||||
frame.profileData.then = performance.now();
|
||||
}
|
||||
},
|
||||
|
||||
enterAsyncNative: function(key, promise) {
|
||||
var profileData = this.asyncProfile[key] || (this.asyncProfile[key] = { count: 0, cost: 0 });
|
||||
promise.startTime = performance.now();
|
||||
},
|
||||
|
||||
exitAsyncNative: function(key, promise) {
|
||||
var profileData = this.asyncProfile[key];
|
||||
if (!profileData || !promise.startTime) {
|
||||
// Ignore native without profile data, which can happen when you start
|
||||
// profiling while the native is pending.
|
||||
return;
|
||||
}
|
||||
profileData.count++;
|
||||
profileData.cost += performance.now() - promise.startTime;
|
||||
},
|
||||
|
||||
startProfile: function() {
|
||||
this.profile = {};
|
||||
this.asyncProfile = {};
|
||||
this.profiling = true;
|
||||
},
|
||||
|
||||
printProfile: function(aProfile, aProfileName) {
|
||||
var methods = [];
|
||||
|
||||
for (var key in aProfile) {
|
||||
methods.push({
|
||||
key: key,
|
||||
count: aProfile[key].count,
|
||||
cost: aProfile[key].cost,
|
||||
});
|
||||
}
|
||||
|
||||
methods.sort(function(a, b) { return b.cost - a.cost });
|
||||
|
||||
console.log(aProfileName + ":");
|
||||
methods.forEach(function(method) {
|
||||
console.log(Math.round(method.cost) + "ms " + method.count + " " + method.key);
|
||||
});
|
||||
},
|
||||
|
||||
stopProfile: function() {
|
||||
this.printProfile(this.profile, "Profile");
|
||||
this.printProfile(this.asyncProfile, "Async natives profile");
|
||||
|
||||
this.profiling = false;
|
||||
},
|
||||
|
||||
measure: function(alternateImpl, ctx, methodInfo) {
|
||||
var key = methodInfo.implKey;
|
||||
if (this.profiling) {
|
||||
var then = performance.now();
|
||||
alternateImpl.call(null, ctx, ctx.current().stack, methodInfo.isStatic);
|
||||
var methodProfileData = this.profile[key] || (this.profile[key] = { count: 0, cost: 0 });
|
||||
methodProfileData.count++;
|
||||
methodProfileData.cost += performance.now() - then;
|
||||
} else {
|
||||
alternateImpl.call(null, ctx, ctx.current().stack, methodInfo.isStatic);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Instrument.enter["com/sun/midp/ssl/SSLStreamConnection.<init>.(Ljava/lang/String;ILjava/io/InputStream;Ljava/io/OutputStream;Lcom/sun/midp/pki/CertStore;)V"] = function(caller, callee) {
|
||||
var _this = callee.locals.read(6), port = callee.locals.read(4), host = util.fromJavaString(callee.locals.read(5));
|
||||
_this.logBuffer = "SSLStreamConnection to " + host + ":" + port + ":\n";
|
||||
};
|
||||
|
||||
Instrument.enter["com/sun/midp/ssl/Out.write.(I)V"] = function(caller, callee) {
|
||||
var _this = callee.locals.read(3);
|
||||
var connection = _this.klass.classInfo.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
|
||||
connection.logBuffer += String.fromCharCode(callee.stack.read(1));
|
||||
};
|
||||
|
||||
Instrument.enter["com/sun/midp/ssl/Out.write.([BII)V"] = function(caller, callee) {
|
||||
var len = callee.locals.read(1), off = callee.locals.read(2), b = callee.locals.read(3), _this = callee.locals.read(4);
|
||||
var connection = _this.klass.classInfo.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
|
||||
var range = b.subarray(off, off + len);
|
||||
for (var i = 0; i < range.length; i++) {
|
||||
if (range[i] == 0) {
|
||||
break;
|
||||
}
|
||||
connection.logBuffer += String.fromCharCode(range[i] & 0xff);
|
||||
}
|
||||
};
|
||||
|
||||
Instrument.exit["com/sun/midp/ssl/In.read.()I"] = function(caller, callee) {
|
||||
// We can't use caller.stack.read() here, because the length of the caller's
|
||||
// stack differs depending on whether or not In.read threw an exception.
|
||||
var _this = caller.stack[2];
|
||||
|
||||
var connection = _this.klass.classInfo.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
|
||||
connection.logBuffer += String.fromCharCode(callee.stack.read(1));
|
||||
};
|
||||
|
||||
Instrument.exit["com/sun/midp/ssl/In.read.([BII)I"] = function(caller, callee) {
|
||||
var len = callee.locals.read(4), off = callee.locals.read(5), b = callee.locals.read(6), _this = callee.locals.read(7);
|
||||
var connection = _this.klass.classInfo.getField("I.ssc.Lcom/sun/midp/ssl/SSLStreamConnection;").get(_this);
|
||||
var range = b.subarray(off, off + len);
|
||||
for (var i = 0; i < range.length; i++) {
|
||||
if (range[i] == 0) {
|
||||
break;
|
||||
}
|
||||
connection.logBuffer += String.fromCharCode(range[i] & 0xff);
|
||||
}
|
||||
};
|
||||
|
||||
Instrument.enter["com/sun/midp/ssl/SSLStreamConnection.close.()V"] = function(caller, callee) {
|
||||
var _this = callee.locals.read(1);
|
||||
if ("logBuffer" in _this) {
|
||||
console.log(_this.logBuffer);
|
||||
delete _this.logBuffer;
|
||||
}
|
||||
};
|
|
@ -1,6 +1,5 @@
|
|||
module J2ME {
|
||||
declare var util;
|
||||
declare var Instrument;
|
||||
declare var Promise;
|
||||
|
||||
import BytecodeStream = Bytecode.BytecodeStream;
|
||||
|
@ -82,17 +81,14 @@ module J2ME {
|
|||
* Debugging helper to make sure native methods were implemented correctly.
|
||||
*/
|
||||
function checkReturnValue(methodInfo: MethodInfo, returnValue: any) {
|
||||
if (returnValue instanceof Promise) {
|
||||
console.error("You forgot to call asyncImpl():", methodInfo.implKey);
|
||||
} else if (methodInfo.getReturnKind() === Kind.Void && returnValue) {
|
||||
console.error("You returned something in a void method:", methodInfo.implKey);
|
||||
} else if (methodInfo.getReturnKind() !== Kind.Void && (returnValue === undefined) &&
|
||||
!U) {
|
||||
console.error("You returned undefined in a non-void method:", methodInfo.implKey);
|
||||
} else if (typeof returnValue === "string") {
|
||||
console.error("You returned a non-wrapped string:", methodInfo.implKey);
|
||||
} else if (returnValue === true || returnValue === false) {
|
||||
console.error("You returned a JS boolean:", methodInfo.implKey);
|
||||
if (U) {
|
||||
if (typeof returnValue !== "undefined") {
|
||||
assert(false, "Expected undefined return value during unwind, got " + returnValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!(getKindCheck(methodInfo.getReturnKind())(returnValue))) {
|
||||
assert(false, "Expected " + Kind[methodInfo.getReturnKind()] + " return value, got " + returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,12 +178,13 @@ module J2ME {
|
|||
|
||||
if (ctx.current() === Frame.Start) {
|
||||
ctx.kill();
|
||||
if (ctx.thread && ctx.thread.waiting && ctx.thread.waiting.length > 0) {
|
||||
if (ctx.thread && ctx.thread._lock.waiting && ctx.thread._lock.waiting.length > 0) {
|
||||
console.error(buildExceptionLog(e, stackTrace));
|
||||
ctx.thread.waiting.forEach(function(waitingCtx, n) {
|
||||
ctx.thread.waiting[n] = null;
|
||||
for (var i = 0; i < ctx.thread._lock.waiting.length; i++) {
|
||||
var waitingCtx = ctx.thread._lock.waiting[i];
|
||||
ctx.thread._lock.waiting[i] = null;
|
||||
waitingCtx.wakeup(ctx.thread);
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new Error(buildExceptionLog(e, stackTrace));
|
||||
} else {
|
||||
|
@ -1325,7 +1322,6 @@ module J2ME {
|
|||
static execute = interpret;
|
||||
static Yield = {toString: function () { return "YIELD" }};
|
||||
static Pause = {toString: function () { return "PAUSE" }};
|
||||
static DEBUG = false;
|
||||
static DEBUG_PRINT_ALL_EXCEPTIONS = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,29 +3,22 @@ package com.nokia.mid.ui;
|
|||
import javax.microedition.lcdui.Font;
|
||||
import java.util.Hashtable;
|
||||
|
||||
class TextEditorThread implements Runnable {
|
||||
class TextEditorThread extends Thread {
|
||||
// We need a thread to be able to wake from js when there is an async js keyboard event.
|
||||
native void sleep();
|
||||
native int getNextDirtyEditor();
|
||||
|
||||
Hashtable listeners;
|
||||
native TextEditor getNextDirtyEditor();
|
||||
|
||||
TextEditorThread() {
|
||||
listeners = new Hashtable();
|
||||
setPriority(Thread.MAX_PRIORITY);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
sleep();
|
||||
int dirty = getNextDirtyEditor();
|
||||
TextEditor t = (TextEditor)listeners.get("" + dirty);
|
||||
t.myListener.inputAction(t, TextEditorListener.ACTION_CONTENT_CHANGE);
|
||||
TextEditor dirty = getNextDirtyEditor();
|
||||
if (dirty.myListener != null) {
|
||||
dirty.myListener.inputAction(dirty, TextEditorListener.ACTION_CONTENT_CHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void register(int id, TextEditor t) {
|
||||
listeners.put("" + id, t);
|
||||
}
|
||||
}
|
||||
|
||||
public class TextEditor extends CanvasItem {
|
||||
|
@ -35,22 +28,20 @@ public class TextEditor extends CanvasItem {
|
|||
protected TextEditorListener myListener;
|
||||
|
||||
private boolean multiline = false;
|
||||
private int myId;
|
||||
private static TextEditorThread textEditorThread;
|
||||
private Font font = Font.getDefaultFont();
|
||||
|
||||
protected TextEditor(String text, int maxSize, int constraints, int width, int height) {
|
||||
myId = init(text, maxSize, constraints, width, height);
|
||||
init(text, maxSize, constraints, width, height);
|
||||
|
||||
if (textEditorThread == null) {
|
||||
textEditorThread = new TextEditorThread();
|
||||
Thread t = new Thread(textEditorThread);
|
||||
t.start();
|
||||
textEditorThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the native representation.
|
||||
native private int init(String text, int maxSize, int constraints, int width, int height);
|
||||
native private void init(String text, int maxSize, int constraints, int width, int height);
|
||||
|
||||
// Creates a new TextEditor object with the given initial contents, maximum size in characters, constraints and editor size in pixels.
|
||||
public static TextEditor createTextEditor(String text, int maxSize, int constraints, int width, int height) {
|
||||
|
@ -186,7 +177,6 @@ public class TextEditor extends CanvasItem {
|
|||
// Sets a listener for content changes in this TextEditor, replacing any previous TextEditorListener.
|
||||
public void setTextEditorListener(TextEditorListener listener) {
|
||||
myListener = listener;
|
||||
textEditorThread.register(myId, this);
|
||||
}
|
||||
|
||||
// Returns the multiline state of the TextEditor.
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
/**
|
||||
* Consumes events from AMS Services.
|
||||
*/
|
||||
interface AMSServicesEventConsumer {
|
||||
/**
|
||||
* Processes RESTART_MIDLET_EVENT.
|
||||
*
|
||||
* @param externalAppId application ID assigned by externall App Manager;
|
||||
* not used if there is no external manager
|
||||
* @param suiteId ID of the midlet suite
|
||||
* @param className class name of the midlet to restart
|
||||
* @param displayName display name of the midlet to restart
|
||||
*/
|
||||
public void handleRestartMIDletEvent(int externalAppId, int suiteId,
|
||||
String className, String displayName);
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.events.Event;
|
||||
import com.sun.midp.events.EventQueue;
|
||||
import com.sun.midp.events.EventListener;
|
||||
|
||||
/**
|
||||
* Dummy implementation of listener for AMS Services events.
|
||||
*/
|
||||
class AMSServicesEventListener implements EventListener {
|
||||
/**
|
||||
* Dummy implementation of package private constructor.
|
||||
*
|
||||
* @param eventQueue reference to the event queue
|
||||
* @param amsServicesEventConsumer comsumer that will process events
|
||||
* received by this listener
|
||||
*/
|
||||
AMSServicesEventListener(
|
||||
EventQueue eventQueue,
|
||||
AMSServicesEventConsumer amsServicesEventConsumer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess an event that is being posted to the event queue.
|
||||
*
|
||||
* @param event event being posted
|
||||
*
|
||||
* @param waitingEvent previous event of this type waiting in the
|
||||
* queue to be processed
|
||||
*
|
||||
* @return true to allow the post to continue, false to not post the
|
||||
* event to the queue
|
||||
*/
|
||||
public boolean preprocess(Event event, Event waitingEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes events.
|
||||
*
|
||||
* @param event event to process
|
||||
*/
|
||||
public void process(Event event) {
|
||||
}
|
||||
}
|
|
@ -1,333 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import com.sun.midp.main.TrustedMIDletIcon;
|
||||
|
||||
import com.sun.midp.midlet.*;
|
||||
|
||||
import com.sun.midp.midletsuite.*;
|
||||
|
||||
import com.sun.midp.io.j2me.push.*;
|
||||
|
||||
import com.sun.midp.installer.*;
|
||||
|
||||
import com.sun.midp.configurator.Constants;
|
||||
|
||||
/**
|
||||
* The Graphical MIDlet suite information display.
|
||||
* <p>
|
||||
* The application property "arg0" will have the ID of the suite to display.
|
||||
*/
|
||||
public class AppInfo extends Form {
|
||||
|
||||
/** Cache of the suite icon. */
|
||||
Image suiteIcon;
|
||||
/** Cache of the single suite icon. */
|
||||
Image singleSuiteIcon;
|
||||
|
||||
/** Icon to display for the suite */
|
||||
Image icon;
|
||||
|
||||
/** MIDlet Suite storage object. */
|
||||
MIDletSuiteStorage midletSuiteStorage;
|
||||
|
||||
/** Switch to the manager when "Back" is activated */
|
||||
ApplicationManager manager;
|
||||
|
||||
/** Installation information of the suite. */
|
||||
InstallInfo installInfo;
|
||||
/** Number of MIDlets in the suite. */
|
||||
int numberOfMidlets;
|
||||
/** Display name of the suite. */
|
||||
String displayName;
|
||||
|
||||
/**
|
||||
* Create and initialize a new Application Info MIDlet.
|
||||
* @param suiteId - the id of the suite for
|
||||
* which the AppInfo should be displayed
|
||||
* @exception Exception if error occurs
|
||||
*/
|
||||
public AppInfo(int suiteId) throws Throwable {
|
||||
|
||||
super(null);
|
||||
|
||||
midletSuiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
|
||||
|
||||
displaySuiteInfo(suiteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the information for a suite.
|
||||
*
|
||||
* @param suiteId ID for suite to display
|
||||
* @exception Exception if error occurs
|
||||
*/
|
||||
private void displaySuiteInfo(int suiteId) throws Throwable {
|
||||
StringBuffer label = new StringBuffer(40);
|
||||
StringBuffer value = new StringBuffer(40);
|
||||
Item item;
|
||||
String[] authPath;
|
||||
String temp;
|
||||
MIDletSuiteImpl midletSuite = null;
|
||||
|
||||
try {
|
||||
midletSuite = midletSuiteStorage.getMIDletSuite(suiteId, false);
|
||||
|
||||
initMidletSuiteInfo(midletSuite);
|
||||
|
||||
label.append(Resource.getString(ResourceConstants.INFO));
|
||||
label.append(": ");
|
||||
label.append(displayName);
|
||||
setTitle(label.toString());
|
||||
|
||||
append(
|
||||
new ImageItem(null, icon, ImageItem.LAYOUT_NEWLINE_BEFORE +
|
||||
ImageItem.LAYOUT_CENTER +
|
||||
ImageItem.LAYOUT_NEWLINE_AFTER, null));
|
||||
|
||||
if (!midletSuite.isEnabled()) {
|
||||
item = new StringItem(null, Resource.getString(
|
||||
ResourceConstants.AMS_SUITE_DISABLED_NOTE));
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
}
|
||||
|
||||
// round up the size to a Kilobyte
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString(ResourceConstants.AMS_SIZE));
|
||||
label.append(": ");
|
||||
value.append(
|
||||
Integer.toString((MIDletSuiteStorage.getMIDletSuiteStorage().
|
||||
getStorageUsed(midletSuite.getID()) +
|
||||
1023) / 1024));
|
||||
value.append(" K");
|
||||
item = new StringItem(label.toString(), value.toString());
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString(ResourceConstants.AMS_VERSION));
|
||||
label.append(": ");
|
||||
item = new StringItem(label.toString(),
|
||||
midletSuite.getProperty(MIDletSuite.VERSION_PROP));
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
label.setLength(0);
|
||||
|
||||
if (midletSuite.isTrusted()) {
|
||||
temp = Resource.getString
|
||||
(ResourceConstants.AMS_MGR_AUTH_VENDOR);
|
||||
} else {
|
||||
temp = Resource.getString
|
||||
(ResourceConstants.AMS_MGR_VENDOR);
|
||||
}
|
||||
|
||||
label.append(temp);
|
||||
label.append(": ");
|
||||
item = new StringItem(label.toString(),
|
||||
midletSuite.getProperty(MIDletSuite.VENDOR_PROP));
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
temp = midletSuite.getProperty(MIDletSuite.DESC_PROP);
|
||||
if (temp != null) {
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString
|
||||
(ResourceConstants.AMS_DESCRIPTION));
|
||||
label.append(": ");
|
||||
item = new StringItem(label.toString(), temp);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
}
|
||||
|
||||
if (numberOfMidlets != 1) {
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString
|
||||
(ResourceConstants.AMS_CONTENTS));
|
||||
label.append(":");
|
||||
item = new StringItem(label.toString(), "");
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
appendMIDletsToForm(midletSuite);
|
||||
}
|
||||
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString(ResourceConstants.AMS_WEBSITE));
|
||||
label.append(": ");
|
||||
item = new StringItem(label.toString(),
|
||||
installInfo.getDownloadUrl());
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString(ResourceConstants.AMS_ADVANCED));
|
||||
label.append(": ");
|
||||
item = new StringItem(label.toString(), "");
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
if (midletSuite.isTrusted()) {
|
||||
append(new ImageItem(null, TrustedMIDletIcon.getIcon(),
|
||||
ImageItem.LAYOUT_DEFAULT, null));
|
||||
temp = Resource.getString
|
||||
(ResourceConstants.AMS_MGR_TRUSTED);
|
||||
} else {
|
||||
temp = Resource.getString
|
||||
(ResourceConstants.AMS_MGR_UNTRUSTED);
|
||||
}
|
||||
|
||||
item = new StringItem(null, temp);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
// Append classes verification state to advanced section
|
||||
if (Constants.VERIFY_ONCE && midletSuite.isVerified()) {
|
||||
item = new StringItem(null, Resource.getString(
|
||||
ResourceConstants.AMS_VERIFIED_CLASSES));
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
|
||||
}
|
||||
|
||||
authPath = installInfo.getAuthPath();
|
||||
if (authPath != null) {
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString
|
||||
(ResourceConstants.AMS_AUTHORIZED_BY));
|
||||
label.append(": ");
|
||||
temp = label.toString();
|
||||
for (int i = 0; i < authPath.length; i++) {
|
||||
item = new StringItem(temp, authPath[i]);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
temp = null;
|
||||
}
|
||||
}
|
||||
|
||||
temp = PushRegistryInternal.listConnections(
|
||||
midletSuite.getID(), false);
|
||||
if (temp != null) {
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString
|
||||
(ResourceConstants.AMS_AUTO_START_CONN));
|
||||
label.append(": ");
|
||||
item = new StringItem(label.toString(), temp);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw t;
|
||||
} finally {
|
||||
if (midletSuite != null) {
|
||||
midletSuite.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the MIDlet suite info fields for a given suite.
|
||||
*
|
||||
* @param midletSuite the MIDletSuiteImpl object instance
|
||||
*
|
||||
* @exception Exception if problem occurs while getting the suite info
|
||||
*/
|
||||
private void initMidletSuiteInfo(MIDletSuiteImpl midletSuite)
|
||||
throws Exception {
|
||||
|
||||
installInfo = midletSuite.getInstallInfo();
|
||||
numberOfMidlets = midletSuite.getNumberOfMIDlets();
|
||||
|
||||
if (numberOfMidlets == 1) {
|
||||
String value = midletSuite.getProperty("MIDlet-1");
|
||||
MIDletInfo temp = new MIDletInfo(value);
|
||||
displayName = temp.name;
|
||||
icon = getSingleSuiteIcon();
|
||||
} else {
|
||||
displayName =
|
||||
midletSuite.getProperty(MIDletSuiteImpl.SUITE_NAME_PROP);
|
||||
icon = getSuiteIcon();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a names of all the MIDlets in a suite to a Form, one per line.
|
||||
*
|
||||
* @param midletSuite information of a suite of MIDlets
|
||||
*/
|
||||
private void appendMIDletsToForm(MIDletSuiteImpl midletSuite) {
|
||||
int numberOfMidlets;
|
||||
MIDletInfo midletInfo;
|
||||
StringItem item;
|
||||
|
||||
numberOfMidlets = midletSuite.getNumberOfMIDlets();
|
||||
for (int i = 1; i <= numberOfMidlets; i++) {
|
||||
midletInfo = new MIDletInfo(
|
||||
midletSuite.getProperty("MIDlet-" + i));
|
||||
|
||||
item = new StringItem(null, midletInfo.name);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MIDlet suite icon from storage.
|
||||
*
|
||||
* @return icon image
|
||||
*/
|
||||
private Image getSuiteIcon() {
|
||||
if (suiteIcon != null) {
|
||||
return suiteIcon;
|
||||
}
|
||||
|
||||
suiteIcon = GraphicalInstaller.getImageFromInternalStorage("_suite8");
|
||||
return suiteIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single MIDlet suite icon from storage.
|
||||
*
|
||||
* @return icon image
|
||||
*/
|
||||
private Image getSingleSuiteIcon() {
|
||||
if (singleSuiteIcon != null) {
|
||||
return singleSuiteIcon;
|
||||
}
|
||||
|
||||
singleSuiteIcon = GraphicalInstaller.
|
||||
getImageFromInternalStorage("_single8");
|
||||
return singleSuiteIcon;
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.main.*;
|
||||
|
||||
import javax.microedition.lcdui.Displayable;
|
||||
|
||||
|
||||
interface AppManagerUI {
|
||||
|
||||
/**
|
||||
* The AppManagerPeer manages list of available MIDlet suites
|
||||
* and informs AppManagerUI regarding changes in list through
|
||||
* itemAppended callback when new item is appended to the list.
|
||||
*
|
||||
* The order in which the MIDlets are shown is up to the UI
|
||||
* and need not be the order of itemAppended invocations.
|
||||
*
|
||||
* @param suiteInfo the midlet suite info
|
||||
*/
|
||||
void itemAppended(RunningMIDletSuiteInfo suiteInfo);
|
||||
|
||||
/**
|
||||
* The AppManagerPeer manages list of available MIDlet suites
|
||||
* and informs AppManagerUI regarding changes in list through
|
||||
* itemRemoved callback when item is removed from the list.
|
||||
*
|
||||
* @param suiteInfo the midlet suite info
|
||||
*/
|
||||
void itemRemoved(RunningMIDletSuiteInfo suiteInfo);
|
||||
|
||||
/**
|
||||
* Called when a new internal midlet was launched
|
||||
*
|
||||
* @param midlet proxy of a newly launched MIDlet
|
||||
*/
|
||||
void notifyInternalMidletStarted(MIDletProxy midlet);
|
||||
|
||||
/**
|
||||
* Called when a new midlet was launched.
|
||||
*
|
||||
* @param si corresponding midlet suite info
|
||||
* @param className MIDlet class name
|
||||
*/
|
||||
void notifyMidletStarted(RunningMIDletSuiteInfo si, String className);
|
||||
|
||||
/**
|
||||
* Called when state of a running midlet has changed.
|
||||
*
|
||||
* @param si corresponding midlet suite info
|
||||
* @param midlet
|
||||
*/
|
||||
void notifyMidletStateChanged(RunningMIDletSuiteInfo si, MIDletProxy midlet);
|
||||
|
||||
/**
|
||||
* Called when a running internal midlet exited.
|
||||
* @param midlet proxy of the midlet that has exited
|
||||
*/
|
||||
void notifyInternalMidletExited(MIDletProxy midlet);
|
||||
|
||||
/**
|
||||
* Called when a running midlet exited.
|
||||
* @param si corresponding midlet suite info
|
||||
* @param midletClassName Class name of the exited midlet
|
||||
*/
|
||||
void notifyMidletExited(RunningMIDletSuiteInfo si, String midletClassName);
|
||||
|
||||
/**
|
||||
* Called by AppManagerPeer after a MIDlet suite
|
||||
* is successfully installed on the device,
|
||||
* to ask the user whether or not to launch
|
||||
* the MIDlet from the suite.
|
||||
* @param si corresponding suite info
|
||||
*/
|
||||
void notifySuiteInstalled(RunningMIDletSuiteInfo si);
|
||||
|
||||
/**
|
||||
* Called when a new MIDlet suite is installed externally.
|
||||
* @param si corresponding suite info
|
||||
*/
|
||||
void notifySuiteInstalledExt(RunningMIDletSuiteInfo si);
|
||||
|
||||
/**
|
||||
* Called when a suite exited (lastr running MIDlet in suite exited).
|
||||
* @param suiteInfo Suite which just exited
|
||||
*/
|
||||
void notifySuiteExited(RunningMIDletSuiteInfo suiteInfo);
|
||||
|
||||
/**
|
||||
* Called when MIDlet selector exited.
|
||||
* @param suiteInfo Containing ID of suite
|
||||
*/
|
||||
void notifyMIDletSelectorExited(RunningMIDletSuiteInfo suiteInfo);
|
||||
|
||||
/**
|
||||
* Called when a MIDlet suite has been removed externally.
|
||||
* @param si corresponding suite info
|
||||
*/
|
||||
void notifySuiteRemovedExt(RunningMIDletSuiteInfo si);
|
||||
|
||||
/**
|
||||
* Called when MIDlet suite being enabled
|
||||
* @param si corresponding suite info
|
||||
*/
|
||||
void notifyMIDletSuiteEnabled(RunningMIDletSuiteInfo si);
|
||||
|
||||
/**
|
||||
* Called when MIDlet suite icon hase changed
|
||||
* @param si corresponding suite info
|
||||
*/
|
||||
void notifyMIDletSuiteIconChaged(RunningMIDletSuiteInfo si);
|
||||
|
||||
/**
|
||||
* Called when a midlet could not be launched.
|
||||
*
|
||||
* @param suiteId suite ID of the MIDlet
|
||||
* @param className class name of the MIDlet
|
||||
* @param errorCode error code
|
||||
* @param errorDetails error code details
|
||||
*/
|
||||
void notifyMidletStartError(int suiteId, String className, int errorCode,
|
||||
String errorDetails);
|
||||
|
||||
/**
|
||||
* Called when state of the midlet changes.
|
||||
*
|
||||
* @param si corresponding suite info
|
||||
* @param newSi new suite info
|
||||
*/
|
||||
void notifyMIDletSuiteStateChanged(RunningMIDletSuiteInfo si,
|
||||
RunningMIDletSuiteInfo newSi);
|
||||
|
||||
/**
|
||||
* Requests that the ui element, associated with the specified midlet
|
||||
* suite, be visible and active.
|
||||
*
|
||||
* @param item corresponding suite info
|
||||
*/
|
||||
void setCurrentItem(RunningMIDletSuiteInfo item);
|
||||
|
||||
/**
|
||||
* Called to determine MidletSuiteInfo of the last selected Item.
|
||||
* Is used to restore selection in the app manager.
|
||||
*
|
||||
* @return last selected MidletSuiteInfo
|
||||
*/
|
||||
RunningMIDletSuiteInfo getSelectedMIDletSuiteInfo();
|
||||
|
||||
/**
|
||||
* Called when midlet switcher is needed.
|
||||
*
|
||||
* @param onlyFromLaunchedList true if midlet should
|
||||
* be selected from the list of already launched midlets,
|
||||
* if false then possibility to launch midlet is needed.
|
||||
*/
|
||||
void showMidletSwitcher(boolean onlyFromLaunchedList);
|
||||
|
||||
/**
|
||||
* Called when midlet selector is needed. Should show a list of
|
||||
* midlets present in the given suite and allow to select one.
|
||||
*
|
||||
* @param msiToRun a suite from which a midlet must be selected
|
||||
*/
|
||||
void showMidletSelector(RunningMIDletSuiteInfo msiToRun);
|
||||
|
||||
/**
|
||||
* Called by Manager when destroyApp happens to clean up data.
|
||||
*/
|
||||
void cleanUp();
|
||||
|
||||
/**
|
||||
* Returns the main displayable of the AppManagerUI.
|
||||
* @return main screen
|
||||
*/
|
||||
Displayable getMainDisplayable();
|
||||
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.Displayable;
|
||||
|
||||
/**
|
||||
* The interface to application setting peer used by AppSettingUI.
|
||||
*/
|
||||
interface AppSettings {
|
||||
|
||||
/**
|
||||
* Called by UI when value of particular application setting has been
|
||||
* changed by user. AppSettings validates the user input and If value
|
||||
* is not acceptable, for example due to exclusive combination selected,
|
||||
* changeSettingValue method of AppSettingsUI could be called by AppSettings
|
||||
* to change settings to appropriate values. All necessary informational
|
||||
* alerts in this case are shown to the user by AppSettings and thus
|
||||
* AppSettingsUI has just to change UI accordingly when changeSettingValue
|
||||
* is called.
|
||||
*
|
||||
* @param settingID id of setting
|
||||
* @param valueID id of selected value
|
||||
*/
|
||||
void onSettingChanged(int settingID, int valueID);
|
||||
|
||||
/**
|
||||
* Returns ValueChoice that contains set of available application
|
||||
* setting names and IDs. Selected ID represents the initial setting
|
||||
* to be shown to the user.
|
||||
* @return value choice
|
||||
*/
|
||||
ValueChoice getSettings();
|
||||
|
||||
/**
|
||||
* Returns ValueChoice that contains set of possible value' IDs and
|
||||
* lables for specified setting. Selected ID represents value that
|
||||
* is currently active for this setting.
|
||||
* @param settingID
|
||||
* @return available setting values
|
||||
*/
|
||||
ValueChoice getSettingValues(int settingID);
|
||||
|
||||
|
||||
/**
|
||||
* Cancel application settings the user entered and dismiss UI.
|
||||
* Called by AppSettingsUI as response to user request.
|
||||
*/
|
||||
void cancelApplicationSettings();
|
||||
|
||||
/**
|
||||
* Save application settings the user entered and dismiss UI.
|
||||
* Called by AppSettingsUI as a response to user request.
|
||||
*
|
||||
* IMPL_NOTE: This method has no arguments as AppSettings is
|
||||
* aware of changes user made due to onSettingChanged calls.
|
||||
*
|
||||
*/
|
||||
void saveApplicationSettings();
|
||||
}
|
|
@ -1,773 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import com.sun.midp.installer.*;
|
||||
|
||||
import com.sun.midp.midletsuite.*;
|
||||
|
||||
import com.sun.midp.security.*;
|
||||
|
||||
import com.sun.midp.io.j2me.push.*;
|
||||
|
||||
import com.sun.midp.log.Logging;
|
||||
import com.sun.midp.log.LogChannels;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* The Graphical MIDlet suite settings form.
|
||||
*/
|
||||
class AppSettingsImpl implements AppSettings, CommandListener {
|
||||
|
||||
/** Application settings UI */
|
||||
AppSettingsUI settingsUI;
|
||||
|
||||
/** ID for the interrupt choice. */
|
||||
private static final int INTERRUPT_CHOICE_ID = 2000;
|
||||
|
||||
/** ID for the first push option radio button. */
|
||||
private static final int PUSH_OPTION_1_ID = 1000;
|
||||
|
||||
/** The settings choice group. */
|
||||
private ValueChoiceImpl groupChoice;
|
||||
/** The application interruption setting. */
|
||||
private ValueChoiceImpl interruptChoice;
|
||||
|
||||
/** The previous current choice value. */
|
||||
private int prevValueID;
|
||||
/** The currently active choice group ID. */
|
||||
private int curChoiceID;
|
||||
/** The application permission settings. */
|
||||
private ValueChoiceImpl[] groupSettings;
|
||||
/** The number of group permission settings. */
|
||||
private int numberOfSettings;
|
||||
/** The initial setting. */
|
||||
private ValueChoiceImpl initialSetting;
|
||||
|
||||
/** Holds the maximum levels for permissions. */
|
||||
private byte[] maxLevels;
|
||||
/** Holds the updated permissions. */
|
||||
private byte[] curLevels;
|
||||
/** Holds the permissions selected by user for validation. */
|
||||
private byte[] tmpLevels;
|
||||
/** Holds the previous permissions selected by user for validation. */
|
||||
private byte[] prevTmpLevels;
|
||||
/** Holds the PUSH permission index */
|
||||
private int PUSH_ID;
|
||||
/** Holds the updated push interrupt level. */
|
||||
private byte pushInterruptSetting;
|
||||
/** Holds the selected push interrupt level for validation. */
|
||||
private byte tmpPushInterruptSetting;
|
||||
/** Holds the updated push options. */
|
||||
private int pushOptions;
|
||||
|
||||
/** Permission group information. */
|
||||
private PermissionGroup[] groups;
|
||||
/** Mutually exclusive permission groups currently selected by user */
|
||||
private PermissionGroup[] groupsInConflict;
|
||||
|
||||
/** MIDlet Suite storage object. */
|
||||
MIDletSuiteStorage midletSuiteStorage;
|
||||
|
||||
/** UI to display error alerts. */
|
||||
DisplayError displayError;
|
||||
|
||||
/** The displayable to be displayed after dismissing AppSettings. */
|
||||
Displayable nextScreen;
|
||||
|
||||
/** Display for the Manager midlet. */
|
||||
Display display;
|
||||
|
||||
/** Display name of the suite. */
|
||||
String suiteDisplayName;
|
||||
|
||||
/** Interface to suite */
|
||||
MIDletSuiteImpl midletSuite;
|
||||
|
||||
/** Installation information of the suite. */
|
||||
InstallInfo installInfo;
|
||||
|
||||
/** Command object for "OK" command for the alert
|
||||
* that is shown during choice selection validation. */
|
||||
private Command okChoiceSelectionCmd =
|
||||
new Command(Resource.getString(ResourceConstants.OK),
|
||||
Command.OK, 1);
|
||||
/** Command object for "Cancel" command for the alert
|
||||
* that is shown during choice selection validation. */
|
||||
private Command cancelChoiceSelectionCmd =
|
||||
new Command(Resource.getString(ResourceConstants.CANCEL),
|
||||
Command.CANCEL, 1);
|
||||
/**
|
||||
* Command object for "OK" command for the alert
|
||||
* that is shown during exclusive group conflict.
|
||||
*/
|
||||
private Command okExclusiveChoiceSelectionCmd =
|
||||
new Command(Resource.getString(ResourceConstants.YES),
|
||||
Command.OK, 1);
|
||||
/**
|
||||
* Command object for "NO" command for the alert
|
||||
* that is shown during exclusive group conflict.
|
||||
*/
|
||||
private Command noExclusiveChoiceSelectionCmd =
|
||||
new Command(Resource.getString(ResourceConstants.NO),
|
||||
Command.CANCEL, 1);
|
||||
|
||||
/**
|
||||
* Create and initialize a new application settings MIDlet.
|
||||
* @param suiteId - the id of the suite for
|
||||
* which the App settings should be displayed
|
||||
* @param display - the display instance to be used
|
||||
* @param displayError - the UI to be used to display error alerts.
|
||||
* @param nextScreen - the displayable to be shown after
|
||||
* this Form is dismissed
|
||||
*/
|
||||
AppSettingsImpl(int suiteId,
|
||||
Display display,
|
||||
DisplayError displayError,
|
||||
Displayable nextScreen)
|
||||
throws MIDletSuiteLockedException,
|
||||
MIDletSuiteCorruptedException
|
||||
{
|
||||
this.displayError = displayError;
|
||||
midletSuiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
|
||||
|
||||
this.display = display;
|
||||
this.nextScreen = nextScreen;
|
||||
PUSH_ID = Permissions.getId("javax.microedition.io.PushRegistry");
|
||||
loadApplicationSettings(suiteId);
|
||||
|
||||
settingsUI = new AppSettingsUIImpl();
|
||||
settingsUI.showAppSettings(this, Resource.getString(
|
||||
ResourceConstants.AMS_MGR_SETTINGS), display, displayError);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when interrupt choice selection changed
|
||||
*/
|
||||
void onInterruptChoiceChanged() {
|
||||
byte maxInterruptSetting;
|
||||
int interruptSetting = interruptChoice.getSelectedID();
|
||||
|
||||
if (maxLevels[PUSH_ID] == Permissions.ALLOW) {
|
||||
maxInterruptSetting = Permissions.BLANKET_GRANTED;
|
||||
} else {
|
||||
maxInterruptSetting = maxLevels[PUSH_ID];
|
||||
}
|
||||
|
||||
int newInterruptSettings;
|
||||
if (interruptSetting == PUSH_OPTION_1_ID) {
|
||||
newInterruptSettings = maxInterruptSetting;
|
||||
} else {
|
||||
newInterruptSettings = (byte)interruptSetting;
|
||||
}
|
||||
|
||||
groupsInConflict = Permissions.checkForMutuallyExclusiveCombination(
|
||||
tmpLevels, (byte)newInterruptSettings);
|
||||
if (groupsInConflict != null) {
|
||||
showGroupsInConflictAlert();
|
||||
} else {
|
||||
tmpPushInterruptSetting = (byte)newInterruptSettings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when setting group selection changed
|
||||
*
|
||||
* @param c setting value choice
|
||||
* @param prevValID ID of previously selected value
|
||||
*/
|
||||
private void onChoiceGroupSelectionChanged(ValueChoiceImpl c, int prevValID) {
|
||||
if (c == interruptChoice) {
|
||||
onInterruptChoiceChanged();
|
||||
} else {
|
||||
for (int i = 0; i < groupSettings.length; i++) {
|
||||
if (groupSettings[i] == c) {
|
||||
byte newSetting =
|
||||
(byte)groupSettings[i].getSelectedID();
|
||||
onChoiceGroupSelectionChanged(i, prevValID, newSetting);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when setting group selection changed
|
||||
* @param settingID ID of setting
|
||||
* @param lastSelectedID ID of previously selected value
|
||||
* @param newSetting ID of new value
|
||||
*/
|
||||
private void onChoiceGroupSelectionChanged(int settingID,
|
||||
int lastSelectedID,
|
||||
byte newSetting) {
|
||||
|
||||
// store previous values if we need to roll back
|
||||
System.arraycopy(tmpLevels, 0, prevTmpLevels, 0, tmpLevels.length);
|
||||
groupsInConflict = Permissions.checkForMutuallyExclusiveCombination(tmpLevels,
|
||||
tmpPushInterruptSetting, groups[settingID], newSetting);
|
||||
if (groupsInConflict != null) {
|
||||
showGroupsInConflictAlert();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Permissions.setPermissionGroup(tmpLevels,
|
||||
tmpPushInterruptSetting, groups[settingID], newSetting);
|
||||
} catch (SecurityException e) {
|
||||
// returning to previous selection
|
||||
groupSettings[settingID].setSelectedID(lastSelectedID);
|
||||
// nothing else to do
|
||||
return;
|
||||
}
|
||||
|
||||
String warning = Permissions.getInsecureCombinationWarning(tmpLevels,
|
||||
tmpPushInterruptSetting, groups[settingID], newSetting);
|
||||
if (warning != null) {
|
||||
// set up variables used afterAlert been dismissed
|
||||
prevValueID = lastSelectedID;
|
||||
curChoiceID = settingID;
|
||||
// show Alert
|
||||
Alert alert = new Alert(Resource.getString(ResourceConstants.WARNING),
|
||||
warning, null, AlertType.WARNING);
|
||||
alert.addCommand(okChoiceSelectionCmd);
|
||||
alert.addCommand(cancelChoiceSelectionCmd);
|
||||
alert.setCommandListener(this);
|
||||
alert.setTimeout(Alert.FOREVER);
|
||||
display.setCurrent(alert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by UI when value of particular application setting has been
|
||||
* changed by user. AppSettings validates the user input and If value
|
||||
* is not acceptable, for example due to exclusive combination selected,
|
||||
* changeSettingValue method of AppSettingsUI could be called by AppSettings
|
||||
* to change settings to appropriate values. All necessary informational
|
||||
* alerts in this case are shown to the user by AppSettings and thus
|
||||
* AppSettingsUI has just to change UI accordingly when changeSettingValue
|
||||
* is called.
|
||||
*
|
||||
* @param settingID id of setting
|
||||
* @param valueID id of selected value
|
||||
*/
|
||||
public void onSettingChanged(int settingID, int valueID) {
|
||||
|
||||
if (settingID == INTERRUPT_CHOICE_ID) {
|
||||
if (interruptChoice != null) {
|
||||
interruptChoice.setSelectedID(valueID);
|
||||
onInterruptChoiceChanged();
|
||||
}
|
||||
|
||||
} else {
|
||||
//else ID of group is equivalent to index in array
|
||||
int lastSelectedID = groupSettings[settingID].getSelectedID();
|
||||
groupSettings[settingID].setSelectedID(valueID);
|
||||
|
||||
|
||||
byte newSetting =
|
||||
(byte)groupSettings[settingID].getSelectedID();
|
||||
|
||||
if (newSetting != lastSelectedID) {
|
||||
onChoiceGroupSelectionChanged(settingID, lastSelectedID, newSetting);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a command issued on any Screen.
|
||||
*
|
||||
* @param c command activated by the user
|
||||
* @param s the Displayable the command was on.
|
||||
*/
|
||||
public void commandAction(Command c, Displayable s) {
|
||||
if (c == cancelChoiceSelectionCmd) {
|
||||
// roll back group levels
|
||||
System.arraycopy(prevTmpLevels, 0, tmpLevels, 0, tmpLevels.length);
|
||||
// restore choice selection
|
||||
if (curChoiceID >= 0 && curChoiceID < groupSettings.length) {
|
||||
ValueChoiceImpl curChoice = groupSettings[curChoiceID];
|
||||
curChoice.setSelectedID(prevValueID);
|
||||
settingsUI.changeSettingValue(curChoiceID, curChoice.getSelectedID());
|
||||
}
|
||||
display.setCurrent(settingsUI.getMainDisplayable());
|
||||
} else if (c == okChoiceSelectionCmd) {
|
||||
// just switch back to AppSettings UI
|
||||
display.setCurrent(settingsUI.getMainDisplayable());
|
||||
} else if (c == okExclusiveChoiceSelectionCmd) {
|
||||
if (groupsInConflict != null) {
|
||||
// set [0] to blanket, [1] to session
|
||||
ValueChoiceImpl bs1 = findChoice(groupsInConflict[1]);
|
||||
int prevValID1 = bs1.getSelectedID();
|
||||
bs1.setSelectedID(Permissions.SESSION);
|
||||
ValueChoiceImpl bs2 = findChoice(groupsInConflict[0]);
|
||||
int prevValID2 = bs2.getSelectedID();
|
||||
bs2.setSelectedID(Permissions.BLANKET_GRANTED);
|
||||
settingsUI.changeSettingValue(bs1.getPermissionGroupID(), bs1.getSelectedID());
|
||||
settingsUI.changeSettingValue(bs2.getPermissionGroupID(), bs2.getSelectedID());
|
||||
display.setCurrent(settingsUI.getMainDisplayable());
|
||||
onChoiceGroupSelectionChanged(bs1, prevValID1);
|
||||
onChoiceGroupSelectionChanged(bs2, prevValID2);
|
||||
}
|
||||
} else if (c == noExclusiveChoiceSelectionCmd) {
|
||||
if (groupsInConflict != null) {
|
||||
// set [1] to blanket, [0] to session
|
||||
ValueChoiceImpl bs1 = findChoice(groupsInConflict[0]);
|
||||
int prevValID1 = bs1.getSelectedID();
|
||||
bs1.setSelectedID(Permissions.SESSION);
|
||||
ValueChoiceImpl bs2 = findChoice(groupsInConflict[1]);
|
||||
int prevValID2 = bs2.getSelectedID();
|
||||
bs2.setSelectedID(Permissions.BLANKET_GRANTED);
|
||||
settingsUI.changeSettingValue(bs1.getPermissionGroupID(), bs1.getSelectedID());
|
||||
settingsUI.changeSettingValue(bs2.getPermissionGroupID(), bs2.getSelectedID());
|
||||
display.setCurrent(settingsUI.getMainDisplayable());
|
||||
onChoiceGroupSelectionChanged(bs1, prevValID1);
|
||||
onChoiceGroupSelectionChanged(bs2, prevValID2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns choice for specified permission group.
|
||||
*
|
||||
* @param pg permission group
|
||||
* @return vlue choice
|
||||
*/
|
||||
private ValueChoiceImpl findChoice(PermissionGroup pg) {
|
||||
|
||||
if (pg == Permissions.getPushInterruptGroup()) {
|
||||
return interruptChoice;
|
||||
}
|
||||
for (int i = 0; i < groupSettings.length; i++) {
|
||||
if ((groupSettings[i] != null) &&
|
||||
(groupSettings[i].getPermissionGroup() == pg)) {
|
||||
return groupSettings[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show alert when mutullu exclusive setting combination
|
||||
* accured.
|
||||
*/
|
||||
private void showGroupsInConflictAlert() {
|
||||
|
||||
String[] values = {groupsInConflict[0].getName(),
|
||||
groupsInConflict[1].getName()};
|
||||
|
||||
String txt = Resource.getString(
|
||||
ResourceConstants.PERMISSION_MUTUALLY_EXCLUSIVE_SELECT_MESSAGE, values);
|
||||
Alert alert = new Alert(Resource.getString(ResourceConstants.WARNING),
|
||||
txt, null, AlertType.WARNING);
|
||||
alert.addCommand(noExclusiveChoiceSelectionCmd);
|
||||
alert.addCommand(okExclusiveChoiceSelectionCmd);
|
||||
alert.setCommandListener(this);
|
||||
alert.setTimeout(Alert.FOREVER);
|
||||
display.setCurrent(alert);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns ValueChoice that contains set of available application
|
||||
* setting names and IDs. Selected ID represents the initial setting
|
||||
* to be shown to the user.
|
||||
* @return value choice
|
||||
*/
|
||||
public ValueChoice getSettings() {
|
||||
return groupChoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ValueChoice that contains set of possible value' IDs and
|
||||
* lables for specified setting. Selected ID represents value that
|
||||
* is currently active for this setting.
|
||||
* @param settingID
|
||||
* @return available setting values
|
||||
*/
|
||||
public ValueChoice getSettingValues(int settingID) {
|
||||
if (settingID == INTERRUPT_CHOICE_ID) {
|
||||
return interruptChoice;
|
||||
} else {
|
||||
//else ID of group is equivalent to index in array
|
||||
return groupSettings[settingID];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the MIDlet suite info fields for a given suite.
|
||||
*
|
||||
* @param midletSuite the MIDletSuiteImpl object instance
|
||||
*
|
||||
* @exception Exception if problem occurs while getting the suite info
|
||||
*/
|
||||
private void initMidletSuiteInfo(MIDletSuiteImpl midletSuite) {
|
||||
|
||||
int numberOfMidlets = midletSuite.getNumberOfMIDlets();
|
||||
installInfo = midletSuite.getInstallInfo();
|
||||
|
||||
if (numberOfMidlets == 1) {
|
||||
String value = midletSuite.getProperty("MIDlet-1");
|
||||
MIDletInfo temp = new MIDletInfo(value);
|
||||
suiteDisplayName = temp.name;
|
||||
} else {
|
||||
suiteDisplayName = midletSuite.getProperty(
|
||||
MIDletSuiteImpl.SUITE_NAME_PROP);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the MIDlet suite settings as choice group infos.
|
||||
*
|
||||
* @param suiteId ID for suite
|
||||
* @throws MIDletSuiteLockedException if the suite is locked
|
||||
* @throws MIDletSuiteCorruptedException if the suite is corrupted
|
||||
*/
|
||||
private void loadApplicationSettings(int suiteId)
|
||||
throws MIDletSuiteLockedException, MIDletSuiteCorruptedException {
|
||||
|
||||
int maxLevel;
|
||||
int interruptSetting;
|
||||
boolean loadDone = false;
|
||||
|
||||
try {
|
||||
midletSuite = midletSuiteStorage.getMIDletSuite(suiteId, false);
|
||||
initMidletSuiteInfo(midletSuite);
|
||||
|
||||
maxLevels =
|
||||
(Permissions.forDomain(installInfo.getSecurityDomain()))
|
||||
[Permissions.MAX_LEVELS];
|
||||
curLevels = midletSuite.getPermissions();
|
||||
tmpLevels = new byte[curLevels.length];
|
||||
System.arraycopy(curLevels, 0, tmpLevels, 0, curLevels.length);
|
||||
prevTmpLevels = new byte[curLevels.length];
|
||||
|
||||
pushInterruptSetting = midletSuite.getPushInterruptSetting();
|
||||
tmpPushInterruptSetting= pushInterruptSetting;
|
||||
pushOptions = midletSuite.getPushOptions();
|
||||
|
||||
groupChoice = new ValueChoiceImpl(null, -1,
|
||||
Resource.getString(ResourceConstants.AMS_MGR_PREFERENCES));
|
||||
|
||||
if (maxLevels[PUSH_ID] == Permissions.ALLOW) {
|
||||
maxLevel = Permissions.BLANKET;
|
||||
} else {
|
||||
maxLevel = maxLevels[PUSH_ID];
|
||||
}
|
||||
|
||||
if ((pushOptions &
|
||||
PushRegistryInternal.PUSH_OPT_WHEN_ONLY_APP) != 0) {
|
||||
interruptSetting = PUSH_OPTION_1_ID;
|
||||
} else {
|
||||
interruptSetting = pushInterruptSetting;
|
||||
}
|
||||
|
||||
interruptChoice =
|
||||
newSettingChoice(
|
||||
Permissions.getPushInterruptGroup(),
|
||||
INTERRUPT_CHOICE_ID,
|
||||
maxLevel,
|
||||
interruptSetting, suiteDisplayName,
|
||||
ResourceConstants.AMS_MGR_SETTINGS_PUSH_OPT_ANSWER,
|
||||
PUSH_OPTION_1_ID);
|
||||
|
||||
groups = Permissions.getSettingGroups(curLevels);
|
||||
|
||||
groupSettings = new ValueChoiceImpl[groups.length];
|
||||
|
||||
if (interruptChoice != null) {
|
||||
numberOfSettings = 1;
|
||||
} else {
|
||||
numberOfSettings = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < groups.length; i++) {
|
||||
byte maxGroupSetting =
|
||||
Permissions.getMaximumPermissionGroupLevel(
|
||||
maxLevels, groups[i]);
|
||||
byte currentGroupSetting = Permissions.getPermissionGroupLevel(
|
||||
curLevels, groups[i]);
|
||||
|
||||
groupSettings[i] = newSettingChoice(
|
||||
groups[i],
|
||||
i,
|
||||
maxGroupSetting,
|
||||
currentGroupSetting,
|
||||
suiteDisplayName,
|
||||
0, 0);
|
||||
if (groupSettings[i] != null) {
|
||||
numberOfSettings++;
|
||||
}
|
||||
}
|
||||
loadDone = true;
|
||||
} finally {
|
||||
if (!loadDone) {
|
||||
if (midletSuite != null) {
|
||||
midletSuite.close();
|
||||
midletSuite = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new choice info if it is user settable,
|
||||
* with the 3 preset choices and a initial one selected.
|
||||
*
|
||||
* @param permissionGroup correspondent permission group
|
||||
* @param groupID button ID of group in settings popup,
|
||||
* @param maxLevel maximum permission level
|
||||
* @param level current permission level
|
||||
* @param name name of suite
|
||||
* @param extraAnswer if > 0, add this extra answer before last
|
||||
* answer, i18N will be translated
|
||||
* @param extraAnswerId ID for the extra answer
|
||||
*
|
||||
* @return choice info or null if setting cannot be modified
|
||||
*/
|
||||
private ValueChoiceImpl newSettingChoice(
|
||||
PermissionGroup permissionGroup, int groupID,
|
||||
int maxLevel, int level,
|
||||
String name, int extraAnswer, int extraAnswerId) {
|
||||
String[] values = {name};
|
||||
int initValue;
|
||||
ValueChoiceImpl choice;
|
||||
|
||||
if (permissionGroup.getSettingsQuestion() == null ||
|
||||
maxLevel == Permissions.ALLOW || maxLevel == Permissions.NEVER ||
|
||||
level == Permissions.ALLOW || level == Permissions.NEVER) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
choice = new ValueChoiceImpl(permissionGroup, groupID,
|
||||
Resource.getString(permissionGroup.getSettingsQuestion(), values));
|
||||
|
||||
groupChoice.append(permissionGroup.getName(), groupID);
|
||||
|
||||
switch (maxLevel) {
|
||||
case Permissions.BLANKET:
|
||||
choice.append(Resource.getString(
|
||||
ResourceConstants.AMS_MGR_SETTINGS_BLANKET_ANSWER),
|
||||
Permissions.BLANKET_GRANTED);
|
||||
// fall through, since this security level permits the
|
||||
// next response.
|
||||
|
||||
case Permissions.SESSION:
|
||||
choice.append(Resource.getString(
|
||||
ResourceConstants.AMS_MGR_SETTINGS_SESSION_ANSWER),
|
||||
Permissions.SESSION);
|
||||
// fall through, since this security level permits the
|
||||
// next response.
|
||||
|
||||
default:
|
||||
choice.append(Resource.getString(
|
||||
ResourceConstants.AMS_MGR_SETTINGS_ONE_SHOT_ANSWER),
|
||||
Permissions.ONESHOT);
|
||||
|
||||
if (extraAnswer > 0) {
|
||||
choice.append(Resource.getString(extraAnswer), extraAnswerId);
|
||||
}
|
||||
|
||||
choice.append(permissionGroup.getDisableSettingChoice(),
|
||||
Permissions.BLANKET_DENIED);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
|
||||
Logging.report(Logging.INFORMATION, LogChannels.LC_AMS,
|
||||
"AppSettings: " + permissionGroup.getName() +
|
||||
" level = " + level);
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case Permissions.BLANKET_GRANTED:
|
||||
case Permissions.BLANKET:
|
||||
initValue = Permissions.BLANKET_GRANTED;
|
||||
break;
|
||||
|
||||
case Permissions.SESSION:
|
||||
initValue = Permissions.SESSION;
|
||||
break;
|
||||
|
||||
case Permissions.ONESHOT:
|
||||
initValue = Permissions.ONESHOT;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (level == extraAnswerId) {
|
||||
initValue = extraAnswerId;
|
||||
} else {
|
||||
initValue = Permissions.BLANKET_DENIED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (choice.idExists(initValue)) {
|
||||
choice.setSelectedID(initValue);
|
||||
} else {
|
||||
if (level == Permissions.BLANKET_GRANTED &&
|
||||
Permissions.isReadMessageGroup(permissionGroup)) {
|
||||
choice.setSelectedID(Permissions.ONESHOT);
|
||||
} else {
|
||||
throw new RuntimeException("Invalid initial permission level selected.");
|
||||
}
|
||||
}
|
||||
|
||||
if (initialSetting == null) {
|
||||
initialSetting = choice;
|
||||
groupChoice.setSelectedID(groupID);
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel application settings the user entered and dismiss UI.
|
||||
* Called by AppSettingsUI as response to user request.
|
||||
*/
|
||||
public void cancelApplicationSettings() {
|
||||
display.setCurrent(nextScreen);
|
||||
midletSuite.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save application settings the user entered and dismiss UI.
|
||||
* Called by AppSettingsUI as a response to user request.
|
||||
*
|
||||
* IMPL_NOTE: This method has no arguments as AppSettings is
|
||||
* aware of changes user made due to onSettingChanged calls.
|
||||
*
|
||||
*/
|
||||
public void saveApplicationSettings() {
|
||||
try {
|
||||
if (midletSuite == null) {
|
||||
return;
|
||||
}
|
||||
if (interruptChoice != null) {
|
||||
byte maxInterruptSetting;
|
||||
int interruptSetting = interruptChoice.getSelectedID();
|
||||
|
||||
if (maxLevels[PUSH_ID] == Permissions.ALLOW) {
|
||||
maxInterruptSetting = Permissions.BLANKET_GRANTED;
|
||||
} else {
|
||||
maxInterruptSetting = maxLevels[PUSH_ID];
|
||||
}
|
||||
|
||||
if (interruptSetting == PUSH_OPTION_1_ID) {
|
||||
pushOptions = PushRegistryInternal.PUSH_OPT_WHEN_ONLY_APP;
|
||||
pushInterruptSetting = maxInterruptSetting;
|
||||
} else {
|
||||
pushOptions = 0;
|
||||
Permissions.checkPushInterruptLevel(tmpLevels,
|
||||
(byte)interruptSetting);
|
||||
pushInterruptSetting = (byte)interruptSetting;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < groups.length; i++) {
|
||||
if (groupSettings[i] != null) {
|
||||
byte newSetting =
|
||||
(byte)groupSettings[i].getSelectedID();
|
||||
|
||||
if (newSetting != Permissions.getPermissionGroupLevel(
|
||||
curLevels, groups[i])) {
|
||||
if (newSetting != Permissions.BLANKET_GRANTED) {
|
||||
/*
|
||||
* first apply only weak permissions to avoid mutual
|
||||
* exclusive combination
|
||||
*/
|
||||
Permissions.setPermissionGroup(curLevels,
|
||||
pushInterruptSetting, groups[i], newSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < groups.length; i++) {
|
||||
if (groupSettings[i] != null) {
|
||||
byte newSetting =
|
||||
(byte)groupSettings[i].getSelectedID();
|
||||
|
||||
if (newSetting != Permissions.getPermissionGroupLevel(
|
||||
curLevels, groups[i])) {
|
||||
if (newSetting == Permissions.BLANKET_GRANTED) {
|
||||
Permissions.setPermissionGroup(curLevels,
|
||||
pushInterruptSetting, groups[i], newSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numberOfSettings > 0) {
|
||||
midletSuiteStorage.saveSuiteSettings(midletSuite.getID(),
|
||||
pushInterruptSetting, pushOptions, curLevels);
|
||||
displaySuccessMessage(Resource.getString
|
||||
(ResourceConstants.AMS_MGR_SAVED));
|
||||
}
|
||||
} catch (SecurityException ex) {
|
||||
Alert a = new Alert(Resource.getString(ResourceConstants.ERROR),
|
||||
ex.getMessage(), null,
|
||||
AlertType.ERROR);
|
||||
a.setTimeout(Alert.FOREVER);
|
||||
display.setCurrent(a);
|
||||
throw ex;
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
displayError.showErrorAlert(suiteDisplayName, t,
|
||||
Resource.getString
|
||||
(ResourceConstants.EXCEPTION), null);
|
||||
} finally {
|
||||
midletSuite.close();
|
||||
midletSuite = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert the user that an action was successful.
|
||||
* @param successMessage message to display to user
|
||||
*/
|
||||
private void displaySuccessMessage(String successMessage) {
|
||||
|
||||
Image icon = GraphicalInstaller.getImageFromInternalStorage("_dukeok8");
|
||||
|
||||
Alert successAlert = new Alert(null, successMessage, icon, null);
|
||||
|
||||
successAlert.setTimeout(GraphicalInstaller.ALERT_TIMEOUT);
|
||||
|
||||
display.setCurrent(successAlert, nextScreen);
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.Displayable;
|
||||
import javax.microedition.lcdui.Display;
|
||||
|
||||
interface AppSettingsUI {
|
||||
/**
|
||||
* Shows UI with application settings.
|
||||
* All information regarding available settings, possible setting values
|
||||
* and current setting value should be queried from AppSettings peer.
|
||||
* @param appSettings AppSettings peer, where information regarding
|
||||
* available settings and current setting value could be found.
|
||||
* Also appSettings is used to change application settings or to cancel
|
||||
* the process and dismiss this form. Method onSettingChanged of
|
||||
* appSettings should be called when attempt to change value for
|
||||
* particular setting occures. As a result changeSettingValue could be
|
||||
* called by appSettings when proposed setting value leads to changes in
|
||||
* other settings or is not allowed. This may happen for example when mutual
|
||||
* exclusive combinations selected. All necessary alerts in this case are
|
||||
* shown to the user by AppSettings and thus AppSettingsUIImpl has just
|
||||
* to change UI accordingly when changeSettingValue is called.
|
||||
* @param title
|
||||
* @param display - The display instance associated with the manager
|
||||
* @param displayError - The UI used to display error messages
|
||||
*/
|
||||
void showAppSettings(AppSettings appSettings, String title,
|
||||
Display display, DisplayError displayError);
|
||||
|
||||
/**
|
||||
* Called by AppSettings when specified value shoud be changed in UI.
|
||||
* Could be called as a result of user input validation by AppSettings
|
||||
* to correct the invalid setting combination. All necessary informational
|
||||
* alerts in this case are shown to the user by AppSettings and thus
|
||||
* AppSettingsUI has just to change UI accordingly.
|
||||
*
|
||||
* @param settingID id of setting
|
||||
* @param valueID id of selected value
|
||||
*/
|
||||
void changeSettingValue(int settingID, int valueID);
|
||||
|
||||
/**
|
||||
* Returns the main displayable of the AppSettingsUI.
|
||||
* @return main screen
|
||||
*/
|
||||
Displayable getMainDisplayable();
|
||||
|
||||
}
|
|
@ -1,319 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import com.sun.midp.log.Logging;
|
||||
import com.sun.midp.log.LogChannels;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
class AppSettingsUIImpl extends Form
|
||||
implements AppSettingsUI, CommandListener, ItemStateListener {
|
||||
|
||||
/** application settings peer. */
|
||||
AppSettings appSettings;
|
||||
|
||||
/** The ID of the last selected group. */
|
||||
private int lastGroupChoiceID;
|
||||
/** The index of the last selected group. */
|
||||
private int lastGroupChoiceIndex;
|
||||
/** The settings choice group. */
|
||||
private RadioButtonSet groupChoice;
|
||||
/** The level choice groups. */
|
||||
private RadioButtonSet[] groupSettings;
|
||||
/** The ID of the setting displayed in the form. */
|
||||
private int displayedSettingID;
|
||||
|
||||
|
||||
/** Command object for "OK" command for the form. */
|
||||
private Command saveAppSettingsCmd =
|
||||
new Command(Resource.getString(ResourceConstants.SAVE),
|
||||
Command.OK, 1);
|
||||
/** Command object for "Cancel" command for the form. */
|
||||
private Command cancelCmd =
|
||||
new Command(Resource.getString(ResourceConstants.CANCEL),
|
||||
Command.CANCEL, 1);
|
||||
|
||||
/**
|
||||
* Create and initialize a new application settings MIDlet.
|
||||
*/
|
||||
AppSettingsUIImpl() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display the MIDlet suite settings in combo box
|
||||
* and available setting values in option button set.
|
||||
*/
|
||||
private void loadApplicationSettings() {
|
||||
// create popup with available settings
|
||||
ValueChoice settings = appSettings.getSettings();
|
||||
if (settings.getCount() == 0) {
|
||||
// no settings available
|
||||
return;
|
||||
}
|
||||
groupChoice = new RadioButtonSet(settings.getTitle(), true);
|
||||
groupSettings = new RadioButtonSet[settings.getCount()];
|
||||
for (int i = 0; i < settings.getCount(); i++) {
|
||||
groupChoice.append(settings.getLabel(i), settings.getID(i));
|
||||
ValueChoice settingValues = appSettings.getSettingValues(settings.getID(i));
|
||||
// for each group create option button set with available levels
|
||||
groupSettings[i] = new RadioButtonSet(settingValues.getTitle(), false);
|
||||
for (int j = 0; j < settingValues.getCount(); j++) {
|
||||
groupSettings[i].append(settingValues.getLabel(j), settingValues.getID(j));
|
||||
}
|
||||
//select current level
|
||||
groupSettings[i].setSelectedID(settingValues.getSelectedID());
|
||||
groupSettings[i].setPreferredSize(getWidth(), -1);
|
||||
}
|
||||
// select default group
|
||||
groupChoice.setSelectedID(settings.getSelectedID());
|
||||
append(groupChoice);
|
||||
lastGroupChoiceID = settings.getSelectedID();
|
||||
lastGroupChoiceIndex = groupChoice.getSelectedIndex();
|
||||
displayedSettingID = append(groupSettings[lastGroupChoiceIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a command issued on any Screen.
|
||||
*
|
||||
* @param c command activated by the user
|
||||
* @param s the Displayable the command was on.
|
||||
*/
|
||||
public void commandAction(Command c, Displayable s) {
|
||||
if (c == saveAppSettingsCmd) {
|
||||
appSettings.saveApplicationSettings();
|
||||
} else if (c == cancelCmd) {
|
||||
appSettings.cancelApplicationSettings();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when internal state of an item in Settings form is
|
||||
* changed by the user. This is used to dynamically display
|
||||
* the setting the user chooses from the settings popup.
|
||||
*
|
||||
* @param item the item that was changed
|
||||
*/
|
||||
public void itemStateChanged(Item item) {
|
||||
|
||||
if (item == groupChoice) {
|
||||
int selected;
|
||||
selected = groupChoice.getSelectedID();
|
||||
if (selected == lastGroupChoiceID) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastGroupChoiceID = selected;
|
||||
lastGroupChoiceIndex = groupChoice.getSelectedIndex();
|
||||
|
||||
delete(displayedSettingID);
|
||||
|
||||
try {
|
||||
displayedSettingID = append(groupSettings[lastGroupChoiceIndex]);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// for safety/completeness.
|
||||
displayedSettingID = 0;
|
||||
Logging.report(Logging.ERROR, LogChannels.LC_AMS,
|
||||
"AppSettings: selected=" + selected);
|
||||
}
|
||||
} else {
|
||||
appSettings.onSettingChanged(lastGroupChoiceID,
|
||||
groupSettings[lastGroupChoiceIndex].getSelectedID());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by AppSettings when specified value shoud be changed in UI.
|
||||
* Could be called as a result of user input validation by AppSettings
|
||||
* to correct the invalid setting combination. All necessary informational
|
||||
* alerts in this case are shown to the user by AppSettings and thus
|
||||
* AppSettingsUI has just to change UI accordingly.
|
||||
*
|
||||
* @param settingID id of setting
|
||||
* @param valueID id of selected value
|
||||
*/
|
||||
public void changeSettingValue(int settingID, int valueID) {
|
||||
groupSettings[groupChoice.indexFor(settingID)].setSelectedID(valueID);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows UI with application settings.
|
||||
* All information regarding available settings, possible setting values
|
||||
* and current setting value should be queried from AppSettings peer.
|
||||
* @param appSettings AppSettings peer, where information regarding
|
||||
* available settings and current setting value could be found.
|
||||
* Also appSettings is used to change application settings or to cancel
|
||||
* the process and dismiss this form. Method onSettingChanged of
|
||||
* appSettings should be called when attempt to change value for
|
||||
* particular setting occures. As a result changeSettingValue could be
|
||||
* called by appSettings when proposed setting value leads to changes in
|
||||
* other settings or is not allowed. This may happen for example when mutual
|
||||
* exclusive combinations selected. All necessary alerts in this case are
|
||||
* shown to the user by AppSettings and thus AppSettingsUIImpl has just
|
||||
* to change UI accordingly when changeSettingValue is called.
|
||||
* @param title
|
||||
* @param display - The display instance associated with the manager
|
||||
* @param displayError - The UI used to display error messages
|
||||
*/
|
||||
public void showAppSettings(AppSettings appSettings, String title,
|
||||
Display display, DisplayError displayError) {
|
||||
|
||||
setTitle(title);
|
||||
this.appSettings = appSettings;
|
||||
loadApplicationSettings();
|
||||
if (groupChoice != null) {
|
||||
setItemStateListener(this);
|
||||
addCommand(saveAppSettingsCmd);
|
||||
}
|
||||
addCommand(cancelCmd);
|
||||
setCommandListener(this);
|
||||
|
||||
display.setCurrent(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main displayable of the AppSettingsUI.
|
||||
* @return main screen
|
||||
*/
|
||||
public Displayable getMainDisplayable() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A <code>RadioButtonSet</code> is a group radio buttons intended to be
|
||||
* placed within a <code>Form</code>. However the radio buttons can be
|
||||
* accessed by a assigned ID instead of by index. This lets the calling
|
||||
* code be the same when dealing with dynamic sets.
|
||||
*/
|
||||
class RadioButtonSet extends ChoiceGroup {
|
||||
/** Size increment for the ID array. */
|
||||
private static final int SIZE_INCREMENT = 5;
|
||||
|
||||
/** Keeps track of the button IDs. */
|
||||
private int[] ids;
|
||||
|
||||
/**
|
||||
* Creates a new, empty <code>RadioButtonSet</code>, specifying its
|
||||
* title.
|
||||
*
|
||||
* @param label the item's label (see {@link Item Item})
|
||||
* @param popup true if the radio buttons should be popup
|
||||
*/
|
||||
RadioButtonSet(String label, boolean popup) {
|
||||
super(label, popup ? Choice.POPUP : Choice.EXCLUSIVE);
|
||||
ids = new int[SIZE_INCREMENT];
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends choice to the set.
|
||||
*
|
||||
* @param stringPart the string part of the element to be added
|
||||
* @param id ID for the radio button
|
||||
*
|
||||
* @throws IllegalArgumentException if the image is mutable
|
||||
* @throws NullPointerException if <code>stringPart</code> is
|
||||
* <code>null</code>
|
||||
* @throws IndexOutOfBoundsException this call would exceed the maximum
|
||||
* number of buttons for this set
|
||||
*/
|
||||
void append(String stringPart, int id) {
|
||||
int buttonNumber = append(stringPart, null);
|
||||
|
||||
if (buttonNumber >= ids.length) {
|
||||
expandIdArray();
|
||||
}
|
||||
|
||||
ids[buttonNumber] = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects specufued item.
|
||||
*
|
||||
* @param id ID of item
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if <code>id</code> is invalid
|
||||
*/
|
||||
void setSelectedID(int id) {
|
||||
setSelectedIndex(indexFor(id), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the selected radio button.
|
||||
*
|
||||
* @return ID of selected element
|
||||
*/
|
||||
int getSelectedID() {
|
||||
return ids[getSelectedIndex()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index for an ID.
|
||||
*
|
||||
* @param id button id
|
||||
*
|
||||
* @return index for a button
|
||||
*
|
||||
* @exception IndexOutOfBoundsException If no element exists with that ID
|
||||
*/
|
||||
int indexFor(int id) {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
if (ids[i] == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
/** Expands the ID array. */
|
||||
private void expandIdArray() {
|
||||
int[] prev = ids;
|
||||
|
||||
ids = new int[prev.length + SIZE_INCREMENT];
|
||||
for (int i = 0; i < prev.length; i++) {
|
||||
ids[i] = prev[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ID of specified item.
|
||||
* @param index item index
|
||||
* @return item ID
|
||||
*/
|
||||
int getID(int index) {
|
||||
return ids[index];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.midletsuite.*;
|
||||
|
||||
/**
|
||||
* This is a common interface for Application managers.
|
||||
* Application manager controls midlet life cycle:
|
||||
* - installs and updates midlet suites
|
||||
* - launches, moves to foreground and exits midlets
|
||||
* - shuts down the AMS system
|
||||
* It is used by the AppSelector.
|
||||
*/
|
||||
interface ApplicationManager {
|
||||
|
||||
/** Discover and install a suite. */
|
||||
void installSuite();
|
||||
|
||||
/** Launch the CA manager. */
|
||||
void launchCaManager();
|
||||
|
||||
/** Launch the component manager. */
|
||||
void launchComponentManager();
|
||||
|
||||
/** Launch ODT Agent. */
|
||||
void launchODTAgent();
|
||||
|
||||
/**
|
||||
* Launches a suite.
|
||||
*
|
||||
* @param suiteInfo information for suite to launch
|
||||
* @param midletToRun class name of the MIDlet to launch
|
||||
*/
|
||||
void launchSuite(RunningMIDletSuiteInfo suiteInfo, String midletToRun);
|
||||
|
||||
/**
|
||||
* Update a suite.
|
||||
*
|
||||
* @param suiteInfo information for suite to update
|
||||
*/
|
||||
void updateSuite(RunningMIDletSuiteInfo suiteInfo);
|
||||
|
||||
/**
|
||||
* Shut downt the system
|
||||
*/
|
||||
void shutDown();
|
||||
|
||||
/**
|
||||
* Bring the midlet with the passed in midlet suite info to the
|
||||
* foreground.
|
||||
*
|
||||
* @param suiteInfo information for the midlet to be put to foreground
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
void moveToForeground(RunningMIDletSuiteInfo suiteInfo, String className);
|
||||
|
||||
/**
|
||||
* Exit the midlet with the passed in midlet suite info.
|
||||
*
|
||||
* @param suiteInfo information for the midlet to be terminated
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
void exitMidlet(RunningMIDletSuiteInfo suiteInfo, String className);
|
||||
|
||||
/**
|
||||
* Handle exit of MIDlet suite (last running MIDlet in sute exited).
|
||||
* @param suiteInfo Containing ID of exited suite
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
void notifySuiteExited(RunningMIDletSuiteInfo suiteInfo, String className);
|
||||
|
||||
/**
|
||||
* Handle exit of MIDlet selector.
|
||||
* @param suiteInfo Containing ID of suite
|
||||
*/
|
||||
void notifyMIDletSelectorExited(RunningMIDletSuiteInfo suiteInfo);
|
||||
}
|
|
@ -1,432 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import javax.microedition.midlet.*;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import com.sun.midp.midlet.MIDletSuite;
|
||||
|
||||
import com.sun.midp.midletsuite.InstallInfo;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteImpl;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteStorage;
|
||||
|
||||
import com.sun.midp.publickeystore.PublicKeyInfo;
|
||||
import com.sun.midp.publickeystore.WebPublicKeyStore;
|
||||
|
||||
import com.sun.midp.security.Permissions;
|
||||
|
||||
|
||||
/**
|
||||
* This class enabled the user to manage the state of Third Party certificate
|
||||
* authorities.
|
||||
*/
|
||||
public class CaManager extends MIDlet {
|
||||
/** Construct a CA manager MIDlet. */
|
||||
public CaManager() {
|
||||
Display display = Display.getDisplay(this);
|
||||
|
||||
display.setCurrent(new CaForm(this, display));
|
||||
}
|
||||
|
||||
/** Start; there are not resource to re-allocate. */
|
||||
public void startApp() {}
|
||||
|
||||
/** Pause; there are no resources that need to be released. */
|
||||
public void pauseApp() {}
|
||||
|
||||
/**
|
||||
* Destroy cleans up.
|
||||
*
|
||||
* @param unconditional is ignored; this object always
|
||||
* destroys itself when requested.
|
||||
*/
|
||||
public void destroyApp(boolean unconditional) {}
|
||||
|
||||
/** Exits this application. */
|
||||
void exit() {
|
||||
notifyDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of certificate authorities, each with a check box next to it.
|
||||
* Check means enable, no check mean disabled.
|
||||
*/
|
||||
class CaForm extends Form implements CommandListener {
|
||||
|
||||
/** MIDlet suite storage object. */
|
||||
private MIDletSuiteStorage suiteStorage;
|
||||
|
||||
/** List of suites to disable. */
|
||||
private Vector disableSuites;
|
||||
|
||||
/** List of suites to enable. */
|
||||
private Vector enableSuites;
|
||||
|
||||
/** Command object for "Save" command for the form. */
|
||||
private Command confirmCmd =
|
||||
new Command(Resource.getString(ResourceConstants.SAVE),
|
||||
Command.OK, 1);
|
||||
|
||||
|
||||
/** Command object for "Exit" command for splash screen. */
|
||||
private Command exitCmd =
|
||||
new Command(Resource.getString(ResourceConstants.EXIT),
|
||||
Command.BACK, 1);
|
||||
|
||||
/** Command object for "Save" command for the confirmation form. */
|
||||
private Command saveCmd =
|
||||
new Command(Resource.getString(ResourceConstants.SAVE),
|
||||
Command.OK, 1);
|
||||
|
||||
/** Command object for "Exit" command for splash screen. */
|
||||
private Command cancelCmd =
|
||||
new Command(Resource.getString(ResourceConstants.CANCEL),
|
||||
Command.BACK, 1);
|
||||
|
||||
/** List of CAs. */
|
||||
private Vector caList;
|
||||
|
||||
/** Parent CA manager. */
|
||||
private CaManager parent;
|
||||
|
||||
/** Parent display. */
|
||||
private Display display;
|
||||
|
||||
/** CA choices. */
|
||||
private ChoiceGroup choices;
|
||||
|
||||
/** The index of the first item in the choice group. */
|
||||
private int firstIndex;
|
||||
|
||||
/**
|
||||
* Construct a certificate form from a list of CA's.
|
||||
*
|
||||
* @param theParent Parent CaManager object
|
||||
* @param theDisplay parent Display object
|
||||
*/
|
||||
CaForm(CaManager theParent, Display theDisplay) {
|
||||
super("Certificate Authorities");
|
||||
|
||||
String manufacturerCa = null;
|
||||
String operatorCa = null;
|
||||
StringBuffer label = new StringBuffer(80);
|
||||
Item item = null;
|
||||
|
||||
parent = theParent;
|
||||
display = theDisplay;
|
||||
|
||||
|
||||
suiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
|
||||
|
||||
WebPublicKeyStore keystore = WebPublicKeyStore.getTrustedKeyStore();
|
||||
caList = new Vector();
|
||||
|
||||
for (int i = 0; i < keystore.numberOfKeys(); i++) {
|
||||
PublicKeyInfo key = keystore.getKey(i);
|
||||
if (Permissions.MANUFACTURER_DOMAIN_BINDING.
|
||||
equals(key.getDomain())) {
|
||||
manufacturerCa = key.getOwner();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Permissions.OPERATOR_DOMAIN_BINDING.
|
||||
equals(key.getDomain())) {
|
||||
operatorCa = key.getOwner();
|
||||
continue;
|
||||
}
|
||||
|
||||
caList.addElement(new Ca(key.getOwner(), key.isEnabled()));
|
||||
}
|
||||
|
||||
if (manufacturerCa != null) {
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString(ResourceConstants.MANUFACTURER));
|
||||
label.append(": ");
|
||||
|
||||
item = new StringItem(label.toString(), manufacturerCa);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
}
|
||||
|
||||
if (operatorCa != null) {
|
||||
label.setLength(0);
|
||||
label.append(
|
||||
Resource.getString(ResourceConstants.SERVICE_PROVIDER));
|
||||
label.append(": ");
|
||||
|
||||
item = new StringItem(label.toString(), operatorCa);
|
||||
item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
|
||||
append(item);
|
||||
}
|
||||
|
||||
if (caList.size() > 0) {
|
||||
label.setLength(0);
|
||||
label.append(Resource.getString(ResourceConstants.THIRD_PARTIES));
|
||||
label.append(": ");
|
||||
|
||||
choices = new ChoiceGroup(label.toString(), ChoiceGroup.MULTIPLE);
|
||||
item = choices;
|
||||
|
||||
firstIndex = addCa((Ca)caList.elementAt(0));
|
||||
for (int i = 1; i < caList.size(); i++) {
|
||||
addCa((Ca)caList.elementAt(i));
|
||||
}
|
||||
|
||||
append(item);
|
||||
}
|
||||
|
||||
if (item == null) {
|
||||
append(new StringItem(null,
|
||||
Resource.getString(ResourceConstants.AMS_NO_CA_FOUND)));
|
||||
} else {
|
||||
addCommand(confirmCmd);
|
||||
}
|
||||
|
||||
addCommand(exitCmd);
|
||||
setCommandListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a command issued on any Screen.
|
||||
*
|
||||
* @param c command activated by the user
|
||||
* @param s the Displayable the command was on.
|
||||
*/
|
||||
public void commandAction(Command c, Displayable s) {
|
||||
if (c == confirmCmd) {
|
||||
confirmChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == exitCmd) {
|
||||
parent.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == saveCmd) {
|
||||
save();
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == cancelCmd) {
|
||||
display.setCurrent(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Add a CA to the form. */
|
||||
private int addCa(Ca ca) {
|
||||
int index = choices.append(ca.name, null);
|
||||
|
||||
choices.setSelectedIndex(index, ca.enabled);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Confirm the changes with the user. */
|
||||
private void confirmChanges() {
|
||||
boolean saveNeeded = false;
|
||||
enableSuites = new Vector();
|
||||
disableSuites = new Vector();
|
||||
|
||||
// Determine which CA's will be enabled.
|
||||
for (int i = 0; i < caList.size(); i++) {
|
||||
Ca ca = (Ca)caList.elementAt(i);
|
||||
ca.willBeEnabled = choices.isSelected(firstIndex + i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < caList.size(); i++) {
|
||||
Ca ca = (Ca)caList.elementAt(i);
|
||||
if (ca.willBeEnabled && !ca.enabled) {
|
||||
saveNeeded = true;
|
||||
addSuitesAuthorizedBy(ca, enableSuites);
|
||||
} else if (!ca.willBeEnabled && ca.enabled) {
|
||||
saveNeeded = true;
|
||||
addSuitesAuthorizedBy(ca, disableSuites);
|
||||
}
|
||||
}
|
||||
|
||||
if (!saveNeeded) {
|
||||
parent.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (disableSuites.size() == 0) {
|
||||
// we only confirm the disabling of suites
|
||||
save();
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuffer toBeDisabled = new StringBuffer();
|
||||
toBeDisabled.append(
|
||||
Resource.getString(ResourceConstants.AMS_SUITES_TO_BE_DISABLED));
|
||||
for (int i = 0; i < disableSuites.size(); i++) {
|
||||
if (i > 0) {
|
||||
toBeDisabled.append(",\n");
|
||||
}
|
||||
|
||||
toBeDisabled.append(
|
||||
((MIDletSuite)disableSuites.elementAt(i)).
|
||||
getProperty(MIDletSuiteImpl.SUITE_NAME_PROP));
|
||||
}
|
||||
|
||||
Alert a = new Alert(
|
||||
Resource.getString(ResourceConstants.AMS_CONFIRMATION),
|
||||
toBeDisabled.toString(), null, AlertType.WARNING);
|
||||
a.setTimeout(Alert.FOREVER);
|
||||
a.addCommand(cancelCmd);
|
||||
a.addCommand(saveCmd);
|
||||
a.setCommandListener(this);
|
||||
display.setCurrent(a);
|
||||
}
|
||||
|
||||
/** Save the enable status of Third Party certificate authorities. */
|
||||
private void save() {
|
||||
for (int i = 0; i < caList.size(); i++) {
|
||||
Ca ca = (Ca)caList.elementAt(i);
|
||||
if (ca.willBeEnabled && !ca.enabled) {
|
||||
WebPublicKeyStore.enableCertAuthority(ca.name);
|
||||
} else if (!ca.willBeEnabled && ca.enabled) {
|
||||
WebPublicKeyStore.disableCertAuthority(ca.name);
|
||||
}
|
||||
}
|
||||
|
||||
disableSuites(disableSuites);
|
||||
enableSuites(enableSuites);
|
||||
|
||||
display.setCurrent(null);
|
||||
parent.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of suites authorized by a CA.
|
||||
*
|
||||
* @param ca desired CA
|
||||
*
|
||||
* @return list of suites
|
||||
*/
|
||||
private void addSuitesAuthorizedBy(Ca ca, Vector suites) {
|
||||
int[] suiteIds = null;
|
||||
MIDletSuite midletSuite = null;
|
||||
InstallInfo installInfo = null;
|
||||
|
||||
suiteIds = suiteStorage.getListOfSuites();
|
||||
|
||||
for (int i = 0; i < suiteIds.length; i++) {
|
||||
try {
|
||||
midletSuite = suiteStorage.getMIDletSuite(suiteIds[i], false);
|
||||
} catch (Throwable t) {
|
||||
continue;
|
||||
}
|
||||
|
||||
installInfo = ((MIDletSuiteImpl)midletSuite).getInstallInfo();
|
||||
|
||||
String[] authPath = installInfo.getAuthPath();
|
||||
|
||||
if (authPath != null &&
|
||||
ca.name.equals(authPath[0])) {
|
||||
suites.addElement(midletSuite);
|
||||
continue;
|
||||
}
|
||||
|
||||
midletSuite.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a list suites. Closes each suite.
|
||||
*
|
||||
* @param suites list of MIDlet suites
|
||||
*/
|
||||
private void disableSuites(Vector suites) {
|
||||
MIDletSuite midletSuite = null;
|
||||
|
||||
for (int i = 0; i < suites.size(); i++) {
|
||||
midletSuite = (MIDletSuite)suites.elementAt(i);
|
||||
try {
|
||||
suiteStorage.disable(midletSuite.getID());
|
||||
} catch (Throwable t) {
|
||||
// nothing can be done
|
||||
}
|
||||
|
||||
midletSuite.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a list suites. Closes each suite.
|
||||
*
|
||||
* @param suites list of MIDlet suites
|
||||
*/
|
||||
private void enableSuites(Vector suites) {
|
||||
MIDletSuite midletSuite = null;
|
||||
|
||||
for (int i = 0; i < suites.size(); i++) {
|
||||
midletSuite = (MIDletSuite)suites.elementAt(i);
|
||||
try {
|
||||
suiteStorage.enable(midletSuite.getID());
|
||||
} catch (Throwable t) {
|
||||
// nothing can be done
|
||||
}
|
||||
|
||||
midletSuite.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a CA.
|
||||
*/
|
||||
class Ca {
|
||||
/** Name of the CA. */
|
||||
String name;
|
||||
|
||||
/** If true the CA is enabled. */
|
||||
boolean enabled;
|
||||
|
||||
/** If true the CA will be enabled after the user presses "save". */
|
||||
boolean willBeEnabled;
|
||||
|
||||
/**
|
||||
* Construct a CA.
|
||||
*
|
||||
* @param theName name of the CA
|
||||
* @param isEnabled true if the CA is enabled
|
||||
*/
|
||||
Ca(String theName, boolean isEnabled) {
|
||||
name = theName;
|
||||
enabled = isEnabled;
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.Display;
|
||||
|
||||
/**
|
||||
* Launches the component manager
|
||||
*/
|
||||
class ComponentManagerLauncher {
|
||||
/**
|
||||
* Launch the Component Manager
|
||||
* @param suiteId the ID of the suite of interest
|
||||
* @param display the Display object currently in use.
|
||||
* @param canModify true for full access, false for read-only access
|
||||
*/
|
||||
public static void componentView(int suiteId, Display display, boolean canModify) {
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import com.sun.midp.midletsuite.MIDletSuiteLockedException;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteCorruptedException;
|
||||
|
||||
/**
|
||||
* Displays error messages using the Display instance object passed
|
||||
* into the Constructor.
|
||||
*/
|
||||
class DisplayError {
|
||||
|
||||
/** The display instance to be used to display error alerts */
|
||||
Display display;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DisplayError instance given a display object.
|
||||
* @param display the Display instance where Alerts will the errors
|
||||
* will be shown
|
||||
*/
|
||||
DisplayError(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Alert with the error message.
|
||||
*
|
||||
* @param appName - name of the application in which the error happen
|
||||
* @param t - throwable that was thrown while performing one
|
||||
* of the operations on the application
|
||||
* @param alertTitle - if non-null it will be the Alert title, otherwise
|
||||
* a default value will be used
|
||||
* (Resource.getString(ResourceConstants.AMS_CANNOT_START))
|
||||
* @param alertMessage - if non-null it will be the Alert message,
|
||||
* otherwise a default message will be generated using
|
||||
* (Resource.getString(ResourceConstants.ERROR))
|
||||
*/
|
||||
void showErrorAlert(String appName, Throwable t,
|
||||
String alertTitle, String alertMessage) {
|
||||
showErrorAlert(appName, t, alertTitle, alertMessage, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Alert with the error message.
|
||||
*
|
||||
* @param appName - name of the application in which the error happen
|
||||
* @param t - throwable that was thrown while performing one
|
||||
* of the operations on the application
|
||||
* @param alertTitle - if non-null it will be the Alert title, otherwise
|
||||
* a default value will be used
|
||||
* (Resource.getString(ResourceConstants.AMS_CANNOT_START))
|
||||
* @param alertMessage - if non-null it will be the Alert message,
|
||||
* otherwise a default message will be generated using
|
||||
* (Resource.getString(ResourceConstants.ERROR))
|
||||
* @param nextDisplayable the Displayable to be shown after
|
||||
* the error alert is dismissed; can be null
|
||||
*/
|
||||
void showErrorAlert(String appName, Throwable t,
|
||||
String alertTitle, String alertMessage,
|
||||
Displayable nextDisplayable) {
|
||||
|
||||
if (alertMessage == null) {
|
||||
|
||||
if (t instanceof MIDletSuiteLockedException) {
|
||||
String[] values = new String[1];
|
||||
values[0] = appName;
|
||||
alertMessage = Resource.getString(
|
||||
ResourceConstants.AMS_MGR_UPDATE_IS_RUNNING,
|
||||
values);
|
||||
} else if (t instanceof MIDletSuiteCorruptedException) {
|
||||
String[] values = new String[1];
|
||||
values[0] = appName;
|
||||
alertMessage = Resource.getString(
|
||||
ResourceConstants.AMS_MIDLETSUITE_ID_CORRUPT_MSG,
|
||||
values);
|
||||
} else {
|
||||
|
||||
t.printStackTrace();
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
sb.append(appName);
|
||||
sb.append("\n");
|
||||
sb.append(Resource.getString(ResourceConstants.ERROR));
|
||||
sb.append(": ");
|
||||
sb.append(t.toString());
|
||||
alertMessage = sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (alertTitle == null) {
|
||||
alertTitle =
|
||||
Resource.getString(ResourceConstants.AMS_CANNOT_START);
|
||||
}
|
||||
Alert a = new Alert(alertTitle, alertMessage, null, AlertType.ERROR);
|
||||
a.setTimeout(Alert.FOREVER);
|
||||
|
||||
if (nextDisplayable == null) {
|
||||
display.setCurrent(a);
|
||||
} else {
|
||||
display.setCurrent(a, nextDisplayable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an alert screen when midlet suite is corrupted
|
||||
* @param msg Message to display on alert
|
||||
*/
|
||||
void showCorruptedSuiteAlert(String msg) {
|
||||
Alert a = new Alert(Resource.getString
|
||||
(ResourceConstants.AMS_CANT_ACCESS),
|
||||
msg, null, AlertType.ERROR);
|
||||
a.setTimeout(2000);
|
||||
display.setCurrent(a, display.getCurrent());
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.Image;
|
||||
|
||||
/**
|
||||
* Represents Folder object.
|
||||
*/
|
||||
class Folder {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param id folder ID
|
||||
* @param parentId parent folder ID
|
||||
* @param name folder's name
|
||||
* @param icon folder's icon
|
||||
*/
|
||||
Folder(int id, int parentId, String name, Image icon) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this folder's ID.
|
||||
*
|
||||
* @return ID of this folder
|
||||
*/
|
||||
public int getId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ID of this folder's parent.
|
||||
*
|
||||
* @return ID of the parent folder
|
||||
*/
|
||||
public int getParentId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a name of this folder.
|
||||
*
|
||||
* @return name this folder
|
||||
*/
|
||||
public String getName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an icon should be shown for this folder.
|
||||
*
|
||||
* @return icon of this folder
|
||||
*/
|
||||
public Image getIcon() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.appmanager.FolderManager;
|
||||
import com.sun.midp.appmanager.Folder;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
import java.util.Vector;
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
|
||||
/**
|
||||
* The list of exisitng MIDlet suite folders.
|
||||
* Used in AppManagerUI and GraphicalInstaller.
|
||||
*/
|
||||
public class FolderList extends javax.microedition.lcdui.List {
|
||||
|
||||
/**
|
||||
* vector of available folders.
|
||||
*/
|
||||
private Vector folders;
|
||||
|
||||
/**
|
||||
* Create and initialize a new Folder List.
|
||||
*/
|
||||
FolderList() {
|
||||
super(Resource.getString(
|
||||
ResourceConstants.AMS_SELECT_FOLDER), Choice.IMPLICIT);
|
||||
this.folders = null;
|
||||
setFitPolicy(TEXT_WRAP_OFF);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
private synchronized void refresh() {
|
||||
folders = FolderManager.getFolders();
|
||||
if (folders != null) {
|
||||
for (int i = 0; i < folders.size(); i++) {
|
||||
Folder f = (Folder)folders.elementAt(i);
|
||||
append(f.getName(), f.getIcon());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If folder list has any items.
|
||||
*/
|
||||
synchronized boolean hasItems() {
|
||||
if (folders != null) {
|
||||
return folders.size() > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gets currently selected folder or null if there is no selection
|
||||
*
|
||||
* @return folder
|
||||
*/
|
||||
public synchronized Folder getSelectedFolder() {
|
||||
int ind = getSelectedIndex();
|
||||
if (ind != -1) {
|
||||
return (Folder)(folders.elementAt(ind));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select item that correcponds to passed folder id
|
||||
* @param folderId
|
||||
*/
|
||||
public synchronized void setSelectedFolder(int folderId) {
|
||||
folders = FolderManager.getFolders();
|
||||
if (folders != null) {
|
||||
for (int i = 0; i < folders.size(); i++) {
|
||||
Folder f = (Folder)folders.elementAt(i);
|
||||
if (f.getId() == folderId) {
|
||||
this.setSelectedIndex(i, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Provides functionality to manage folders.
|
||||
*/
|
||||
class FolderManager {
|
||||
/** Folder ID that is never used. */
|
||||
public static final int UNUSED_FOLDER_ID = -1;
|
||||
|
||||
/**
|
||||
* ID of the folder where user applications
|
||||
* will be installed by default.
|
||||
*/
|
||||
public static final int DEFAULT_FOLDER_ID = 1;
|
||||
|
||||
/**
|
||||
* Returns the number of folders present in the system
|
||||
*
|
||||
* @return number of folders present in the system
|
||||
*/
|
||||
public static int getFolderCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector of folders present in the system
|
||||
*
|
||||
* @return vector of <code>Folder</code> objects
|
||||
*/
|
||||
public static Vector getFolders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ID of the folder where user applications
|
||||
* are installed by default.
|
||||
*
|
||||
* @return ID of the folder where user applications are installed by default
|
||||
*/
|
||||
public static int getDefaultFolderId() {
|
||||
return DEFAULT_FOLDER_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a folder with the given ID
|
||||
*
|
||||
* @param folderId ID of the folder to find
|
||||
*
|
||||
* @return <code>Folder</code> having the given ID or null if not found
|
||||
*/
|
||||
public static Folder getFolderById(int folderId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new folder.
|
||||
*
|
||||
* @param f folder to create
|
||||
*/
|
||||
public static void createFolder(Folder f) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a folder.
|
||||
*
|
||||
* @param f folder to delete
|
||||
*/
|
||||
public static void deleteFolder(Folder f) {
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
/**
|
||||
* Consumes MIDP_KILL_MIDLETS_EVENT sent by Graphical Installer when
|
||||
* updating a suite one or more midlets from which are running.
|
||||
*/
|
||||
interface InstallerEventConsumer {
|
||||
/**
|
||||
* Processes MIDP_KILL_MIDLETS_EVENT.
|
||||
*
|
||||
* @param suiteId ID of the midlet suite from which the midlets
|
||||
* must be killed
|
||||
* @param isolateId ID of the isolate requested this operation
|
||||
*/
|
||||
public void handleKillMIDletsEvent(int suiteId, int isolateId);
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.events.Event;
|
||||
import com.sun.midp.events.EventQueue;
|
||||
import com.sun.midp.events.EventListener;
|
||||
import com.sun.midp.events.NativeEvent;
|
||||
import com.sun.midp.events.EventTypes;
|
||||
|
||||
/**
|
||||
* Listener for Installer events.
|
||||
*/
|
||||
class InstallerEventListener implements EventListener {
|
||||
private InstallerEventConsumer eventConsumer;
|
||||
|
||||
/**
|
||||
* Package private constructor.
|
||||
*
|
||||
* @param eventQueue reference to the event queue
|
||||
* @param installerEventConsumer comsumer that will process events
|
||||
* received by this listener
|
||||
*/
|
||||
InstallerEventListener(
|
||||
EventQueue eventQueue,
|
||||
InstallerEventConsumer installerEventConsumer) {
|
||||
eventQueue.registerEventListener(
|
||||
EventTypes.MIDP_KILL_MIDLETS_EVENT, this);
|
||||
eventConsumer = installerEventConsumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess an event that is being posted to the event queue.
|
||||
*
|
||||
* @param event event being posted
|
||||
*
|
||||
* @param waitingEvent previous event of this type waiting in the
|
||||
* queue to be processed
|
||||
*
|
||||
* @return true to allow the post to continue, false to not post the
|
||||
* event to the queue
|
||||
*/
|
||||
public boolean preprocess(Event event, Event waitingEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes events.
|
||||
*
|
||||
* @param event event to process
|
||||
*/
|
||||
public void process(Event event) {
|
||||
if (event.getType() == EventTypes.MIDP_KILL_MIDLETS_EVENT) {
|
||||
NativeEvent ne = (NativeEvent)event;
|
||||
eventConsumer.handleKillMIDletsEvent(ne.intParam1, ne.intParam2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,596 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.installer.GraphicalInstaller;
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import javax.microedition.lcdui.CustomItem;
|
||||
import javax.microedition.lcdui.Graphics;
|
||||
import javax.microedition.lcdui.Command;
|
||||
import javax.microedition.lcdui.Image;
|
||||
import javax.microedition.lcdui.Font;
|
||||
import javax.microedition.lcdui.Form;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* The class is designed to present MIDlet or MIDlet suite item in Form container.
|
||||
* MIDletCustomItem consists of an icon and name associated with corresponding
|
||||
* MIDlet or MIDlet suite. Whether the name is too long and cannot fit the width
|
||||
* of a Form, the truncated name is shown with special truncation marker at the
|
||||
* end. When an item with truncated name is focused, full text of the name is
|
||||
* auto-scrolled to user. Also, the painting of the MIDlet/MIDlet suite item is
|
||||
* dependent on state of the application. It can indicate running, locked, disabled
|
||||
* state and availability of alert warnings related to the MIDlet application.
|
||||
*/
|
||||
class MIDletCustomItem extends CustomItem {
|
||||
/**
|
||||
* The font used to paint midlet names in the AppSelector.
|
||||
* Inner class cannot have static variables thus it has to be here.
|
||||
*/
|
||||
private static final Font ICON_FONT = Font.getFont(
|
||||
Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL);
|
||||
|
||||
/**
|
||||
* The font used to paint midlet names in the AppSelector.
|
||||
* Inner class cannot have static variables thus it has to be here.
|
||||
*/
|
||||
private static final Font ICON_FONT_UL = Font.getFont(
|
||||
Font.FACE_SYSTEM, Font.STYLE_BOLD | Font.STYLE_UNDERLINED,
|
||||
Font.SIZE_SMALL);
|
||||
|
||||
/**
|
||||
* The image used to draw background for the midlet representation.
|
||||
* IMPL NOTE: it is assumed that background image is larger or equal
|
||||
* than all other images that are painted over it
|
||||
*/
|
||||
private static final Image ICON_BG =
|
||||
GraphicalInstaller.getImageFromInternalStorage("_ch_hilight_bg");
|
||||
|
||||
/** The pad between custom item's icon and background icon image */
|
||||
private static final int ICON_PAD = 1;
|
||||
|
||||
/** Cached background image width */
|
||||
private static final int bgIconW = ICON_BG.getWidth();
|
||||
|
||||
/** Cached background image height */
|
||||
private static final int bgIconH = ICON_BG.getHeight();
|
||||
|
||||
/**
|
||||
* The icon used to display that user attention is requested
|
||||
* and that midlet needs to brought into foreground.
|
||||
*/
|
||||
private static final Image FG_REQUESTED =
|
||||
GraphicalInstaller.getImageFromInternalStorage("_ch_fg_requested");
|
||||
|
||||
/** The image used to draw disable midlet representation */
|
||||
private static final Image DISABLED_IMAGE =
|
||||
GraphicalInstaller.getImageFromInternalStorage("_ch_disabled");
|
||||
|
||||
/**
|
||||
* The color used to draw midlet name
|
||||
* for the hilighted non-running running midlet representation.
|
||||
*/
|
||||
private static final int ICON_HL_TEXT = 0x000B2876;
|
||||
|
||||
/**
|
||||
* The color used to draw the shadow of the midlet name
|
||||
* for the non hilighted non-running midlet representation.
|
||||
*/
|
||||
private static final int ICON_TEXT = 0x003177E2;
|
||||
|
||||
/**
|
||||
* The color used to draw the midlet name
|
||||
* for the non hilighted running midlet representation.
|
||||
*/
|
||||
private static final int ICON_RUNNING_TEXT = 0xbb0000;
|
||||
|
||||
/**
|
||||
* The color used to draw the midlet name
|
||||
* for the hilighted running midlet representation.
|
||||
*/
|
||||
private static final int ICON_RUNNING_HL_TEXT = 0xff0000;
|
||||
|
||||
/** The pad between custom item's icon and text */
|
||||
private static final int ITEM_PAD = 2;
|
||||
|
||||
/** Cached truncation mark */
|
||||
private static final char truncationMark =
|
||||
Resource.getString(ResourceConstants.TRUNCATION_MARK).charAt(0);
|
||||
|
||||
|
||||
/** Current locale */
|
||||
private String locale;
|
||||
|
||||
/** Layout direction. True if direction is right-to-left */
|
||||
private boolean rtlDirection;
|
||||
|
||||
/** Orientation of text, can be Graphics.RIGHT or Graphics.Left */
|
||||
private int textOrientation;
|
||||
|
||||
|
||||
/** A Timer which will handle firing repaints of the ScrollPainter */
|
||||
protected Timer textScrollTimer;
|
||||
|
||||
/** Text auto-scrolling parameters */
|
||||
private static int SCROLL_RATE = 250;
|
||||
private static int SCROLL_DELAY = 500;
|
||||
private static int SCROLL_SPEED = 10;
|
||||
|
||||
/** Default constructor */
|
||||
protected MIDletCustomItem() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
/** Constructs a MIDlet representation item */
|
||||
MIDletCustomItem(String displayName, Image midletIcon) {
|
||||
super(null);
|
||||
init(displayName, midletIcon);
|
||||
}
|
||||
|
||||
/** Init item instance */
|
||||
protected void init(String displayName, Image midletIcon) {
|
||||
icon = (midletIcon != null) ? midletIcon : getDefaultIcon();
|
||||
text = displayName.toCharArray();
|
||||
textLen = displayName.length();
|
||||
truncWidth = ICON_FONT.charWidth(truncationMark);
|
||||
truncated = false;
|
||||
textScrollTimer = null;
|
||||
xScrollOffset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum width of a MIDlet representation in the owner screen.
|
||||
* @return the minimum width of a MIDlet representation in the owner screen.
|
||||
*/
|
||||
protected int getMinContentWidth() {
|
||||
return owner.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum height of a midlet representation in the owner screen.
|
||||
* @return the minimum height of a MIDlet representation the owner screen.
|
||||
*/
|
||||
protected int getMinContentHeight() {
|
||||
return ICON_BG.getHeight() > ICON_FONT.getHeight() ?
|
||||
ICON_BG.getHeight() : ICON_FONT.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferred width of a midlet representation in
|
||||
* the owner screen based on the passed in height.
|
||||
*
|
||||
* @param height the amount of height available for this Item
|
||||
* @return the minimum width of a MIDlet representation in the owner screen.
|
||||
*/
|
||||
protected int getPrefContentWidth(int height) {
|
||||
return owner.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferred height of a midlet representation in
|
||||
* the App Selector Screen based on the passed in width.
|
||||
* @param width the amount of width available for this Item
|
||||
* @return the minimum height of a midlet representation
|
||||
* in the App Selector Screen.
|
||||
*/
|
||||
protected int getPrefContentHeight(int width) {
|
||||
return ICON_BG.getHeight() > ICON_FONT.getHeight() ?
|
||||
ICON_BG.getHeight() : ICON_FONT.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* On size change event we define the item's text
|
||||
* according to item's new width
|
||||
* @param w The current width of this Item
|
||||
* @param h The current height of this Item
|
||||
*/
|
||||
protected void sizeChanged(int w, int h) {
|
||||
stopScroll();
|
||||
width = w;
|
||||
height = h;
|
||||
int widthForText = w - ITEM_PAD - ICON_BG.getWidth();
|
||||
int displayNameWidth = ICON_FONT.charsWidth(text, 0, textLen);
|
||||
scrollWidth = displayNameWidth - widthForText + w/5;
|
||||
truncated = displayNameWidth > widthForText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default MIDlet icon
|
||||
* @return Image with default icon
|
||||
*/
|
||||
private static Image getDefaultIcon() {
|
||||
return GraphicalInstaller.
|
||||
getImageFromInternalStorage("_ch_single");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets running state of the MIDlet or MIDlte suite.
|
||||
* @return true is MIDlet is running or associated MIDlet suite has running
|
||||
* MIDlets, false otherwise
|
||||
*/
|
||||
boolean isRunning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets locked state of the MIDlet or MIDlet suite.
|
||||
* Locked states limits operations available for this item.
|
||||
* @return true if MIDlet or MIDlet suite is locked, false otherwise
|
||||
*/
|
||||
boolean isLocked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if alert is waiting for the foreground in at
|
||||
* least of one of the MIDlets from this suite.
|
||||
* @return true if there is a waiting alert
|
||||
*/
|
||||
boolean isAnyAlertWaiting() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this MIDlet or MIDlet suite item is enabled
|
||||
* @return true if the item is enabled
|
||||
*/
|
||||
boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the content of a midlet representation in
|
||||
* the App Selector Screen.
|
||||
* Note that icon representing that foreground was requested
|
||||
* is painted on to of the existing ickon.
|
||||
* @param g The graphics context where painting should be done
|
||||
* @param w The width available to this Item
|
||||
* @param h The height available to this Item
|
||||
*/
|
||||
protected void paint(Graphics g, int w, int h) {
|
||||
int cX = g.getClipX();
|
||||
int cY = g.getClipY();
|
||||
int cW = g.getClipWidth();
|
||||
int cH = g.getClipHeight();
|
||||
|
||||
// TODO: Don't check locale on each repaint, listen for
|
||||
// locale change events and update item state accordingly
|
||||
locale = System.getProperty("microedition.locale");
|
||||
if (locale != null && locale.equals("he-IL")) {
|
||||
rtlDirection = true;
|
||||
textOrientation = Graphics.RIGHT;
|
||||
} else {
|
||||
rtlDirection = false;
|
||||
textOrientation = Graphics.LEFT;
|
||||
}
|
||||
|
||||
if ((cW + cX) > bgIconW) {
|
||||
if (text != null && h >= ICON_FONT.getHeight()) {
|
||||
|
||||
int color;
|
||||
if (isRunning()) {
|
||||
color = hasFocus ?
|
||||
ICON_RUNNING_HL_TEXT : ICON_RUNNING_TEXT;
|
||||
} else {
|
||||
color = hasFocus ? ICON_HL_TEXT : ICON_TEXT;
|
||||
}
|
||||
|
||||
g.setColor(color);
|
||||
g.setFont(isLocked() ? ICON_FONT_UL : ICON_FONT);
|
||||
|
||||
boolean truncate = (xScrollOffset == 0) && truncated;
|
||||
|
||||
if (rtlDirection) {
|
||||
g.clipRect(truncate ? truncWidth + ITEM_PAD : ITEM_PAD, 0,
|
||||
truncate ? w - truncWidth - bgIconW - 2 * ITEM_PAD :
|
||||
w - bgIconW - 2 * ITEM_PAD, h);
|
||||
g.drawChars(text, 0, textLen,
|
||||
w - (bgIconW + ITEM_PAD + xScrollOffset),
|
||||
(h - ICON_FONT.getHeight())/2, textOrientation | Graphics.TOP);
|
||||
g.setClip(cX, cY, cW, cH);
|
||||
|
||||
if (truncate) {
|
||||
g.drawChar(truncationMark, truncWidth,
|
||||
(h - ICON_FONT.getHeight())/2, Graphics.RIGHT | Graphics.TOP);
|
||||
}
|
||||
} else {
|
||||
g.clipRect(bgIconW + ITEM_PAD, 0,
|
||||
truncate ? w - truncWidth - bgIconW - 2 * ITEM_PAD :
|
||||
w - bgIconW - 2 * ITEM_PAD, h);
|
||||
g.drawChars(text, 0, textLen,
|
||||
bgIconW + ITEM_PAD + xScrollOffset, (h - ICON_FONT.getHeight())/2,
|
||||
Graphics.LEFT | Graphics.TOP);
|
||||
g.setClip(cX, cY, cW, cH);
|
||||
|
||||
if (truncate) {
|
||||
g.drawChar(truncationMark, w - truncWidth,
|
||||
(h - ICON_FONT.getHeight())/2, Graphics.LEFT | Graphics.TOP);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int anchorY = (h - bgIconH)/2;
|
||||
final int ICON_PAD2 = ICON_PAD * 2;
|
||||
|
||||
if (cX < bgIconW) {
|
||||
if (rtlDirection) {
|
||||
if (hasFocus) {
|
||||
g.drawImage(ICON_BG, w - bgIconW, anchorY,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
}
|
||||
|
||||
if (icon != null) {
|
||||
g.clipRect(
|
||||
w - bgIconW + ICON_PAD, anchorY + ICON_PAD,
|
||||
bgIconW - ICON_PAD2, bgIconH - ICON_PAD2);
|
||||
g.drawImage(icon,
|
||||
w - (bgIconW - icon.getWidth())/2,
|
||||
anchorY + (bgIconH - icon.getHeight())/2,
|
||||
Graphics.TOP | Graphics.RIGHT);
|
||||
g.setClip(cX, cY, cW, cH);
|
||||
}
|
||||
// Draw special icon if user attention is requested and
|
||||
// that midlet needs to be brought into foreground by the user
|
||||
if (isAnyAlertWaiting()) {
|
||||
g.drawImage(FG_REQUESTED,
|
||||
w - (bgIconW - FG_REQUESTED.getWidth()), 0,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
}
|
||||
|
||||
if (!isEnabled()) {
|
||||
// indicate that this suite is disabled
|
||||
g.drawImage(DISABLED_IMAGE,
|
||||
w - (bgIconW - DISABLED_IMAGE.getWidth())/2,
|
||||
anchorY + (bgIconH - DISABLED_IMAGE.getHeight())/2,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
}
|
||||
} else {
|
||||
if (hasFocus) {
|
||||
g.drawImage(ICON_BG, 0, anchorY,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
}
|
||||
|
||||
if (icon != null) {
|
||||
g.clipRect(
|
||||
ICON_PAD, anchorY + ICON_PAD,
|
||||
bgIconW - ICON_PAD2, bgIconH - ICON_PAD2);
|
||||
g.drawImage(icon,
|
||||
(bgIconW - icon.getWidth())/2,
|
||||
anchorY + (bgIconH - icon.getHeight())/2,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
g.setClip(cX, cY, cW, cH);
|
||||
}
|
||||
|
||||
// Draw special icon if user attention is requested and
|
||||
// that midlet needs to be brought into foreground by the user
|
||||
if (isAnyAlertWaiting()) {
|
||||
g.drawImage(FG_REQUESTED,
|
||||
bgIconW - FG_REQUESTED.getWidth(), 0,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
}
|
||||
|
||||
if (!isEnabled()) {
|
||||
// indicate that this suite is disabled
|
||||
g.drawImage(DISABLED_IMAGE,
|
||||
(bgIconW - DISABLED_IMAGE.getWidth())/2,
|
||||
anchorY + (bgIconH - DISABLED_IMAGE.getHeight())/2,
|
||||
Graphics.TOP | Graphics.LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the scrolling of the text
|
||||
*/
|
||||
protected void startScroll() {
|
||||
if (!hasFocus || !truncated) {
|
||||
return;
|
||||
}
|
||||
stopScroll();
|
||||
if (textScrollTimer == null) {
|
||||
textScrollTimer = new Timer();
|
||||
}
|
||||
textScrollPainter = new TextScrollPainter();
|
||||
textScrollTimer.schedule(textScrollPainter, SCROLL_DELAY, SCROLL_RATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the scrolling of the text
|
||||
*/
|
||||
protected void stopScroll() {
|
||||
if (textScrollPainter == null) {
|
||||
return;
|
||||
}
|
||||
xScrollOffset = 0;
|
||||
textScrollPainter.cancel();
|
||||
textScrollPainter = null;
|
||||
if (rtlDirection) {
|
||||
repaint(0, 0, width, height);
|
||||
} else {
|
||||
repaint(bgIconW, 0, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called repeatedly to animate a side-scroll effect for text
|
||||
*/
|
||||
protected void repaintScrollText() {
|
||||
if (-xScrollOffset < scrollWidth) {
|
||||
xScrollOffset -= SCROLL_SPEED;
|
||||
if (rtlDirection) {
|
||||
repaint(0, 0, width, height);
|
||||
} else {
|
||||
repaint(bgIconW, 0, width, height);
|
||||
}
|
||||
|
||||
} else {
|
||||
// already scrolled to the end of text
|
||||
stopScroll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles traversal.
|
||||
* @param dir The direction of traversal (Canvas.UP, Canvas.DOWN,
|
||||
* Canvas.LEFT, Canvas.RIGHT)
|
||||
* @param viewportWidth The width of the viewport in the AppSelector
|
||||
* @param viewportHeight The height of the viewport in the AppSelector
|
||||
* @param visRect_inout The return array that tells AppSelector
|
||||
* which portion of the MidletCustomItem has to be made visible
|
||||
* @return true if traversal was handled in this method
|
||||
* (this MidletCustomItem just got focus or there was an
|
||||
* internal traversal), otherwise false - to transfer focus
|
||||
* to the next item
|
||||
*/
|
||||
protected boolean traverse(int dir,
|
||||
int viewportWidth, int viewportHeight,
|
||||
int visRect_inout[]) {
|
||||
// Entirely visible and hasFocus
|
||||
if (!hasFocus) {
|
||||
hasFocus = true;
|
||||
}
|
||||
|
||||
visRect_inout[0] = 0;
|
||||
visRect_inout[1] = 0;
|
||||
visRect_inout[2] = width;
|
||||
visRect_inout[3] = height;
|
||||
|
||||
startScroll();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles traversal out. This method is called when this
|
||||
* MidletCustomItem looses focus.
|
||||
*/
|
||||
protected void traverseOut() {
|
||||
hasFocus = false;
|
||||
stopScroll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repaints MidletCustomItem. Called when internal state changes.
|
||||
*/
|
||||
public void update() {
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the owner of this MIDletCustomItem
|
||||
* @param form in which this MIDletCustomItem is shown
|
||||
*/
|
||||
void setOwner(Form form) {
|
||||
owner = form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by owner when destroyApp happens to clean up data.
|
||||
* Timer that shedules scrolling text repainting should be
|
||||
* canceled when AMS MIDlet is about to be destroyed to avoid
|
||||
* generation of repaint events.
|
||||
*/
|
||||
public void cleanUp() {
|
||||
if (textScrollTimer != null) {
|
||||
textScrollTimer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default <code>Command</code> for this <code>Item</code>.
|
||||
*
|
||||
* @param c the command to be used as this <code>Item's</code> default
|
||||
* <code>Command</code>, or <code>null</code> if there is to
|
||||
* be no default command
|
||||
*/
|
||||
public void setDefaultCommand(Command c) {
|
||||
defaultCommand = c;
|
||||
super.setDefaultCommand(c);
|
||||
}
|
||||
|
||||
/** A TimerTask which will repaint scrolling text on a repeated basis */
|
||||
protected TextScrollPainter textScrollPainter;
|
||||
|
||||
/** Width of the scroll area for text */
|
||||
protected int scrollWidth;
|
||||
|
||||
/** If text is truncated */
|
||||
boolean truncated;
|
||||
|
||||
/**
|
||||
* Pixel offset to the start of the text field (for example, if
|
||||
* xScrollOffset is -60 it means means that the text in this
|
||||
* text field is scrolled 60 pixels left of the left edge of the
|
||||
* text field)
|
||||
*/
|
||||
protected int xScrollOffset;
|
||||
|
||||
/** Helper class used to repaint scrolling text if needed */
|
||||
private class TextScrollPainter extends TimerTask {
|
||||
/** Repaint the item text */
|
||||
public final void run() {
|
||||
repaintScrollText();
|
||||
}
|
||||
}
|
||||
|
||||
/** True if this MidletCustomItem has focus, and false - otherwise */
|
||||
boolean hasFocus;
|
||||
|
||||
/**
|
||||
* The owner of this MIDletCustomItem
|
||||
* IMPL_NOTE: This field has the same name with package private
|
||||
* Item.owner, however the field values are independent.
|
||||
*/
|
||||
Form owner;
|
||||
|
||||
/** The width of this MidletCustomItem */
|
||||
int width;
|
||||
/** The height of this MIDletSuiteInfo */
|
||||
int height;
|
||||
|
||||
/** Cashed width of the truncation mark */
|
||||
int truncWidth;
|
||||
|
||||
/** The text of this MIDletCustomItem*/
|
||||
char[] text;
|
||||
|
||||
/** Length of the text */
|
||||
int textLen;
|
||||
|
||||
/** The icon to be used to draw this midlet representation */
|
||||
Image icon;
|
||||
|
||||
/** Current default command */
|
||||
Command defaultCommand;
|
||||
}
|
|
@ -1,372 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
import com.sun.midp.main.MIDletProxyList;
|
||||
import com.sun.midp.main.MIDletProxy;
|
||||
import com.sun.midp.midlet.MIDletSuite;
|
||||
import com.sun.midp.midletsuite.MIDletInfo;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteCorruptedException;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteLockedException;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteStorage;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Selector provides a simple user interface to select MIDlets to run.
|
||||
* It extracts the list of MIDlets from the attributes in the
|
||||
* descriptor file and presents them to the user using the MIDlet-<n>
|
||||
* name and icon if any. When the user selects a MIDlet an instance
|
||||
* of the class indicated by MIDlet-<n> classname is created.
|
||||
*/
|
||||
final class MIDletSelector implements CommandListener, ItemCommandListener {
|
||||
/** The Form with list of all the MIDlets */
|
||||
private Form mform;
|
||||
|
||||
/** Information needed to display a list of MIDlets */
|
||||
private RunningMIDletSuiteInfo suiteInfo;
|
||||
|
||||
/** The Display */
|
||||
private Display display;
|
||||
|
||||
/** The parent's display able */
|
||||
private Displayable parentDisplayable;
|
||||
|
||||
/** Parent app manager */
|
||||
ApplicationManager manager;
|
||||
|
||||
/** Number of midlets in minfo */
|
||||
private int mcount;
|
||||
|
||||
/** MIDlet information, class, name, icon; one per MIDlet */
|
||||
private MIDletInfo[] minfo;
|
||||
|
||||
/**The Command object to exit back to the MIDlet Suite Manager */
|
||||
private Command backCmd = new Command(Resource.getString
|
||||
(ResourceConstants.BACK),
|
||||
Command.BACK, 2);
|
||||
|
||||
/** The Command object for "Launch" */
|
||||
private Command launchCmd = new Command(Resource.getString
|
||||
(ResourceConstants.LAUNCH),
|
||||
Command.ITEM, 1);
|
||||
|
||||
/** The Command object for "End" midlet */
|
||||
private Command endCmd = new Command(Resource.getString
|
||||
(ResourceConstants.END),
|
||||
Command.ITEM, 1);
|
||||
|
||||
|
||||
/**
|
||||
* Create and initialize a new Selector MIDlet.
|
||||
* The Display is retrieved and the list of MIDlets read
|
||||
* from the descriptor file.
|
||||
*
|
||||
* @param theSuiteInfo information needed to display a list of MIDlets
|
||||
* @param theDisplay the Display
|
||||
* @param theParentDisplayable the parent's displayable
|
||||
* @param theManager the parent application manager
|
||||
*
|
||||
* @throws MIDletSuiteCorruptedException if the suite is corrupted
|
||||
* @throws MIDletSuiteLockedException if the suite is locked
|
||||
*/
|
||||
MIDletSelector(RunningMIDletSuiteInfo theSuiteInfo, Display theDisplay,
|
||||
Displayable theParentDisplayable,
|
||||
ApplicationManager theManager)
|
||||
throws MIDletSuiteCorruptedException, MIDletSuiteLockedException {
|
||||
|
||||
MIDletSuiteStorage mss;
|
||||
|
||||
suiteInfo = theSuiteInfo;
|
||||
display = theDisplay;
|
||||
parentDisplayable = theParentDisplayable;
|
||||
manager = theManager;
|
||||
mcount = 0;
|
||||
minfo = new MIDletInfo[20];
|
||||
|
||||
mss = MIDletSuiteStorage.getMIDletSuiteStorage();
|
||||
|
||||
readMIDletInfo(mss);
|
||||
setupForm(mss);
|
||||
|
||||
mform.addCommand(backCmd);
|
||||
mform.setCommandListener(this);
|
||||
|
||||
display.setCurrent(mform);
|
||||
|
||||
/* for locked suite, we need storage lock until some MIDlet is launched.
|
||||
* This prevents reinstallation of the locked suite. */
|
||||
if (suiteInfo.isLocked()) {
|
||||
suiteInfo.grabStorageLock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets structure containing information about suite accessible by this
|
||||
* selector.
|
||||
* @return the suite info
|
||||
*/
|
||||
public RunningMIDletSuiteInfo getSuiteInfo() {
|
||||
return suiteInfo;
|
||||
}
|
||||
|
||||
/** Displays this selector on the screen */
|
||||
public void show() {
|
||||
refreshList();
|
||||
display.setCurrent(mform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when MIDlet execution exited.
|
||||
* Removes the MIDlet from list of running MIDlets and shows selector on the
|
||||
* screen.
|
||||
* @param midlet ClassName of MIDlet which just exited
|
||||
*/
|
||||
public void notifyMidletExited(String midlet) {
|
||||
|
||||
/* If main MIDlet is exited and all other MIDlets as well, exit the
|
||||
* selector. */
|
||||
if (!suiteInfo.hasRunningMidlet() && suiteInfo.hasMainMidlet()) {
|
||||
leaveSelector();
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no more MIDlets are running from a locked suite, we need
|
||||
* the storage lock until another MIDlet is launched. This prevents
|
||||
* reinstallation of the locked suite. */
|
||||
if (!suiteInfo.hasRunningMidlet() && suiteInfo.isLocked()) {
|
||||
suiteInfo.grabStorageLock();
|
||||
}
|
||||
|
||||
refreshList();
|
||||
}
|
||||
|
||||
/** If no MIDlet is running, exits the suite */
|
||||
public void exitIfNoMidletRuns() {
|
||||
if (!suiteInfo.hasRunningMidlet()) {
|
||||
if (suiteInfo.holdsStorageLock()) {
|
||||
suiteInfo.releaseStorageLock();
|
||||
}
|
||||
if (suiteInfo.isLocked()) {
|
||||
suiteInfo.unlock();
|
||||
}
|
||||
manager.notifyMIDletSelectorExited(suiteInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a command issued on any Screen.
|
||||
* The commands on list is Select and About.
|
||||
* Select triggers the creation of the MIDlet of the same name.
|
||||
* About puts up the copyright notice.
|
||||
*
|
||||
* @param c command activated by the user
|
||||
* @param s the Displayable the command was on.
|
||||
*/
|
||||
public void commandAction(Command c, Displayable s) {
|
||||
if (c == backCmd) {
|
||||
leaveSelector();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves the MIDlet selector.
|
||||
*/
|
||||
public void leaveSelector() {
|
||||
if (parentDisplayable != null) {
|
||||
display.setCurrent(parentDisplayable);
|
||||
} else {
|
||||
manager.shutDown();
|
||||
}
|
||||
exitIfNoMidletRuns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to a command issued on an Item in MIDlet selector
|
||||
* @param c command activated by the user
|
||||
* @param item the Item the command was on.
|
||||
*/
|
||||
public void commandAction(Command c, Item item) {
|
||||
int selected = ((SelectorMIDletCustomItem)item).index;
|
||||
if (selected < 0 || selected >= mcount) {
|
||||
return;
|
||||
}
|
||||
|
||||
String midletClassName = minfo[selected].classname;
|
||||
if (c == launchCmd) {
|
||||
|
||||
if (suiteInfo.getProxyFor(midletClassName) != null) {
|
||||
manager.moveToForeground(suiteInfo, midletClassName);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if we hold a storage lock, release it to allow the started MIDlet
|
||||
* to take it */
|
||||
if (suiteInfo.holdsStorageLock()) {
|
||||
suiteInfo.releaseStorageLock();
|
||||
}
|
||||
|
||||
manager.launchSuite(suiteInfo, midletClassName);
|
||||
|
||||
} else if (c == endCmd) {
|
||||
|
||||
manager.exitMidlet(suiteInfo, midletClassName);
|
||||
display.setCurrent(mform);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the set of MIDlet names, icons and classes
|
||||
* Fill in the list.
|
||||
*
|
||||
* @param mss the midlet suite storage
|
||||
*/
|
||||
private void setupForm(MIDletSuiteStorage mss) {
|
||||
MIDletProxyList mpl = MIDletProxyList.getMIDletProxyList();
|
||||
if (mform == null) {
|
||||
mform = new Form(Resource.getString
|
||||
(ResourceConstants.AMS_SELECTOR_SEL_TO_LAUNCH));
|
||||
|
||||
// Add each midlet
|
||||
for (int i = 0; i < mcount; i++) {
|
||||
Image icon = null;
|
||||
if (minfo[i].icon != null) {
|
||||
icon = RunningMIDletSuiteInfo.getIcon(
|
||||
suiteInfo.suiteId, minfo[i].icon, mss);
|
||||
}
|
||||
// the MIDlet is running iff the MIDlet proxy is found
|
||||
MIDletProxy mp = mpl.findMIDletProxy(
|
||||
suiteInfo.suiteId, minfo[i].classname);
|
||||
|
||||
SelectorMIDletCustomItem mci =
|
||||
new SelectorMIDletCustomItem(minfo[i].name, icon, i);
|
||||
|
||||
mci.updateState(mp);
|
||||
mci.addCommand(launchCmd);
|
||||
mci.addCommand(endCmd);
|
||||
mci.setDefaultCommand(launchCmd);
|
||||
mci.setOwner(mform);
|
||||
mci.setItemCommandListener(this);
|
||||
|
||||
mform.append(mci);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Refreshes the MIDlet list, showing the updated statuses */
|
||||
private void refreshList() {
|
||||
MIDletProxyList mpl = MIDletProxyList.getMIDletProxyList();
|
||||
for (int i = 0; i < mcount; i++) {
|
||||
SelectorMIDletCustomItem mci = (SelectorMIDletCustomItem)mform.get(i);
|
||||
int index = mci.index;
|
||||
MIDletProxy mp = mpl.findMIDletProxy(
|
||||
suiteInfo.suiteId, minfo[index].classname);
|
||||
mci.updateState(mp);
|
||||
mci.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in and create a MIDletInfo for each MIDlet-<n>
|
||||
*
|
||||
* @param mss the midlet suite storage
|
||||
* @throws MIDletSuiteCorruptedException if the suite is corrupted
|
||||
* @throws MIDletSuiteLockedException if the suite is locked
|
||||
*/
|
||||
private void readMIDletInfo(MIDletSuiteStorage mss)
|
||||
throws MIDletSuiteCorruptedException, MIDletSuiteLockedException {
|
||||
MIDletSuite midletSuite = mss.getMIDletSuite(suiteInfo.suiteId, false);
|
||||
|
||||
if (midletSuite == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (int n = 1; n < 100; n++) {
|
||||
String nth = "MIDlet-"+ n;
|
||||
String attr = midletSuite.getProperty(nth);
|
||||
if (attr == null || attr.length() == 0)
|
||||
break;
|
||||
|
||||
addMIDlet(new MIDletInfo(attr));
|
||||
}
|
||||
} finally {
|
||||
midletSuite.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a MIDlet to the list.
|
||||
* @param info MIDlet information to add to MIDlet
|
||||
*/
|
||||
private void addMIDlet(MIDletInfo info) {
|
||||
if (mcount >= minfo.length) {
|
||||
MIDletInfo[] n = new MIDletInfo[mcount+4];
|
||||
System.arraycopy(minfo, 0, n, 0, mcount);
|
||||
minfo = n;
|
||||
}
|
||||
|
||||
minfo[mcount++] = info;
|
||||
}
|
||||
|
||||
/** The inner class to represent MIDlet items in the MIDlet Selector screen */
|
||||
class SelectorMIDletCustomItem extends MIDletCustomItem {
|
||||
/** Predefined index of the item in the form */
|
||||
int index;
|
||||
/** Running state of the item */
|
||||
boolean isActive;
|
||||
|
||||
/**
|
||||
* Constructs new item
|
||||
* @param displayName MIDlet name
|
||||
* @param icon MIDlet icon
|
||||
* @param index index in the list of MIDlets
|
||||
*/
|
||||
SelectorMIDletCustomItem(String displayName, Image icon, int index) {
|
||||
super(displayName, icon);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates state of the MIDlet item
|
||||
* @param midletProxy MIDlet proxy of running MIDlet item
|
||||
*/
|
||||
void updateState(MIDletProxy midletProxy) {
|
||||
isActive = (midletProxy != null &&
|
||||
MIDletProxy.MIDLET_ACTIVE == midletProxy.getMidletState());
|
||||
}
|
||||
|
||||
/** Overrides #MIDletCustomItem.isRunning() */
|
||||
boolean isRunning() {
|
||||
return isActive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.midlet.*;
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import com.sun.midp.main.MIDletSuiteUtils;
|
||||
import com.sun.midp.midletsuite.*;
|
||||
|
||||
public class MIDletSuiteLauncher extends MIDlet implements ApplicationManager {
|
||||
|
||||
/** MIDlet Suite storage object. */
|
||||
private MIDletSuiteStorage midletSuiteStorage;
|
||||
|
||||
/** UI to display error alerts. */
|
||||
private DisplayError displayError;
|
||||
|
||||
/** Display for the Launcher MIDlet. */
|
||||
Display display;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public MIDletSuiteLauncher() {
|
||||
Display display = Display.getDisplay(this);
|
||||
displayError = new DisplayError(display);
|
||||
|
||||
midletSuiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
|
||||
|
||||
try {
|
||||
String suiteID = getAppProperty("arg-0");
|
||||
int id = Integer.parseInt(suiteID);
|
||||
MIDletSuiteImpl midletSuite =
|
||||
midletSuiteStorage.getMIDletSuite(id, false);
|
||||
|
||||
if (midletSuite == null) {
|
||||
/*
|
||||
* check if the suite is the index of the suite
|
||||
* as returned by -Xjam:list
|
||||
*/
|
||||
try {
|
||||
int suiteIndex = id - 1;
|
||||
int[] suites = midletSuiteStorage.getListOfSuites();
|
||||
id = suites[suiteIndex];
|
||||
midletSuite = midletSuiteStorage.getMIDletSuite(id, false);
|
||||
} catch (Exception e) {
|
||||
displayError.showErrorAlert("MIDlet Suite not found",
|
||||
e, null,
|
||||
"MIDlet Suite " +
|
||||
suiteID + " not found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RunningMIDletSuiteInfo suiteInfo =
|
||||
new RunningMIDletSuiteInfo(id, midletSuite, midletSuiteStorage);
|
||||
|
||||
if (suiteInfo.hasSingleMidlet()) {
|
||||
launchSuite(suiteInfo, suiteInfo.midletToRun);
|
||||
} else {
|
||||
new MIDletSelector(suiteInfo, display, null, this);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void startApp() throws MIDletStateChangeException {
|
||||
}
|
||||
|
||||
protected void pauseApp() {
|
||||
}
|
||||
|
||||
protected void destroyApp(boolean unconditional) {
|
||||
}
|
||||
|
||||
/** Discover and install a suite. */
|
||||
public void installSuite() {
|
||||
}
|
||||
|
||||
/** Launch the CA manager. */
|
||||
public void launchCaManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the component manager.
|
||||
*/
|
||||
public void launchComponentManager() {
|
||||
}
|
||||
|
||||
/** Launch ODT Agent. */
|
||||
public void launchODTAgent() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a suite.
|
||||
*
|
||||
* @param suiteInfo information for suite to launch
|
||||
* @param midletToRun class name of the MIDlet to launch
|
||||
*/
|
||||
public void launchSuite(RunningMIDletSuiteInfo suiteInfo,
|
||||
String midletToRun) {
|
||||
try {
|
||||
// Create an instance of the MIDlet class
|
||||
// All other initialization happens in MIDlet constructor
|
||||
MIDletSuiteUtils.execute(suiteInfo.suiteId, midletToRun, null);
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(suiteInfo.displayName, ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a suite.
|
||||
*
|
||||
* @param suiteInfo information for suite to update
|
||||
*/
|
||||
public void updateSuite(RunningMIDletSuiteInfo suiteInfo) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut downt the system
|
||||
*/
|
||||
public void shutDown() {
|
||||
destroyApp(false);
|
||||
notifyDestroyed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bring the midlet with the passed in midlet suite info to the
|
||||
* foreground.
|
||||
*
|
||||
* @param suiteInfo information for the midlet to be put to foreground
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
public void moveToForeground(RunningMIDletSuiteInfo suiteInfo, String className) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit the midlet with the passed in midlet suite info.
|
||||
*
|
||||
* @param suiteInfo information for the midlet to be terminated
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
public void exitMidlet(RunningMIDletSuiteInfo suiteInfo, String className) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exit of MIDlet suite (the only MIDlet in sute exited or MIDlet
|
||||
* selector exited).
|
||||
* @param suiteInfo Containing ID of exited suite
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
public void notifySuiteExited(RunningMIDletSuiteInfo suiteInfo, String className) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exit of MIDlet selector.
|
||||
* @param suiteInfo Containing ID of suite
|
||||
*/
|
||||
public void notifyMIDletSelectorExited(RunningMIDletSuiteInfo suiteInfo) {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
import com.sun.midp.configurator.Constants;
|
||||
import com.sun.midp.main.MIDletProxy;
|
||||
import com.sun.midp.ams.VMUtils;
|
||||
|
||||
/**
|
||||
* The Graphical MIDlet swicher.
|
||||
*
|
||||
* Switcher provides a simple user interface to select MIDlets to
|
||||
* bring into foreground from the list of running midlets.
|
||||
*/
|
||||
|
||||
class MIDletSwitcher extends javax.microedition.lcdui.Form
|
||||
implements ItemCommandListener {
|
||||
|
||||
/** Number of midlets in minfo */
|
||||
private int mcount;
|
||||
|
||||
/** MIDlet information, class, name, icon; one per MIDlet */
|
||||
private MidletListEntry[] minfo;
|
||||
|
||||
/** Number of reserved elements in minfo array */
|
||||
private final int pitch = 4;
|
||||
|
||||
/** Application Manager */
|
||||
ApplicationManager manager;
|
||||
|
||||
/** Application Manager main form */
|
||||
AppManagerUI managerUI;
|
||||
|
||||
/** Display for the Manager MIDlet */
|
||||
Display display; // = null
|
||||
|
||||
/** Command object for "Bring to foreground". */
|
||||
private Command fgCmd = new Command(Resource.getString
|
||||
(ResourceConstants.AMS_SWITCHER_SEL), Command.ITEM, 1);
|
||||
/**
|
||||
* Create and initialize a new MIDlet Switcher.
|
||||
*
|
||||
* @param managerUI the aplication manager main form
|
||||
* @param manager the parent application manager
|
||||
* @param display the Display
|
||||
*/
|
||||
MIDletSwitcher(AppManagerUI managerUI, ApplicationManager manager,
|
||||
Display display) {
|
||||
super("");
|
||||
this.manager = manager;
|
||||
this.managerUI = managerUI;
|
||||
this.display = display;
|
||||
mcount = 0;
|
||||
minfo = new MidletListEntry[VMUtils.getMaxIsolates()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Append launched suite info to the list.
|
||||
*
|
||||
* @param msi RunningMIDletSuiteInfo to append
|
||||
* @param className the MIDlet class name
|
||||
*/
|
||||
synchronized void append(RunningMIDletSuiteInfo msi, String className) {
|
||||
checkInfoArraySize();
|
||||
MidletListEntry mle = new MidletListEntry(msi, className);
|
||||
minfo[mcount++] = mle;
|
||||
|
||||
SwitcherMIDletCustomItem mci = new SwitcherMIDletCustomItem(mle);
|
||||
mci.setItemCommandListener(this);
|
||||
mci.setDefaultCommand(fgCmd);
|
||||
mci.addCommand(fgCmd);
|
||||
mci.setOwner(this);
|
||||
append(mci);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the existing item in the list.
|
||||
* It should be used to update the reference to the previously added object.
|
||||
*
|
||||
* @param oldMsi entry to update
|
||||
* @param newMsi new value of the entry
|
||||
*/
|
||||
synchronized void update(RunningMIDletSuiteInfo oldMsi,
|
||||
RunningMIDletSuiteInfo newMsi) {
|
||||
// IMPL_NOTE: our implementation stores a reference
|
||||
// to the RunningMIDletSuiteInfo object that gets modified elsewhere;
|
||||
// therefore, we do not need to copy any information from newMsi
|
||||
// to oldMsi.
|
||||
// Note also that our implementation implies that the
|
||||
// RunningMIDletSuiteInfo objects are unique, one per midlet suite,
|
||||
// and compares them using ==.
|
||||
|
||||
// IMPL_NOTE: The fields that may be changed are all mentioned in
|
||||
// AppManagerPeer.updateContent().
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove suite info from the list.
|
||||
*
|
||||
* @param msi RunningMIDletSuiteInfo to remove
|
||||
* @param className the MIDlet class name
|
||||
*/
|
||||
synchronized void remove(RunningMIDletSuiteInfo msi, String className) {
|
||||
int pos = -1;
|
||||
|
||||
for (int i = 0; i < mcount; i++) {
|
||||
// IMPL_NOTE: the suiteId check will be removed as soon
|
||||
// as we maintain all RunningMIDletSuiteInfo lists
|
||||
if ((minfo[i].suite == msi || minfo[i].suite.suiteId == msi.suiteId)
|
||||
&& (minfo[i].className == null || className == null ||
|
||||
minfo[i].className.equals(className))) {
|
||||
|
||||
// IMPL_NOTE: two instances of
|
||||
// the same MIDlet cannot be running
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos >= 0) {
|
||||
for (int i = pos+1; i < mcount; i++) {
|
||||
minfo[i-1] = minfo[i];
|
||||
}
|
||||
mcount--;
|
||||
checkInfoArraySize();
|
||||
delete(pos);
|
||||
}
|
||||
}
|
||||
|
||||
/** Ensures that info array has enough capacity */
|
||||
private void checkInfoArraySize() {
|
||||
if ((mcount+pitch < minfo.length) || (mcount >= minfo.length)) {
|
||||
MidletListEntry[] n =
|
||||
new MidletListEntry[mcount+pitch];
|
||||
System.arraycopy(minfo, 0, n, 0, mcount);
|
||||
minfo = n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the switcher has any items, that is, if there are any running MIDlet(s).
|
||||
* @return true if MIDlet(s) are running
|
||||
*/
|
||||
synchronized boolean hasItems() {
|
||||
return (mcount > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a command issued on form item
|
||||
* @param command command activated by the user
|
||||
* @param item form item to apply command to
|
||||
*/
|
||||
public synchronized void commandAction(Command command, Item item) {
|
||||
if (command == fgCmd) {
|
||||
//bring to foreground appropriate midlet
|
||||
MidletListEntry mle = ((SwitcherMIDletCustomItem)item).mle;
|
||||
manager.moveToForeground(mle.suite, mle.className);
|
||||
display.setCurrent(managerUI.getMainDisplayable());
|
||||
}
|
||||
}
|
||||
|
||||
class MidletListEntry {
|
||||
RunningMIDletSuiteInfo suite;
|
||||
String className;
|
||||
|
||||
public MidletListEntry(RunningMIDletSuiteInfo msi, String midletClassName) {
|
||||
suite = msi;
|
||||
className = midletClassName;
|
||||
}
|
||||
}
|
||||
|
||||
class SwitcherMIDletCustomItem extends MIDletCustomItem {
|
||||
/** MIDlet list entry associated with the item*/
|
||||
MidletListEntry mle;
|
||||
|
||||
/**
|
||||
* Constructs new MIDlet item
|
||||
* @param midletListEntry MIDlet list entry to create item for
|
||||
*/
|
||||
SwitcherMIDletCustomItem(MidletListEntry midletListEntry) {
|
||||
String className = midletListEntry.className;
|
||||
RunningMIDletSuiteInfo msi = midletListEntry.suite;
|
||||
MIDletProxy midletProxy = msi.getProxyFor(className);
|
||||
StringBuffer name = new StringBuffer(msi.displayName);
|
||||
if (midletProxy != null) {
|
||||
name.append('/');
|
||||
name.append(midletProxy.getDisplayName());
|
||||
}
|
||||
init(name.toString(), msi.icon);
|
||||
this.mle = midletListEntry;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,430 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.midlet.*;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
|
||||
import com.sun.midp.midlet.*;
|
||||
|
||||
import com.sun.midp.installer.*;
|
||||
|
||||
import com.sun.midp.midletsuite.*;
|
||||
|
||||
import com.sun.midp.main.*;
|
||||
|
||||
import com.sun.midp.configurator.Constants;
|
||||
import com.sun.midp.events.EventQueue;
|
||||
|
||||
/**
|
||||
* This is an implementation of the ApplicationManager interface
|
||||
* for the single VM mode of the VM.
|
||||
*
|
||||
* In this mode the VM is shut down each time a MIDlet exits.
|
||||
*
|
||||
* Application manager controls midlet life cycle:
|
||||
* - installs, updates and removes midlets/midlet suites
|
||||
* - launches and terminates midlets
|
||||
* - displays info about a midlet/midlet suite
|
||||
* - shuts down the AMS system
|
||||
*/
|
||||
public class Manager extends MIDlet implements ApplicationManager,
|
||||
ODTControllerEventConsumer {
|
||||
|
||||
/** Constant for the discovery application class name. */
|
||||
private static final String DISCOVERY_APP =
|
||||
"com.sun.midp.installer.DiscoveryApp";
|
||||
|
||||
/** Constant for the graphical installer class name. */
|
||||
private static final String INSTALLER =
|
||||
"com.sun.midp.installer.GraphicalInstaller";
|
||||
|
||||
/** Constant for the CA manager class name. */
|
||||
private static final String CA_MANAGER =
|
||||
"com.sun.midp.appmanager.CaManager";
|
||||
|
||||
/** Constant for the component manager class name. */
|
||||
private static final String COMP_MANAGER =
|
||||
"com.sun.midp.appmanager.ComponentManager";
|
||||
|
||||
/** Constant for the ODT Agent class name. */
|
||||
private static final String ODT_AGENT =
|
||||
"com.sun.midp.odd.ODTAgentMIDlet";
|
||||
|
||||
/** True until constructed for the first time. */
|
||||
private static boolean first = true;
|
||||
|
||||
/** MIDlet Suite storage object. */
|
||||
private MIDletSuiteStorage midletSuiteStorage;
|
||||
|
||||
/** UI to display error alerts. */
|
||||
private DisplayError displayError;
|
||||
|
||||
/** Application Selector Screen. */
|
||||
private AppManagerPeer appManager;
|
||||
|
||||
/**
|
||||
* Create and initialize a new Manager MIDlet.
|
||||
*/
|
||||
public Manager() {
|
||||
midletSuiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
|
||||
|
||||
EventQueue eq = EventQueue.getEventQueue();
|
||||
new ODTControllerEventListener(eq, this);
|
||||
|
||||
GraphicalInstaller.initSettings();
|
||||
|
||||
first = (getAppProperty("logo-displayed") == null);
|
||||
|
||||
Display display = Display.getDisplay(this);
|
||||
displayError = new DisplayError(display);
|
||||
|
||||
// Get arguments to create appManager
|
||||
String suiteIdStr = getAppProperty("arg-0");
|
||||
int suiteId = MIDletSuite.UNUSED_SUITE_ID;
|
||||
try {
|
||||
suiteId = Integer.parseInt(suiteIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
suiteId = MIDletSuite.UNUSED_SUITE_ID;
|
||||
}
|
||||
|
||||
if (suiteId != MIDletSuite.UNUSED_SUITE_ID) {
|
||||
MIDletSuiteInfo sui = new MIDletSuiteInfo(suiteId);
|
||||
if (suiteId == MIDletSuite.INTERNAL_SUITE_ID) {
|
||||
// For internal suites midlet class name should be specified
|
||||
sui.midletToRun = getAppProperty("arg-1");
|
||||
}
|
||||
// AppManagerUI will be set to be current at the end of its constructor
|
||||
appManager = new AppManagerPeer(this, display, displayError, first, sui);
|
||||
} else {
|
||||
// AppManagerUI will be set to be current at the end of its constructor
|
||||
appManager = new AppManagerPeer(this, display, displayError, first, null);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start puts up a List of the MIDlets found in the descriptor file.
|
||||
*/
|
||||
public void startApp() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause; there are no resources that need to be released.
|
||||
*/
|
||||
public void pauseApp() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy cleans up.
|
||||
*
|
||||
* @param unconditional is ignored; this object always
|
||||
* destroys itself when requested.
|
||||
*/
|
||||
public void destroyApp(boolean unconditional) {
|
||||
GraphicalInstaller.saveSettings(null, MIDletSuite.UNUSED_SUITE_ID);
|
||||
|
||||
appManager.cleanUp();
|
||||
|
||||
if (MIDletSuiteUtils.getNextMIDletSuiteToRun() !=
|
||||
MIDletSuite.UNUSED_SUITE_ID) {
|
||||
/*
|
||||
* A MIDlet was pushed.
|
||||
* So make sure this MIDlet is run after the pushed one.
|
||||
*
|
||||
* Note this call only is
|
||||
* needed now because suites are not run concurrently and must
|
||||
* be queued to be run after this MIDlet is destroyed.
|
||||
*/
|
||||
updateLastSuiteToRun();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes MIDP_ENABLE_ODD_EVENT
|
||||
*/
|
||||
public void handleEnableODDEvent() {
|
||||
appManager.showODTAgent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_START_MIDLET_EVENT
|
||||
*
|
||||
* @param suiteId ID of the midlet suite
|
||||
* @param className class name of the midlet to run
|
||||
* @param displayName display name of the midlet to run
|
||||
* @param isDebugMode true if the midlet must be started in debug mode,
|
||||
* false otherwise
|
||||
*/
|
||||
public void handleODDStartMidletEvent(int suiteId, String className,
|
||||
String displayName,
|
||||
boolean isDebugMode) {
|
||||
/*
|
||||
* Not used in SVM: midlet is started directly instead of sending
|
||||
* a message to AMS.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_EXIT_MIDLET_EVENT.
|
||||
*
|
||||
* @param suiteId ID of the midlet suite
|
||||
* @param className class name of the midlet to exit or <code>NULL</code>
|
||||
* if all MIDlets from the suite should be exited
|
||||
*/
|
||||
public void handleODDExitMidletEvent(int suiteId, String className) {
|
||||
/*
|
||||
* Not used in SVM: ODT agent doesn't send messages to AMS in SVM mode.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_SUITE_INSTALLED_EVENT. This event indicates that
|
||||
* a new MIDlet suite has been installed by ODT agent.
|
||||
*
|
||||
* @param suiteId ID of the newly installed MIDlet suite
|
||||
*/
|
||||
public void handleODDSuiteInstalledEvent(int suiteId) {
|
||||
/*
|
||||
* Not used in SVM: ODT agent doesn't send messages to AMS in SVM mode.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_SUITE_REMOVED_EVENT. This event indicates that
|
||||
* an installed MIDlet suite has been removed by ODT agent.
|
||||
*
|
||||
* @param suiteId ID of the removed MIDlet suite
|
||||
*/
|
||||
public void handleODDSuiteRemovedEvent(int suiteId) {
|
||||
/*
|
||||
* Not used in SVM: ODT agent doesn't send messages to AMS in SVM mode.
|
||||
*/
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// ---- Implementation of the ApplicationManager interface ------------
|
||||
|
||||
/**
|
||||
* Discover and install a suite.
|
||||
*/
|
||||
public void installSuite() {
|
||||
try {
|
||||
MIDletStateHandler.getMidletStateHandler().startMIDlet(
|
||||
DISCOVERY_APP,
|
||||
Resource.getString(ResourceConstants.INSTALL_APPLICATION));
|
||||
|
||||
yieldForNextMidlet();
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(Resource.getString
|
||||
(ResourceConstants.INSTALL_APPLICATION),
|
||||
ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/** Launch the CA manager. */
|
||||
public void launchCaManager() {
|
||||
try {
|
||||
MIDletStateHandler.getMidletStateHandler().startMIDlet(
|
||||
CA_MANAGER,
|
||||
Resource.getString(ResourceConstants.CA_MANAGER_APP));
|
||||
|
||||
yieldForNextMidlet();
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(Resource.getString(
|
||||
ResourceConstants.CA_MANAGER_APP), ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the component manager.
|
||||
*/
|
||||
public void launchComponentManager() {
|
||||
try {
|
||||
MIDletSuiteUtils.execute(MIDletSuite.INTERNAL_SUITE_ID,
|
||||
COMP_MANAGER,
|
||||
Resource.getString(ResourceConstants.COMP_MANAGER_APP));
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(Resource.getString(
|
||||
ResourceConstants.COMP_MANAGER_APP), ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch ODT Agent.
|
||||
*/
|
||||
public void launchODTAgent() {
|
||||
try {
|
||||
MIDletStateHandler.getMidletStateHandler().startMIDlet(
|
||||
ODT_AGENT,
|
||||
Resource.getString(ResourceConstants.ODT_AGENT_MIDLET));
|
||||
|
||||
yieldForNextMidlet();
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(Resource.getString(
|
||||
ResourceConstants.ODT_AGENT_MIDLET), ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a suite.
|
||||
*
|
||||
* @param suiteInfo information for suite to launch
|
||||
* @param midletToRun class name of the MIDlet to launch
|
||||
*/
|
||||
public void launchSuite(RunningMIDletSuiteInfo suiteInfo,
|
||||
String midletToRun) {
|
||||
|
||||
if (Constants.MEASURE_STARTUP) {
|
||||
System.err.println("Application Startup Time: Begin at "
|
||||
+System.currentTimeMillis());
|
||||
}
|
||||
|
||||
try {
|
||||
// Create an instance of the MIDlet class
|
||||
// All other initialization happens in MIDlet constructor
|
||||
MIDletSuiteUtils.execute(suiteInfo.suiteId, midletToRun,
|
||||
suiteInfo.displayName);
|
||||
|
||||
/*
|
||||
* Give the new MIDlet the screen by destroy our self,
|
||||
* because we are running in a limited VM and must
|
||||
* restart the VM let the select suite run.
|
||||
*/
|
||||
yieldForNextMidlet();
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(suiteInfo.displayName, ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a suite.
|
||||
*
|
||||
* @param suiteInfo information for suite to update
|
||||
*/
|
||||
public void updateSuite(RunningMIDletSuiteInfo suiteInfo) {
|
||||
MIDletStateHandler midletStateHandler =
|
||||
MIDletStateHandler.getMidletStateHandler();
|
||||
MIDletSuite midletSuite = midletStateHandler.getMIDletSuite();
|
||||
|
||||
/*
|
||||
* Setting arg 0 to "U" signals that arg 1 is a suite ID for updating.
|
||||
*/
|
||||
midletSuite.setTempProperty(null, "arg-0", "U");
|
||||
midletSuite.setTempProperty(null, "arg-1",
|
||||
String.valueOf(suiteInfo.suiteId));
|
||||
try {
|
||||
midletStateHandler.startMIDlet(INSTALLER, null);
|
||||
yieldForNextMidlet();
|
||||
|
||||
} catch (Exception ex) {
|
||||
displayError.showErrorAlert(suiteInfo.displayName, ex, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down the system
|
||||
*/
|
||||
public void shutDown() {
|
||||
MIDletProxyList.getMIDletProxyList().shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bring the midlet with the passed in midlet suite info to the
|
||||
* foreground.
|
||||
*
|
||||
* @param suiteInfo information for the midlet to be put to foreground
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
public void moveToForeground(RunningMIDletSuiteInfo suiteInfo, String className) {}
|
||||
|
||||
|
||||
/**
|
||||
* Exit the midlet with the passed in midlet suite info.
|
||||
*
|
||||
* @param suiteInfo information for the midlet to be terminated
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
public void exitMidlet(RunningMIDletSuiteInfo suiteInfo, String className) {}
|
||||
|
||||
/**
|
||||
* Handle exit of MIDlet suite (last running MIDlet in sute exited).
|
||||
* @param suiteInfo Containing ID of exited suite
|
||||
* @param className the running MIDlet class name
|
||||
*/
|
||||
public void notifySuiteExited(RunningMIDletSuiteInfo suiteInfo, String className) {}
|
||||
|
||||
/**
|
||||
* Handle exit of MIDlet selector.
|
||||
* @param suiteInfo Containing ID of suite
|
||||
*/
|
||||
public void notifyMIDletSelectorExited(RunningMIDletSuiteInfo suiteInfo) {}
|
||||
|
||||
// ==============================================================
|
||||
// ----------------- PRIVATE methods ---------------------------
|
||||
|
||||
/**
|
||||
* Yield the VM so the next MIDlet can run. To yield set this MIDlet as
|
||||
* last MIDlet run after the next MIDlet suite is done and then destroy
|
||||
* this MIDlet. Note: if the system is changed to allow multiple suites
|
||||
* to run concurrently, this method will not be needed.
|
||||
*/
|
||||
private void yieldForNextMidlet() {
|
||||
// We want this MIDlet to run after the next MIDlet is run.
|
||||
updateLastSuiteToRun();
|
||||
destroyApp(false);
|
||||
notifyDestroyed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this MIDlet to run after the next MIDlet is run.
|
||||
*/
|
||||
private void updateLastSuiteToRun() {
|
||||
MIDletSuiteInfo msi = appManager.getSelectedMIDletSuiteInfo();
|
||||
if (msi == null) {
|
||||
MIDletSuiteUtils.setLastSuiteToRun(MIDletStateHandler.
|
||||
getMidletStateHandler().getMIDletSuite().getID(),
|
||||
getClass().getName(), null, null);
|
||||
} else {
|
||||
String midletToRun = null;
|
||||
if (msi.isInternal()) {
|
||||
midletToRun = msi.midletToRun;
|
||||
}
|
||||
MIDletSuiteUtils.setLastSuiteToRun(MIDletStateHandler.
|
||||
getMidletStateHandler().getMIDletSuite().getID(),
|
||||
getClass().getName(), String.valueOf(msi.suiteId), midletToRun);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
/**
|
||||
* Dummy implementation to use when On Device Debugging is disabled.
|
||||
*/
|
||||
interface ODTControllerEventConsumer {
|
||||
/**
|
||||
* Processes MIDP_ENABLE_ODD_EVENT.
|
||||
*/
|
||||
public void handleEnableODDEvent();
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_START_MIDLET_EVENT.
|
||||
*
|
||||
* @param suiteId ID of the midlet suite
|
||||
* @param className class name of the midlet to run
|
||||
* @param displayName display name of the midlet to run
|
||||
* @param isDebugMode true if the midlet must be started in debug mode,
|
||||
* false otherwise
|
||||
*/
|
||||
public void handleODDStartMidletEvent(int suiteId, String className,
|
||||
String displayName,
|
||||
boolean isDebugMode);
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_EXIT_MIDLET_EVENT.
|
||||
*
|
||||
* @param suiteId ID of the midlet suite
|
||||
* @param className class name of the midlet to exit or <code>NULL</code>
|
||||
* if all MIDlets from the suite should be exited
|
||||
*/
|
||||
public void handleODDExitMidletEvent(int suiteId, String className);
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_SUITE_INSTALLED_EVENT. This event indicates that
|
||||
* a new MIDlet suite has been installed by ODT agent.
|
||||
*
|
||||
* @param suiteId ID of the newly installed midlet suite
|
||||
*/
|
||||
public void handleODDSuiteInstalledEvent(int suiteId);
|
||||
|
||||
/**
|
||||
* Processes MIDP_ODD_SUITE_REMOVED_EVENT. This event indicates that
|
||||
* an installed MIDlet suite has been removed by ODT agent.
|
||||
*
|
||||
* @param suiteId ID of the removed midlet suite
|
||||
*/
|
||||
public void handleODDSuiteRemovedEvent(int suiteId);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.events.EventQueue;
|
||||
import com.sun.midp.events.Event;
|
||||
import com.sun.midp.events.EventListener;
|
||||
|
||||
/**
|
||||
* Dummy implementation to use when On Device Debugging is disabled.
|
||||
*/
|
||||
class ODTControllerEventListener implements EventListener {
|
||||
|
||||
/**
|
||||
* Default package private constructor.
|
||||
*
|
||||
* @param eventQueue reference to the event queue
|
||||
* @param odtControllerEventConsumerParam comsumer that will process
|
||||
* events received by this listener
|
||||
*/
|
||||
public ODTControllerEventListener(
|
||||
EventQueue eventQueue,
|
||||
ODTControllerEventConsumer odtControllerEventConsumerParam) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess an event that is being posted to the event queue.
|
||||
*
|
||||
* @param event event being posted
|
||||
*
|
||||
* @param waitingEvent previous event of this type waiting in the
|
||||
* queue to be processed
|
||||
*
|
||||
* @return true to allow the post to continue, false to not post the
|
||||
* event to the queue
|
||||
*/
|
||||
public boolean preprocess(Event event, Event waitingEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes events.
|
||||
*
|
||||
* @param event event to process
|
||||
*/
|
||||
public void process(Event event) {
|
||||
}
|
||||
}
|
|
@ -1,471 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.configurator.Constants;
|
||||
import com.sun.midp.installer.GraphicalInstaller;
|
||||
import com.sun.midp.log.LogChannels;
|
||||
import com.sun.midp.log.Logging;
|
||||
import com.sun.midp.main.MIDletProxy;
|
||||
import com.sun.midp.midletsuite.MIDletInfo;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteImpl;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteInfo;
|
||||
import com.sun.midp.midletsuite.MIDletSuiteStorage;
|
||||
import com.sun.midp.main.MIDletSuiteUtils;
|
||||
import com.sun.midp.main.Configuration;
|
||||
import com.sun.midp.midlet.MIDletSuite;
|
||||
import com.sun.midp.ams.VMUtils;
|
||||
|
||||
import javax.microedition.lcdui.Image;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/** Simple attribute storage for MIDlet suites */
|
||||
public class RunningMIDletSuiteInfo extends MIDletSuiteInfo {
|
||||
/**
|
||||
* The list of MIDlet proxies, one for each running MIDlet.
|
||||
* It is set from AppManagerUI.java and has maximal allowed
|
||||
* number of concurrent VM tasks as initial capacity.
|
||||
*/
|
||||
private Vector proxies = new Vector(
|
||||
VMUtils.getMaxIsolates());
|
||||
|
||||
/** Icon for this suite. */
|
||||
public Image icon = null;
|
||||
/** Whether suite is under debug */
|
||||
public boolean isDebugMode = false;
|
||||
/** Whether the running suite is locked */
|
||||
private boolean locked = false;
|
||||
/** Corresponding suite */
|
||||
private MIDletSuite msi = null;
|
||||
/** Whether the suite has main MIDlet. */
|
||||
private boolean hasMainMidlet = false;
|
||||
|
||||
/**
|
||||
* Constructs a RunningMIDletSuiteInfo object for a suite.
|
||||
*
|
||||
* @param theID ID the system has for this suite
|
||||
*/
|
||||
public RunningMIDletSuiteInfo(int theID) {
|
||||
super(theID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RunningMIDletSuiteInfo object for a suite.
|
||||
*
|
||||
* @param theID ID the system has for this suite
|
||||
* @param theMidletToRun Class name of the only midlet in the suite
|
||||
* @param theDisplayName Name to display to the user
|
||||
* @param isEnabled true if the suite is enabled
|
||||
*/
|
||||
public RunningMIDletSuiteInfo(int theID, String theMidletToRun,
|
||||
String theDisplayName, boolean isEnabled) {
|
||||
super(theID, theMidletToRun, theDisplayName, isEnabled);
|
||||
icon = getDefaultSingleSuiteIcon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RunningMIDletSuiteInfo object for a suite.
|
||||
*
|
||||
* @param theID ID the system has for this suite
|
||||
* @param theMidletSuite MIDletSuite information
|
||||
* @param mss the midletSuite storage
|
||||
*/
|
||||
public RunningMIDletSuiteInfo(int theID, MIDletSuiteImpl theMidletSuite,
|
||||
MIDletSuiteStorage mss) {
|
||||
super(theID, theMidletSuite);
|
||||
|
||||
icon = getIcon(theID, theMidletSuite.getProperty("MIDlet-Icon"), mss);
|
||||
if (icon == null && numberOfMidlets == 1) {
|
||||
MIDletInfo midlet =
|
||||
new MIDletInfo(theMidletSuite.getProperty("MIDlet-1"));
|
||||
|
||||
// MIDlet icons are optional, so it the icon may be null
|
||||
icon = getIcon(theID, midlet.icon, mss);
|
||||
}
|
||||
|
||||
if (icon == null) {
|
||||
icon = getDefaultSingleSuiteIcon();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RunningMIDletSuiteInfo from MIDletSuiteInfo.
|
||||
*
|
||||
* @param info MIDletSuiteInfo reference
|
||||
* @param mss the midletSuite storage
|
||||
*/
|
||||
public RunningMIDletSuiteInfo(MIDletSuiteInfo info,
|
||||
MIDletSuiteStorage mss) {
|
||||
super(info.suiteId, info.midletToRun, info.displayName,
|
||||
info.enabled);
|
||||
|
||||
storageId = info.storageId;
|
||||
folderId = info.folderId;
|
||||
numberOfMidlets = info.numberOfMidlets;
|
||||
trusted = info.trusted;
|
||||
preinstalled = info.preinstalled;
|
||||
iconName = info.iconName;
|
||||
|
||||
loadIcon(mss);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an icon for this suite.
|
||||
*
|
||||
* @param mss the midletSuite storage
|
||||
*/
|
||||
public void loadIcon(MIDletSuiteStorage mss) {
|
||||
if (iconName != null) {
|
||||
icon = getIcon(suiteId, iconName, mss);
|
||||
}
|
||||
|
||||
if (icon == null) {
|
||||
if (numberOfMidlets == 1) {
|
||||
icon = getDefaultSingleSuiteIcon();
|
||||
} else {
|
||||
icon = getDefaultMultiSuiteIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets suite icon either from image cache, or from the suite jar.
|
||||
*
|
||||
* @param theID the suite id that system has for this suite
|
||||
* @param iconName the name of the file where the icon is
|
||||
* stored in the JAR
|
||||
* @param mss The midletSuite storage
|
||||
* @return Image provided by the application with
|
||||
* the passed in iconName
|
||||
*/
|
||||
public static Image getIcon(int theID, String iconName,
|
||||
MIDletSuiteStorage mss) {
|
||||
byte[] iconBytes;
|
||||
|
||||
try {
|
||||
iconBytes = mss.getMIDletSuiteIcon(theID, iconName);
|
||||
|
||||
if (iconBytes == null) {
|
||||
if (Logging.REPORT_LEVEL <= Logging.WARNING) {
|
||||
Logging.report(Logging.WARNING, LogChannels.LC_AMS,
|
||||
"getIcon: iconBytes == null");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return Image.createImage(iconBytes, 0, iconBytes.length);
|
||||
} catch (Throwable t) {
|
||||
if (Logging.REPORT_LEVEL <= Logging.WARNING) {
|
||||
Logging.report(Logging.WARNING, LogChannels.LC_AMS,
|
||||
"getIcon threw an " + t.getClass());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the MIDletSuiteInfo object.
|
||||
* For debug only.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("id = " + suiteId);
|
||||
b.append(", midletToRun = " + midletToRun);
|
||||
b.append(", proxies = [" + getProxies()+"]");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/** Cache of the suite icon. */
|
||||
private static Image multiSuiteIcon;
|
||||
|
||||
/** Cache of the single suite icon. */
|
||||
private static Image singleSuiteIcon;
|
||||
|
||||
/**
|
||||
* Gets the single MIDlet suite icon from storage.
|
||||
*
|
||||
* @return icon image
|
||||
*/
|
||||
private static Image getDefaultSingleSuiteIcon() {
|
||||
if (singleSuiteIcon == null) {
|
||||
singleSuiteIcon = GraphicalInstaller.
|
||||
getImageFromInternalStorage("_ch_single");
|
||||
}
|
||||
return singleSuiteIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MIDlet suite icon from storage.
|
||||
*
|
||||
* @return icon image
|
||||
*/
|
||||
private static Image getDefaultMultiSuiteIcon() {
|
||||
if (multiSuiteIcon == null) {
|
||||
multiSuiteIcon = GraphicalInstaller.
|
||||
getImageFromInternalStorage("_ch_suite");
|
||||
}
|
||||
return multiSuiteIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if midlet belongs to the same suite. If the suite id
|
||||
* is INTERNAL_SUITE_ID, the MIDlet class name is also checked.
|
||||
*
|
||||
* Note that the "built-in MIDlets" are a special case: their suite id
|
||||
* is INTERNAL_SUITE_ID and they are distinguished by the MIDlet class
|
||||
* name. Although they belong to the same internal suite, they are
|
||||
* described with different RunningMIDletSuiteInfo objects.
|
||||
* @param midlet the MIDlet proxy
|
||||
* @return true if the MIDletProxy and this RunningMIDletSuiteInfo have the
|
||||
* same suite id, and, if the suite is internal, if class names match.
|
||||
*/
|
||||
public boolean sameSuite(MIDletProxy midlet) {
|
||||
return sameSuiteId(midlet)
|
||||
&& (!isInternal()
|
||||
// midletToRun must not be null for internal midlets
|
||||
|| midletToRun != null && midletToRun.equals(midlet.getClassName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare suite ids of RunningMIDletSuiteInfo and MIDletProxy.
|
||||
* Return true if they are equal.
|
||||
*
|
||||
* Note that the MIDlets whose suite id is INTERNAL_SUITE_ID are
|
||||
* distinguished by the MIDlet class name and are described with
|
||||
* different RunningMIDletSuiteInfo objects.
|
||||
* @param midlet describes a running MIDlet
|
||||
* @return true if the suite ids match
|
||||
*/
|
||||
public final boolean sameSuiteId(MIDletProxy midlet) {
|
||||
return suiteId == midlet.getSuiteId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the suite runs the specified MIDlet.
|
||||
* @param midlet specifies the MIDlet
|
||||
* @return true if the MIDlet proxy is found in the running MIDlet proxy list.
|
||||
*/
|
||||
public boolean hasRunning(MIDletProxy midlet) {
|
||||
if (suiteId != midlet.getSuiteId()) {
|
||||
return false;
|
||||
} else {
|
||||
synchronized (this) {
|
||||
return proxies.contains(midlet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first item from the running MIDlet proxy list.
|
||||
* @return Proxy of a running MIDlet, or null
|
||||
*/
|
||||
synchronized public MIDletProxy getFirstProxy() {
|
||||
return (proxies.size() != 0) ? (MIDletProxy) proxies.firstElement() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the MIDlet identified by className is running, return its proxy.
|
||||
* @param className MIDlet class name
|
||||
* @return the running MIDlet proxy or null
|
||||
*/
|
||||
public MIDletProxy getProxyFor(String className) {
|
||||
if (className == null) {
|
||||
return getFirstProxy();
|
||||
}
|
||||
synchronized (this) {
|
||||
for (int i=0; i<proxies.size(); i++) {
|
||||
if (className.equals(getProxyAt(i).getClassName())) {
|
||||
return getProxyAt(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of proxies for all running MIDlets.
|
||||
* @return the proxy array.
|
||||
*/
|
||||
synchronized public MIDletProxy[] getProxies() {
|
||||
MIDletProxy[] proxyArray = new MIDletProxy[proxies.size()];
|
||||
proxies.copyInto(proxyArray);
|
||||
return proxyArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all specified proxies to the list of MIDlet proxies.
|
||||
* @param newList specifies the MIDlet proxies to add
|
||||
*/
|
||||
synchronized void addProxies(MIDletProxy[] newList) {
|
||||
for (int i=0; i<newList.length; i++) {
|
||||
if (!proxies.contains(newList[i])) {
|
||||
proxies.addElement(newList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the i-th MIDlet proxy. An exception happens if i is not a valid proxy index.
|
||||
* @param i The number of MIDlet proxy in the midlet proxy list
|
||||
* @return the MIDlet proxy
|
||||
*/
|
||||
synchronized public MIDletProxy getProxyAt(int i) {
|
||||
return (MIDletProxy) proxies.elementAt(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find proxy among the list of running MIDlet proxies.
|
||||
* @param proxy proxy for some MIDlet
|
||||
* @return true if this proxy is in the list of running midlets
|
||||
*/
|
||||
synchronized public boolean hasProxy(MIDletProxy proxy) {
|
||||
return proxies.contains(proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the list of running MIDlet proxies for emptiness.
|
||||
* @return true if at least one MIDlet is running
|
||||
*/
|
||||
public boolean hasRunningMidlet() {
|
||||
return !proxies.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of entries in the MIDlet proxy list.
|
||||
* @return the number of running MIDlets from this suite
|
||||
*/
|
||||
public int numberOfRunningMidlets() {
|
||||
return proxies.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if alert is waiting for the foreground in at
|
||||
* least of one of the MIDlets from this suite.
|
||||
* @return true if there is a waiting alert
|
||||
*/
|
||||
public boolean isAnyAlertWaiting() {
|
||||
boolean res = false;
|
||||
synchronized (this) {
|
||||
for (int i=0, n=numberOfRunningMidlets(); i<n && !res; i++) {
|
||||
res = getProxyAt(i).isAlertWaiting();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the list of running MIDlet proxies.
|
||||
* @param proxy the MIDlet proxy to add. Nothing is done when it's null.
|
||||
*/
|
||||
public void addProxy(MIDletProxy proxy) {
|
||||
if (proxy != null) {
|
||||
synchronized (this) {
|
||||
proxies.addElement(proxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the running MIDlet proxy list.
|
||||
* @param proxy a MIDlet proxy to remove from the list
|
||||
*/
|
||||
synchronized public void removeProxy(MIDletProxy proxy) {
|
||||
proxies.removeElement(proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the running suite.
|
||||
*/
|
||||
public void lock() {
|
||||
locked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the running suite.
|
||||
*/
|
||||
public void unlock() {
|
||||
locked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the suite is locked
|
||||
*/
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the storage lock for the suite if it is free.
|
||||
*/
|
||||
public void grabStorageLock() {
|
||||
if (msi == null) {
|
||||
try {
|
||||
msi = MIDletSuiteUtils.getSuite(suiteId);
|
||||
} catch (SecurityException e) {
|
||||
/* not critical */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases storage lock for the suite (only if previously locked by
|
||||
* grabStorageLock())
|
||||
*/
|
||||
public void releaseStorageLock() {
|
||||
if (msi != null) {
|
||||
try {
|
||||
msi.close();
|
||||
} catch (Exception e) {
|
||||
/* not critical */
|
||||
}
|
||||
msi = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this object holds storage lock for the suite
|
||||
*/
|
||||
public boolean holdsStorageLock() {
|
||||
return msi != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets main MIDlet flag.
|
||||
* @param mainMidlet Determines whether this suite has main MIDlet
|
||||
*/
|
||||
public void setMainMidlet(boolean hasMainMidlet) {
|
||||
this.hasMainMidlet = hasMainMidlet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if main MIDlet is set
|
||||
*/
|
||||
public boolean hasMainMidlet() {
|
||||
return hasMainMidlet;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
/**
|
||||
* This class is Selector that exits after launching the selected MIDlet.
|
||||
*/
|
||||
public class Selector extends SelectorBase {
|
||||
/**
|
||||
* Destroys this Selector midlet and exits after scheduling
|
||||
* an execution of the next midlet in SVM, do nothing in MVM.
|
||||
*/
|
||||
protected void yieldToNextMidlet() {
|
||||
try {
|
||||
// Give the create MIDlet notification 1 second to get to AMS.
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore the exception
|
||||
}
|
||||
|
||||
// exit
|
||||
destroyApp(false);
|
||||
notifyDestroyed();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.midlet.MIDlet;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
import com.sun.midp.i18n.Resource;
|
||||
import com.sun.midp.i18n.ResourceConstants;
|
||||
import com.sun.midp.midlet.MIDletStateHandler;
|
||||
import com.sun.midp.midletsuite.MIDletInfo;
|
||||
|
||||
/**
|
||||
* A base class for the class Selector providing a simple user interface
|
||||
* to select MIDlets to run.
|
||||
* It extracts the list of MIDlets from the attributes in the
|
||||
* descriptor file and presents them to the user using the MIDlet-<n>
|
||||
* name and icon if any. When the user selects a MIDlet an instance
|
||||
* of the class indicated by MIDlet-<n> classname is created.
|
||||
*/
|
||||
abstract class SelectorBase extends MIDlet implements CommandListener, Runnable {
|
||||
/**
|
||||
* The List of all the MIDlets.
|
||||
*/
|
||||
private List mlist;
|
||||
/**
|
||||
* The Display.
|
||||
*/
|
||||
protected Display display;
|
||||
/**
|
||||
* Number of midlets in minfo.
|
||||
*/
|
||||
private int mcount;
|
||||
/**
|
||||
* MIDlet information, class, name, icon; one per MIDlet.
|
||||
*/
|
||||
private MIDletInfo[] minfo;
|
||||
/**
|
||||
* the Command object to exit the Selector MIDlet
|
||||
*/
|
||||
private Command exitCmd = new Command(Resource.getString
|
||||
(ResourceConstants.EXIT),
|
||||
Command.EXIT, 2);
|
||||
/**
|
||||
* the Command object for "Launch".
|
||||
*/
|
||||
private Command launchCmd = new Command(Resource.getString
|
||||
(ResourceConstants.LAUNCH),
|
||||
Command.ITEM, 1);
|
||||
/**
|
||||
* Index of the selected MIDlet, starts at -1 for non-selected.
|
||||
*/
|
||||
protected int selectedMidlet = -1;
|
||||
|
||||
/**
|
||||
* Create and initialize a new Selector MIDlet.
|
||||
* The Display is retrieved and the list of MIDlets read
|
||||
* from the descriptor file.
|
||||
*/
|
||||
public SelectorBase() {
|
||||
display = Display.getDisplay(this);
|
||||
mcount = 0;
|
||||
minfo = new MIDletInfo[20];
|
||||
readMIDletInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Put up a List of the MIDlets found in the descriptor file.
|
||||
*/
|
||||
public void startApp() {
|
||||
setupList();
|
||||
mlist.addCommand(launchCmd);
|
||||
mlist.addCommand(exitCmd);
|
||||
mlist.setCommandListener(this);
|
||||
display.setCurrent(mlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* There are no resources that need to be released.
|
||||
*/
|
||||
public void pauseApp() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy cleans up.
|
||||
* The only resource used is in the objects that will be
|
||||
* reclaimed by the garbage collector.
|
||||
* @param unconditional is ignored; the Selector always
|
||||
* destroys itself when requested.
|
||||
*/
|
||||
public void destroyApp(boolean unconditional) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a command issued on any Screen.
|
||||
* The commands on list is Select and About.
|
||||
* Select triggers the creation of the MIDlet of the same name.
|
||||
* About puts up the copyright notice.
|
||||
*
|
||||
* @param c command activated by the user
|
||||
* @param s the Displayable the command was on.
|
||||
*/
|
||||
public void commandAction(Command c, Displayable s) {
|
||||
if ((s == mlist && c == List.SELECT_COMMAND) || (c == launchCmd)) {
|
||||
synchronized (this) {
|
||||
if (selectedMidlet != -1) {
|
||||
// the previous selected MIDlet is being launched
|
||||
return;
|
||||
}
|
||||
|
||||
selectedMidlet = mlist.getSelectedIndex();
|
||||
}
|
||||
new Thread(this).start();
|
||||
} else if (c == exitCmd) {
|
||||
destroyApp(false);
|
||||
notifyDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this Selector midlet and exits after scheduling
|
||||
* an execution of the next midlet in SVM, do nothing in MVM.
|
||||
*/
|
||||
protected abstract void yieldToNextMidlet();
|
||||
|
||||
/**
|
||||
* Launch a the select MIDlet.
|
||||
*/
|
||||
public void run() {
|
||||
MIDletStateHandler midletStateHandler =
|
||||
MIDletStateHandler.getMidletStateHandler();
|
||||
String classname = minfo[selectedMidlet].classname;
|
||||
String displayName = minfo[selectedMidlet].name;
|
||||
|
||||
try {
|
||||
midletStateHandler.startMIDlet(classname,
|
||||
displayName);
|
||||
yieldToNextMidlet();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
StringBuffer sb = new StringBuffer()
|
||||
.append(minfo[selectedMidlet].name)
|
||||
.append(", ")
|
||||
.append(classname)
|
||||
.append("\n")
|
||||
.append(Resource.getString(ResourceConstants.EXCEPTION))
|
||||
.append(": ")
|
||||
.append(ex.toString());
|
||||
|
||||
Alert a = new Alert(Resource.getString
|
||||
(ResourceConstants.AMS_CANNOT_START),
|
||||
sb.toString(), null, null);
|
||||
|
||||
display.setCurrent(a, mlist);
|
||||
|
||||
// let another MIDlet be selected after the alert
|
||||
selectedMidlet = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the set of MIDlet names, icons and classes
|
||||
* Fill in the list.
|
||||
*/
|
||||
private void setupList() {
|
||||
if (mlist == null) {
|
||||
mlist = new List(Resource.getString
|
||||
(ResourceConstants.AMS_SELECTOR_SEL_TO_LAUNCH),
|
||||
Choice.IMPLICIT);
|
||||
|
||||
// Add each midlet
|
||||
for (int i = 0; i < mcount; i++) {
|
||||
Image icon = null;
|
||||
if (minfo[i].icon != null) {
|
||||
try {
|
||||
icon = Image.createImage(minfo[i].icon);
|
||||
} catch (java.io.IOException noImage) {
|
||||
// TBD: use a default ICON if the app has none.
|
||||
}
|
||||
}
|
||||
mlist.append(minfo[i].name, icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in and create a MIDletInfor for each MIDlet-<n>
|
||||
*/
|
||||
private void readMIDletInfo() {
|
||||
for (int n = 1; n < 100; n++) {
|
||||
String nth = "MIDlet-" + n;
|
||||
String attr = getAppProperty(nth);
|
||||
if (attr == null || attr.length() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
addMIDlet(new MIDletInfo(attr));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a MIDlet to the list.
|
||||
* @param info MIDlet information to add to MIDlet
|
||||
*/
|
||||
private void addMIDlet(MIDletInfo info) {
|
||||
if (mcount >= minfo.length) {
|
||||
MIDletInfo[] n = new MIDletInfo[mcount+4];
|
||||
System.arraycopy(minfo, 0, n, 0, mcount);
|
||||
minfo = n;
|
||||
}
|
||||
minfo[mcount++] = info;
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
import com.sun.midp.installer.*;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
|
||||
/** Implements the splash screen */
|
||||
class SplashScreen extends Canvas {
|
||||
|
||||
/** Splash screen image */
|
||||
private Image splashScreen;
|
||||
|
||||
/** The displayable to be displayed after SplashScreen is dismissed. */
|
||||
private Displayable nextScreen;
|
||||
|
||||
/** The display associated with Manager midlet. */
|
||||
private Display display;
|
||||
|
||||
/**
|
||||
* A TimerTask which will be set to switch to the App Manager Screen
|
||||
* after its timeout period has elapsed.
|
||||
*/
|
||||
TimerTask timerTask;
|
||||
|
||||
/**
|
||||
* A Timer which serves this Splash Screen object to schedule
|
||||
* its timeout task
|
||||
*/
|
||||
Timer timeoutTimer;
|
||||
|
||||
/**
|
||||
* Creates a Splash screen.
|
||||
* @param display - the display associated wit the Manager midlet
|
||||
* @param nextScreen - the screen to be displayed after timeout
|
||||
*/
|
||||
SplashScreen(Display display, Displayable nextScreen) {
|
||||
this.nextScreen = nextScreen;
|
||||
this.display = display;
|
||||
|
||||
setFullScreenMode(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint splash screen.
|
||||
*
|
||||
* @param g Graphics instance to paint on
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
|
||||
// White background
|
||||
g.setColor(255, 255, 255);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
if (splashScreen != null) {
|
||||
g.drawImage(splashScreen, 0, 0, Graphics.LEFT | Graphics.TOP);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override showNotify to set a timer task so that Splash screen
|
||||
* automatically switches to the App Manager Screen.
|
||||
*/
|
||||
public void showNotify() {
|
||||
if (timerTask != null) {
|
||||
timerTask.cancel();
|
||||
}
|
||||
|
||||
if (timeoutTimer == null) {
|
||||
timeoutTimer = new Timer();
|
||||
}
|
||||
|
||||
timerTask = new TimeoutTask();
|
||||
timeoutTimer.schedule(timerTask, 2000);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when available area of
|
||||
* the Displayable has been changed.
|
||||
*/
|
||||
protected void sizeChanged(int w, int h) {
|
||||
splashScreen =
|
||||
GraphicalInstaller.getImageFromInternalStorage("splash_screen_"
|
||||
+ getWidth() + "x" + getHeight());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Override hideNotify to cancel timer task.
|
||||
*/
|
||||
public void hideNotify() {
|
||||
if (timerTask != null) {
|
||||
timerTask.cancel();
|
||||
}
|
||||
timerTask = null;
|
||||
|
||||
timeoutTimer = null;
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// Internal Class
|
||||
// *****************************************************
|
||||
|
||||
/**
|
||||
* A TimerTask subclass which will switch to the App Manager after
|
||||
* a time out time set.
|
||||
*/
|
||||
private class TimeoutTask extends TimerTask {
|
||||
|
||||
/**
|
||||
* Create a new timeout task
|
||||
*/
|
||||
TimeoutTask() { }
|
||||
|
||||
/**
|
||||
* Switch to the the App Manager Screen.
|
||||
*/
|
||||
public void run() {
|
||||
display.setCurrent(nextScreen);
|
||||
}
|
||||
} // TimeoutTask
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Interfase represente the set of pairs of ID and label.
|
||||
* One entity id market as selected.
|
||||
* It can be used to represent the data for exclusive
|
||||
* option buttons where each option has an ID.
|
||||
*/
|
||||
interface ValueChoice {
|
||||
|
||||
/**
|
||||
* Returns the ID of the selected item.
|
||||
*
|
||||
* @return ID of selected element
|
||||
*/
|
||||
int getSelectedID();
|
||||
|
||||
/**
|
||||
* Returns ID of specified item.
|
||||
* @param index item index
|
||||
* @return item ID
|
||||
*/
|
||||
int getID(int index);
|
||||
|
||||
/**
|
||||
* Returns label of specified choice items.
|
||||
* @param index item index
|
||||
* @return label
|
||||
*/
|
||||
String getLabel(int index);
|
||||
|
||||
/**
|
||||
* Returns count of items
|
||||
* @return count
|
||||
*/
|
||||
int getCount();
|
||||
|
||||
/**
|
||||
* Returns choice title.
|
||||
* @return title
|
||||
*/
|
||||
String getTitle();
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.appmanager;
|
||||
|
||||
import com.sun.midp.security.PermissionGroup;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Class contains set of pairs (ID, label)
|
||||
* and one entity market as selected.
|
||||
* It can be used as a data for exclusive
|
||||
* option buttons where each option has an ID.
|
||||
*/
|
||||
class ValueChoiceImpl implements ValueChoice {
|
||||
|
||||
/** Choice title. */
|
||||
private String title;
|
||||
|
||||
/** Keeps track of the choice IDs. */
|
||||
private Vector ids;
|
||||
|
||||
/** Choice lables. */
|
||||
private Vector labels;
|
||||
|
||||
/** Id of selected item. */
|
||||
private int selectedID;
|
||||
|
||||
/** Correspondent permission group. */
|
||||
private PermissionGroup permissionGroup;
|
||||
|
||||
/** ID of the permission group */
|
||||
private int permissionGroupID;
|
||||
|
||||
/**
|
||||
* Creates empty ValueChoice
|
||||
* @param title of the choice
|
||||
*/
|
||||
ValueChoiceImpl(PermissionGroup permissionGroup,
|
||||
int permissionGroupID, String title) {
|
||||
this.title = title;
|
||||
ids = new Vector(5);
|
||||
labels = new Vector(5);
|
||||
this.permissionGroup = permissionGroup;
|
||||
this.permissionGroupID = permissionGroupID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends choice to the set.
|
||||
*
|
||||
* @param label the lable of the element to be added
|
||||
* @param id ID for the item
|
||||
*/
|
||||
void append(String label, int id) {
|
||||
ids.addElement(new Integer(id));
|
||||
labels.addElement(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected item.
|
||||
*
|
||||
* @param id ID of selected item
|
||||
*/
|
||||
void setSelectedID(int id) {
|
||||
selectedID = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if specified ID exists in the list
|
||||
* @param id to find
|
||||
* @return true if it is present, false otherwise
|
||||
*/
|
||||
boolean idExists(int id) {
|
||||
Integer ID = new Integer(id);
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
if (ID.equals(ids.elementAt(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the selected item.
|
||||
*
|
||||
* @return ID of selected element
|
||||
*/
|
||||
public int getSelectedID() {
|
||||
return selectedID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ID of specified item.
|
||||
* @param index item index
|
||||
* @return item ID
|
||||
*/
|
||||
public int getID(int index) {
|
||||
return ((Integer)ids.elementAt(index)).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns label of cpecified choice items.
|
||||
* @param index item index
|
||||
* @return label
|
||||
*/
|
||||
public String getLabel(int index) {
|
||||
return (String)labels.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns count of items
|
||||
* @return count
|
||||
*/
|
||||
public int getCount() {
|
||||
return ids.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns choice title.
|
||||
* @return title
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns corresponding permission group.
|
||||
* @return permission group
|
||||
*/
|
||||
public PermissionGroup getPermissionGroup() {
|
||||
return permissionGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns corresponding permission group ID.
|
||||
* @return permission group ID
|
||||
*/
|
||||
public int getPermissionGroupID() {
|
||||
return permissionGroupID;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,11 +39,13 @@ module J2ME {
|
|||
"com/ibm/oti/connection/file/FCOutputStream.openOffsetImpl.([BJ)I": YieldReason.Root,
|
||||
"com/sun/midp/io/j2me/storage/RandomAccessStream.open.(Ljava/lang/String;I)I": YieldReason.Root,
|
||||
"javax/microedition/lcdui/ImageDataFactory.createImmutableImageDecodeImage.(Ljavax/microedition/lcdui/ImageData;[BII)V": YieldReason.Root,
|
||||
"com/nokia/mid/ui/TextEditorThread.sleep.()V": YieldReason.Root,
|
||||
"com/nokia/mid/ui/TextEditorThread.getNextDirtyEditor.()Lcom/nokia/mid/ui/TextEditor;": YieldReason.Root,
|
||||
"com/nokia/mid/ui/TextEditor.setFocus.(Z)V": YieldReason.Root,
|
||||
"com/nokia/mid/ui/VKVisibilityNotificationRunnable.sleepUntilVKVisibilityChange.()Z": YieldReason.Root,
|
||||
"com/nokia/mid/s40/bg/BGUtils.waitUserInteraction.()V": YieldReason.Root,
|
||||
"org/mozilla/io/LocalMsgConnection.init.(Ljava/lang/String;)V": YieldReason.Root,
|
||||
"org/mozilla/io/LocalMsgConnection.receiveData.([B)I": YieldReason.Root,
|
||||
"org/mozilla/io/LocalMsgConnection.waitConnection.()V": YieldReason.Root,
|
||||
"com/sun/mmedia/PlayerImpl.nRealize.(ILjava/lang/String;)Z": YieldReason.Root,
|
||||
"com/sun/mmedia/DirectRecord.nPause.(I)I": YieldReason.Root,
|
||||
"com/sun/mmedia/DirectRecord.nStop.(I)I": YieldReason.Root,
|
||||
|
@ -60,6 +62,7 @@ module J2ME {
|
|||
"java/lang/Class.invoke_clinit.()V": YieldReason.Root,
|
||||
"java/lang/Class.newInstance.()Ljava/lang/Object;": YieldReason.Root,
|
||||
"java/lang/Thread.yield.()V": YieldReason.Root,
|
||||
"java/lang/Thread.start0.()V": YieldReason.Root,
|
||||
// Test Files:
|
||||
"gnu/testlet/vm/NativeTest.throwExceptionAfterPause.()V": YieldReason.Root,
|
||||
"gnu/testlet/vm/NativeTest.returnAfterPause.()I": YieldReason.Root,
|
||||
|
|
|
@ -215,6 +215,7 @@ module J2ME {
|
|||
private methodInfo: MethodInfo;
|
||||
private parameters: string [];
|
||||
private hasHandlers: boolean;
|
||||
private hasMonitorEnter: boolean;
|
||||
private blockStackHeightMap: number [];
|
||||
private initializedClasses: any;
|
||||
private referencedClasses: ClassInfo [];
|
||||
|
@ -242,6 +243,7 @@ module J2ME {
|
|||
this.referencedClasses = [];
|
||||
this.initializedClasses = null;
|
||||
this.hasHandlers = !!methodInfo.exception_table.length;
|
||||
this.hasMonitorEnter = false;
|
||||
this.blockStackHeightMap = [0];
|
||||
this.bodyEmitter = new Emitter(target !== CompilationTarget.Runtime);
|
||||
this.blockEmitter = new Emitter(target !== CompilationTarget.Runtime);
|
||||
|
@ -262,9 +264,13 @@ module J2ME {
|
|||
this.entryBlock = blocks[0].relooperBlockID;
|
||||
this.emitPrologue();
|
||||
this.emitBody();
|
||||
|
||||
if (this.variables.length) {
|
||||
this.bodyEmitter.prependLn("var " + this.variables.join(", ") + ";");
|
||||
}
|
||||
if (this.hasMonitorEnter) {
|
||||
this.bodyEmitter.prependLn("var th = $.ctx.thread;");
|
||||
}
|
||||
return new CompiledMethodInfo(this.parameters, this.bodyEmitter.toString(), this.referencedClasses, this.hasOSREntryPoint);
|
||||
}
|
||||
|
||||
|
@ -854,8 +860,13 @@ module J2ME {
|
|||
}
|
||||
|
||||
private emitMonitorEnter(emitter: Emitter, nextPC: number, object: string) {
|
||||
emitter.writeLn("ME(" + object + ");");
|
||||
this.hasMonitorEnter = true;
|
||||
|
||||
this.needsVariable("lk");
|
||||
emitter.writeLn("lk = " + object + "._lock;");
|
||||
emitter.enter("if (lk && lk.level === 0) { lk.thread = th; lk.level = 1; } else { ME(" + object + ");");
|
||||
this.emitUnwind(emitter, this.pc, nextPC);
|
||||
emitter.leave("}");
|
||||
}
|
||||
|
||||
private emitPreemptionCheck(emitter: Emitter, nextPC: number) {
|
||||
|
@ -864,7 +875,7 @@ module J2ME {
|
|||
}
|
||||
|
||||
private emitMonitorExit(emitter: Emitter, object: string) {
|
||||
emitter.writeLn("MX(" + object + ");");
|
||||
emitter.writeLn("if (" + object + "._lock.level === 1 && " + object + "._lock.ready.length === 0) " + object + "._lock.level = 0; else MX(" + object + ");");
|
||||
}
|
||||
|
||||
emitStackOp(opcode: Bytecodes) {
|
||||
|
|
1
jsc.ts
1
jsc.ts
|
@ -80,7 +80,6 @@ module J2ME {
|
|||
|
||||
loadFiles("blackBox.js", "build/j2me-jsc.js", "libs/zipfile.js",
|
||||
"libs/encoding.js", "util.js",
|
||||
"instrument.js",
|
||||
"override.js", "native.js", "string.js", "midp/midp.js",
|
||||
"libs/long.js", "midp/crypto.js", "libs/forge/md5.js", "libs/forge/util.js");
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ var config = {
|
|||
try {
|
||||
load("libs/relooper.js", "build/j2me.js","libs/zipfile.js", "blackBox.js",
|
||||
"libs/encoding.js", "util.js",
|
||||
"instrument.js",
|
||||
"override.js", "native.js", "tests/override.js",
|
||||
"string.js", "midp/midp.js",
|
||||
"libs/long.js", "midp/crypto.js", "libs/forge/md5.js", "libs/forge/util.js");
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
push: function(item) {
|
||||
if (item.matchesCurrentFilters()) {
|
||||
this.flush(); // Preserve order w/r/t console.print().
|
||||
windowConsole[item.levelName].apply(windowConsole, item.args);
|
||||
windowConsole[item.levelName].apply(windowConsole, [item.message]);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -202,7 +202,7 @@
|
|||
NativeConsole.prototype = {
|
||||
push: function(item) {
|
||||
if (item.matchesCurrentFilters()) {
|
||||
dumpLine(item.message);
|
||||
dump(item.message + "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -344,7 +344,9 @@
|
|||
info: logAtLevel.bind(null, "info"),
|
||||
warn: logAtLevel.bind(null, "warn"),
|
||||
error: logAtLevel.bind(null, "error"),
|
||||
print: print
|
||||
print: print,
|
||||
profile: typeof console !== "undefined" && console.profile ? console.profile.bind(console) : null,
|
||||
profileEnd: typeof console !== "undefined" && console.profileEnd ? console.profileEnd.bind(console) : null,
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
@ -383,7 +383,7 @@ var fs = (function() {
|
|||
}
|
||||
}
|
||||
|
||||
var newArray = new Uint8Array(newBufferSize);
|
||||
var newArray = new Int8Array(newBufferSize);
|
||||
newArray.set(this.array);
|
||||
|
||||
this.array = newArray;
|
||||
|
@ -463,7 +463,7 @@ var fs = (function() {
|
|||
var fd = openedFiles.push({
|
||||
dirty: false,
|
||||
path: path,
|
||||
buffer: new FileBuffer(new Uint8Array(reader.result)),
|
||||
buffer: new FileBuffer(new Int8Array(reader.result)),
|
||||
mtime: record.mtime,
|
||||
size: record.size,
|
||||
position: 0,
|
||||
|
|
|
@ -659,4 +659,5 @@
|
|||
exports.fromNumber = fromNumber;
|
||||
exports.fromBits = fromBits;
|
||||
exports.fromString = fromString;
|
||||
exports.constructor = Long;
|
||||
})(typeof exports === "undefined" ? this.Long = {} : exports);
|
||||
|
|
12
main.html.in
12
main.html.in
|
@ -34,7 +34,6 @@
|
|||
<script type="text/javascript" src="override.js" defer></script>
|
||||
<script type="text/javascript" src="native.js" defer></script>
|
||||
<script type="text/javascript" src="string.js" defer></script>
|
||||
<script type="text/javascript" src="instrument.js" defer></script>
|
||||
<script type="text/javascript" src="libs/load.js" defer></script>
|
||||
<script type="text/javascript" src="libs/zipfile.js" defer></script>
|
||||
<script type="text/javascript" src="libs/long.js" defer></script>
|
||||
|
@ -128,9 +127,7 @@
|
|||
<input type="text" id="importstorageurl" placeholder="URL to FS backup">
|
||||
<button id="importstorage">Import</button>
|
||||
<button id="clearCompiledMethodCache">Clear Compiled Method Cache</button>
|
||||
<button id="trace">Trace: OFF</button>
|
||||
<button id="printAllExceptions">Print all exceptions: OFF</button>
|
||||
<button id="profile">Profile: OFF</button>
|
||||
<button id="clearCounters">Clear Counters</button>
|
||||
<button id="dumpCounters">Dump Counters</button>
|
||||
<button id="sampleCounters1">One sample for 1s</button>
|
||||
|
@ -157,7 +154,11 @@
|
|||
<h1 id="display_title"></h1>
|
||||
</header>
|
||||
<div id="main" role="main">
|
||||
<canvas id="canvas" style="image-rendering: -moz-crisp-edges"></canvas>
|
||||
<canvas id="canvas"></canvas>
|
||||
<input id="password-editor" class="text-editor" type="password">
|
||||
<div id="textarea-editor" class="text-editor" contenteditable="true"></div>
|
||||
<!-- The hidden textarea editor is used to measure the content height -->
|
||||
<div id="hidden-textarea-editor" class="text-editor"></div>
|
||||
<button id="back-button">Back</button>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -177,6 +178,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="background-screen">
|
||||
</div>
|
||||
|
||||
<form role="dialog" data-type="confirm"
|
||||
class="lcdui-alert"
|
||||
id="lcdui-alert" style="display: none">
|
||||
|
|
23
main.js
23
main.js
|
@ -175,7 +175,9 @@ function start() {
|
|||
jvm.startIsolate0(config.main, config.args);
|
||||
}
|
||||
|
||||
Promise.all(loadingPromises).then(start);
|
||||
Promise.all(loadingPromises).then(start, function (reason) {
|
||||
console.error("Loading failed: \"" + reason + "\"");
|
||||
});
|
||||
|
||||
document.getElementById("start").onclick = function() {
|
||||
start();
|
||||
|
@ -222,10 +224,6 @@ window.onload = function() {
|
|||
document.getElementById("clearCompiledMethodCache").onclick = function() {
|
||||
CompiledMethodCache.clear().then(function() { console.log("cleared compiled method cache") });
|
||||
};
|
||||
document.getElementById("trace").onclick = function() {
|
||||
VM.DEBUG = !VM.DEBUG;
|
||||
toggle(this);
|
||||
};
|
||||
document.getElementById("printAllExceptions").onclick = function() {
|
||||
VM.DEBUG_PRINT_ALL_EXCEPTIONS = !VM.DEBUG_PRINT_ALL_EXCEPTIONS;
|
||||
toggle(this);
|
||||
|
@ -346,23 +344,8 @@ window.onload = function() {
|
|||
}
|
||||
setTimeout(sample, 2000); // Wait 2s before starting.
|
||||
};
|
||||
document.getElementById("profile").onclick = function() {
|
||||
if (getIsOff(this)) {
|
||||
Instrument.startProfile();
|
||||
} else {
|
||||
Instrument.stopProfile();
|
||||
}
|
||||
toggle(this);
|
||||
};
|
||||
if (Instrument.profiling) {
|
||||
toggle(document.getElementById("profile"));
|
||||
}
|
||||
};
|
||||
|
||||
if (config.profile && !/no|0/.test(config.profile)) {
|
||||
Instrument.startProfile();
|
||||
}
|
||||
|
||||
function requestTimelineBuffers(fn) {
|
||||
if (J2ME.timeline) {
|
||||
fn([
|
||||
|
|
|
@ -48,5 +48,9 @@
|
|||
"messages": [
|
||||
{ "alarm": "/index.html" }
|
||||
],
|
||||
"type": "privileged"
|
||||
"type": "privileged",
|
||||
"precompile": [
|
||||
"libs/rusha.js",
|
||||
"libs/relooper.js"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3,29 +3,39 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var fgMidletNumber;
|
||||
var fgMidletClass;
|
||||
|
||||
function backgroundCheck() {
|
||||
if (!MIDP.manifest["Nokia-MIDlet-bg-server"]) {
|
||||
var bgServer = MIDP.manifest["Nokia-MIDlet-bg-server"];
|
||||
if (!bgServer) {
|
||||
document.getElementById("splash-screen").style.display = "block";
|
||||
document.getElementById("background-screen").style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
// We're assuming there are only two midlets
|
||||
fgMidletNumber = (bgServer == 2) ? 1 : 2;
|
||||
fgMidletClass = MIDP.manifest["MIDlet-" + fgMidletNumber].split(",")[2];
|
||||
|
||||
DumbPipe.close(DumbPipe.open("backgroundCheck", {}));
|
||||
}
|
||||
|
||||
Native["com/nokia/mid/s40/bg/BGUtils.getFGMIDletClass.()Ljava/lang/String;"] = function() {
|
||||
return J2ME.newString(config.fgMidletClass);
|
||||
return J2ME.newString(fgMidletClass);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/s40/bg/BGUtils.getFGMIDletNumber.()I"] = function() {
|
||||
return 1;
|
||||
return fgMidletNumber;
|
||||
};
|
||||
|
||||
MIDP.additionalProperties = {};
|
||||
|
||||
Native["com/nokia/mid/s40/bg/BGUtils.addSystemProperties.(Ljava/lang/String;)V"] = function(args) {
|
||||
util.fromJavaString(args).split(";").splice(1).forEach(function(arg) {
|
||||
var elems = arg.split("=");
|
||||
MIDP.additionalProperties[elems[0]] = elems[1];
|
||||
});
|
||||
util.fromJavaString(args).split(";").splice(1).forEach(function(arg) {
|
||||
var elems = arg.split("=");
|
||||
MIDP.additionalProperties[elems[0]] = elems[1];
|
||||
});
|
||||
};
|
||||
|
||||
var localmsgServerCreated = false;
|
||||
|
@ -35,8 +45,8 @@ Native["com/nokia/mid/s40/bg/BGUtils.waitUserInteraction.()V"] = function() {
|
|||
asyncImpl("V", new Promise(function(resolve, reject) {
|
||||
// If the page is visible, just start the FG MIDlet
|
||||
if (!document.hidden) {
|
||||
resolve();
|
||||
return;
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, wait until the page becomes visible, then start the FG MIDlet
|
||||
|
@ -55,5 +65,8 @@ Native["com/nokia/mid/s40/bg/BGUtils.waitUserInteraction.()V"] = function() {
|
|||
|
||||
localmsgServerWait = resolve;
|
||||
});
|
||||
}).then(function() {
|
||||
document.getElementById("splash-screen").style.display = "block";
|
||||
document.getElementById("background-screen").style.display = "none";
|
||||
}));
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@ DataEncoder.prototype.getData = function() {
|
|||
}
|
||||
|
||||
var DataDecoder = function(data, offset, length) {
|
||||
this.data = JSON.parse(util.decodeUtf8(new Uint8Array(data.buffer, offset, length)));
|
||||
this.data = JSON.parse(util.decodeUtf8(new Int8Array(data.buffer, offset, length)));
|
||||
this.current = [];
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ Native["com/sun/midp/crypto/SHA.nativeFinal.([BII[BI[I[I[I[I)V"] = function(inBu
|
|||
}
|
||||
|
||||
var hash = hasher.digest();
|
||||
outBuf.set(new Uint8Array(hash.buffer), outOff);
|
||||
outBuf.set(new Int8Array(hash.buffer), outOff);
|
||||
|
||||
// XXX Call the reset method instead to completely reset the object.
|
||||
data.set(MIDP.emptyDataArray);
|
||||
|
@ -120,7 +120,7 @@ Native["com/sun/midp/crypto/SHA.nativeClone.([I)V"] = function(data) {
|
|||
};
|
||||
|
||||
Native["com/sun/midp/crypto/MD5.nativeUpdate.([BII[I[I[I[I)V"] = function(inBuf, inOff, inLen, state, num, count, data) {
|
||||
MIDP.getMD5Hasher(data).update(MIDP.bin2String(new Uint8Array(inBuf.subarray(inOff, inOff + inLen))));
|
||||
MIDP.getMD5Hasher(data).update(MIDP.bin2String(new Int8Array(inBuf.subarray(inOff, inOff + inLen))));
|
||||
};
|
||||
|
||||
Native["com/sun/midp/crypto/MD5.nativeFinal.([BII[BI[I[I[I[I)V"] = function(inBuf, inOff, inLen, outBuf, outOff, state, num, count, data) {
|
||||
|
|
|
@ -484,7 +484,7 @@ Native["com/ibm/oti/connection/file/FCInputStream.readByteImpl.(I)I"] = function
|
|||
|
||||
var data = fs.read(fd, curpos, curpos+1);
|
||||
|
||||
return (data.byteLength > 0) ? data[0] : -1;
|
||||
return (data.byteLength > 0) ? (data[0] & 0xFF) : -1;
|
||||
};
|
||||
|
||||
Native["com/ibm/oti/connection/file/FCInputStream.closeImpl.(I)V"] = function(fd) {
|
||||
|
@ -542,7 +542,7 @@ Native["com/ibm/oti/connection/file/FCOutputStream.syncImpl.(I)V"] = function(fd
|
|||
};
|
||||
|
||||
Native["com/ibm/oti/connection/file/FCOutputStream.writeByteImpl.(II)V"] = function(val, fd) {
|
||||
var buf = new Uint8Array(1);
|
||||
var buf = new Int8Array(1);
|
||||
buf[0] = val;
|
||||
fs.write(fd, buf);
|
||||
};
|
||||
|
|
272
midp/gfx.js
272
midp/gfx.js
|
@ -63,11 +63,11 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/sun/midp/lcdui/DisplayDevice.getScreenWidth0.(I)I"] = function(id) {
|
||||
return MIDP.ScreenWidth;
|
||||
return MIDP.Context2D.canvas.width;
|
||||
};
|
||||
|
||||
Native["com/sun/midp/lcdui/DisplayDevice.getScreenHeight0.(I)I"] = function(id) {
|
||||
return MIDP.ScreenHeight;
|
||||
return MIDP.Context2D.canvas.height;
|
||||
};
|
||||
|
||||
Native["com/sun/midp/lcdui/DisplayDevice.displayStateChanged0.(II)V"] = function(hardwareId, state) {
|
||||
|
@ -83,6 +83,7 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/sun/midp/lcdui/DisplayDevice.gainedForeground0.(II)V"] = function(hardwareId, displayId) {
|
||||
document.getElementById("background-screen").style.display = "none";
|
||||
document.getElementById("splash-screen").style.display = "none";
|
||||
var d = NativeDisplays.get(displayId);
|
||||
MIDP.setFullScreen(d.fullScreen);
|
||||
|
@ -493,16 +494,8 @@ var currentlyFocusedTextEditor;
|
|||
return [x, y];
|
||||
}
|
||||
|
||||
function abgrIntToCSS(pixel) {
|
||||
var a = (pixel >> 24) & 0xff;
|
||||
var b = (pixel >> 16) & 0xff;
|
||||
var g = (pixel >> 8) & 0xff;
|
||||
var r = pixel & 0xff;
|
||||
return "rgba(" + r + "," + g + "," + b + "," + (a/255) + ")";
|
||||
};
|
||||
|
||||
function withPixel(g, c) {
|
||||
c.fillStyle = c.strokeStyle = abgrIntToCSS(g.pixel);
|
||||
c.fillStyle = c.strokeStyle = util.abgrIntToCSS(g.pixel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -818,7 +811,9 @@ var currentlyFocusedTextEditor;
|
|||
context.putImageData(imageData, 0, 0);
|
||||
|
||||
var c = withGraphics(graphics);
|
||||
c.save();
|
||||
if (graphics.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(graphics, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -826,7 +821,9 @@ var currentlyFocusedTextEditor;
|
|||
|
||||
c.drawImage(context.canvas, x, y);
|
||||
|
||||
c.restore();
|
||||
if (graphics.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.render.(Ljavax/microedition/lcdui/Image;III)Z"] = function(image, x, y, anchor) {
|
||||
|
@ -837,7 +834,9 @@ var currentlyFocusedTextEditor;
|
|||
var texture = image.imageData.context.canvas;
|
||||
|
||||
var c = withGraphics(g);
|
||||
c.save();
|
||||
if (g.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withAnchor(g, c, anchor, x, y, texture.width, texture.height);
|
||||
x = pair[0];
|
||||
|
@ -845,7 +844,9 @@ var currentlyFocusedTextEditor;
|
|||
|
||||
c.drawImage(texture, x, y);
|
||||
|
||||
c.restore();
|
||||
if (g.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -990,6 +991,7 @@ var currentlyFocusedTextEditor;
|
|||
this.displayId = -1;
|
||||
this.img = null;
|
||||
this.style = SOLID;
|
||||
this.clipped = false;
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.initScreen0.(III)V"] = function(displayId, w, h) {
|
||||
|
@ -1138,30 +1140,32 @@ var currentlyFocusedTextEditor;
|
|||
var font = g.currentFont;
|
||||
|
||||
var c = withGraphics(g);
|
||||
c.save();
|
||||
if (g.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(g, c, x, y);
|
||||
x = pair[0];
|
||||
y = pair[1];
|
||||
|
||||
if (isOpaque) {
|
||||
withOpaquePixel(g, c);
|
||||
} else {
|
||||
withPixel(g, c);
|
||||
}
|
||||
|
||||
parseEmojiString(str).forEach(function(part) {
|
||||
if (part.text) {
|
||||
var pair = withTextAnchor(g, c, anchor, x, y, part.text);
|
||||
var textX = pair[0];
|
||||
var textY = pair[1];
|
||||
|
||||
if (isOpaque) {
|
||||
withOpaquePixel(g, c);
|
||||
} else {
|
||||
withPixel(g, c);
|
||||
}
|
||||
|
||||
c.fillText(part.text, textX, textY);
|
||||
|
||||
// If there are emojis in the string that we need to draw,
|
||||
// we need to calculate the string width
|
||||
if (part.emoji) {
|
||||
x += measureWidth(c, part.text)
|
||||
x += measureWidth(c, part.text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1172,7 +1176,9 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
});
|
||||
|
||||
c.restore();
|
||||
if (g.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
}
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.drawString.(Ljava/lang/String;III)V"] = function(str, x, y, anchor) {
|
||||
|
@ -1192,7 +1198,9 @@ var currentlyFocusedTextEditor;
|
|||
var chr = String.fromCharCode(jChr);
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -1204,12 +1212,16 @@ var currentlyFocusedTextEditor;
|
|||
|
||||
c.fillText(chr, x, y);
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.fillTriangle.(IIIIII)V"] = function(x1, y1, x2, y2, x3, y3) {
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x1, y1);
|
||||
var x = pair[0];
|
||||
|
@ -1229,7 +1241,9 @@ var currentlyFocusedTextEditor;
|
|||
c.closePath();
|
||||
c.fill();
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.drawRect.(IIII)V"] = function(x, y, w, h) {
|
||||
|
@ -1238,7 +1252,9 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -1251,7 +1267,9 @@ var currentlyFocusedTextEditor;
|
|||
|
||||
c.strokeRect(x, y, w, h);
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.drawRoundRect.(IIIIII)V"] = function(x, y, w, h, arcWidth, arcHeight) {
|
||||
|
@ -1260,7 +1278,9 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -1275,7 +1295,9 @@ var currentlyFocusedTextEditor;
|
|||
createRoundRect(c, x, y, w, h, arcWidth, arcHeight);
|
||||
c.stroke();
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.fillRect.(IIII)V"] = function(x, y, w, h) {
|
||||
|
@ -1284,7 +1306,9 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -1297,7 +1321,9 @@ var currentlyFocusedTextEditor;
|
|||
|
||||
c.fillRect(x, y, w, h);
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.fillRoundRect.(IIIIII)V"] = function(x, y, w, h, arcWidth, arcHeight) {
|
||||
|
@ -1306,7 +1332,9 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -1321,7 +1349,9 @@ var currentlyFocusedTextEditor;
|
|||
createRoundRect(c, x, y, w, h, arcWidth, arcHeight);
|
||||
c.fill();
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.drawArc.(IIIIII)V"] = function(x, y, width, height, startAngle, arcAngle) {
|
||||
|
@ -1330,7 +1360,6 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
|
||||
withPixel(this, c);
|
||||
|
||||
|
@ -1339,8 +1368,6 @@ var currentlyFocusedTextEditor;
|
|||
c.beginPath();
|
||||
createEllipticalArc(c, x, y, width / 2, height / 2, startRad, endRad, false);
|
||||
c.stroke();
|
||||
|
||||
c.restore();
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.fillArc.(IIIIII)V"] = function(x, y, width, height, startAngle, arcAngle) {
|
||||
|
@ -1349,7 +1376,6 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
|
||||
withPixel(this, c);
|
||||
|
||||
|
@ -1360,8 +1386,6 @@ var currentlyFocusedTextEditor;
|
|||
createEllipticalArc(c, x, y, width / 2, height / 2, startRad, endRad, true);
|
||||
c.moveTo(x, y);
|
||||
c.fill();
|
||||
|
||||
c.restore();
|
||||
};
|
||||
|
||||
var TRANS_NONE = 0;
|
||||
|
@ -1378,14 +1402,14 @@ var currentlyFocusedTextEditor;
|
|||
texture = imgData.context.canvas;
|
||||
|
||||
var c = withGraphics(g);
|
||||
c.save();
|
||||
if (g.clipped || transform !== TRANS_NONE) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withAnchor(g, c, anchor, x, y, sw, sh);
|
||||
x = pair[0];
|
||||
y = pair[1];
|
||||
|
||||
c.translate(x, y);
|
||||
|
||||
if (transform === TRANS_MIRROR || transform === TRANS_MIRROR_ROT180) {
|
||||
c.scale(-1, 1);
|
||||
} else if (transform === TRANS_MIRROR_ROT90 || transform === TRANS_MIRROR_ROT270) {
|
||||
|
@ -1398,16 +1422,20 @@ var currentlyFocusedTextEditor;
|
|||
c.rotate(1.5 * Math.PI);
|
||||
}
|
||||
|
||||
c.drawImage(texture, sx, sy, sw, sh, 0, 0, sw, sh);
|
||||
c.drawImage(texture, sx, sy, sw, sh, x, y, sw, sh);
|
||||
|
||||
c.restore();
|
||||
if (g.clipped || transform !== TRANS_NONE) {
|
||||
c.restore();
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.drawLine.(IIII)V"] = function(x1, y1, x2, y2) {
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x1, y1);
|
||||
var x = pair[0];
|
||||
|
@ -1430,7 +1458,9 @@ var currentlyFocusedTextEditor;
|
|||
c.stroke();
|
||||
c.closePath();
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Graphics.drawRGB.([IIIIIIIZ)V"] =
|
||||
|
@ -1445,7 +1475,9 @@ var currentlyFocusedTextEditor;
|
|||
context.putImageData(imageData, 0, 0);
|
||||
|
||||
var c = withGraphics(this);
|
||||
c.save();
|
||||
if (this.clipped) {
|
||||
c.save();
|
||||
}
|
||||
|
||||
var pair = withClip(this, c, x, y);
|
||||
x = pair[0];
|
||||
|
@ -1453,40 +1485,38 @@ var currentlyFocusedTextEditor;
|
|||
|
||||
c.drawImage(context.canvas, x, y);
|
||||
|
||||
c.restore();
|
||||
if (this.clipped) {
|
||||
c.restore();
|
||||
}
|
||||
};
|
||||
|
||||
var textEditorId = 0,
|
||||
textEditorResolve = null,
|
||||
dirtyEditors = [];
|
||||
|
||||
function wakeTextEditorThread(id) {
|
||||
dirtyEditors.push(id);
|
||||
function wakeTextEditorThread(textEditor) {
|
||||
dirtyEditors.push(textEditor);
|
||||
if (textEditorResolve) {
|
||||
textEditorResolve();
|
||||
textEditorResolve = null;
|
||||
}
|
||||
}
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.init.(Ljava/lang/String;IIII)I"] =
|
||||
Native["com/nokia/mid/ui/TextEditor.init.(Ljava/lang/String;IIII)V"] =
|
||||
function(text, maxSize, constraints, width, height) {
|
||||
if (constraints != 0) {
|
||||
console.warn("TextEditor.constraints not implemented");
|
||||
}
|
||||
|
||||
this.textEditorId = ++textEditorId;
|
||||
this.textEditor = TextEditorProvider.createEditor(constraints);
|
||||
this.textEditor = TextEditorProvider.getEditor(constraints, null, this.textEditorId);
|
||||
this.visible = false;
|
||||
this.backgroundColor = 0xFFFFFFFF | 0; // opaque white
|
||||
this.foregroundColor = 0xFF000000 | 0; // opaque black
|
||||
this.textEditor.setStyle("border", "none");
|
||||
this.textEditor.setStyle("resize", "none");
|
||||
this.textEditor.setStyle("backgroundColor", abgrIntToCSS(this.backgroundColor));
|
||||
this.textEditor.setStyle("color", abgrIntToCSS(this.foregroundColor));
|
||||
this.textEditor.setBackgroundColor(0xFFFFFFFF | 0); // opaque white
|
||||
this.textEditor.setForegroundColor(0xFF000000 | 0); // opaque black
|
||||
|
||||
this.getCaretPosition = function() {
|
||||
if (this.textEditor.getParent()) {
|
||||
return this.textEditor.getSelectionStart().index;
|
||||
if (this.textEditor.isAttached()) {
|
||||
return this.textEditor.getSelectionStart();
|
||||
}
|
||||
if (this.caretPosition !== null) {
|
||||
return this.caretPosition;
|
||||
|
@ -1495,7 +1525,7 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
this.setCaretPosition = function(index) {
|
||||
if (this.textEditor.getParent()) {
|
||||
if (this.textEditor.isAttached()) {
|
||||
this.textEditor.setSelectionRange(index, index);
|
||||
} else {
|
||||
this.caretPosition = index;
|
||||
|
@ -1503,24 +1533,21 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
this.textEditor.setAttribute("maxlength", maxSize);
|
||||
this.textEditor.setStyle("width", width + "px");
|
||||
this.textEditor.setStyle("height", height + "px");
|
||||
this.textEditor.setStyle("position", "absolute");
|
||||
this.textEditor.setSize(width, height);
|
||||
this.textEditor.setVisible(false);
|
||||
var font = this.klass.classInfo.getField("I.font.Ljavax/microedition/lcdui/Font;").get(this);
|
||||
this.textEditor.setFont(font);
|
||||
|
||||
this.textEditor.setContent(util.fromJavaString(text));
|
||||
this.setCaretPosition(this.textEditor.getSize());
|
||||
this.setCaretPosition(this.textEditor.getContentSize());
|
||||
|
||||
this.textEditor.oninput(function(e) {
|
||||
wakeTextEditorThread(this.textEditorId);
|
||||
wakeTextEditorThread(this);
|
||||
}.bind(this));
|
||||
return textEditorId;
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.attachNativeImpl.()V"] = function() {
|
||||
this.textEditor.setParent(document.getElementById("display"));
|
||||
this.textEditor.attach();
|
||||
if (this.caretPosition !== null) {
|
||||
this.textEditor.setSelectionRange(this.caretPosition, this.caretPosition);
|
||||
this.caretPosition = null;
|
||||
|
@ -1528,27 +1555,8 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.detachNativeImpl.()V"] = function() {
|
||||
this.caretPosition = this.textEditor.getSelectionStart().index;
|
||||
this.textEditor.setParent(null);
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Display.unfocusTextEditorForScreenChange.()V"] = function() {
|
||||
if (currentlyFocusedTextEditor) {
|
||||
currentlyFocusedTextEditor.blur();
|
||||
currentlyFocusedTextEditor = null;
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Display.unfocusTextEditorForAlert.()V"] = function() {
|
||||
if (currentlyFocusedTextEditor) {
|
||||
currentlyFocusedTextEditor.blur();
|
||||
}
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Display.refocusTextEditorAfterAlert.()V"] = function() {
|
||||
if (currentlyFocusedTextEditor) {
|
||||
currentlyFocusedTextEditor.focus();
|
||||
}
|
||||
this.caretPosition = this.textEditor.getSelectionStart();
|
||||
this.textEditor.detach();
|
||||
};
|
||||
|
||||
Native["javax/microedition/lcdui/Display.setTitle.(Ljava/lang/String;)V"] = function(title) {
|
||||
|
@ -1556,8 +1564,7 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.setSize.(II)V"] = function(width, height) {
|
||||
this.textEditor.setStyle("width", width + "px");
|
||||
this.textEditor.setStyle("height", height + "px");
|
||||
this.textEditor.setSize(width, height);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.setVisible.(Z)V"] = function(visible) {
|
||||
|
@ -1566,26 +1573,23 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.getWidth.()I"] = function() {
|
||||
return parseInt(this.textEditor.getStyle("width"));
|
||||
return this.textEditor.getWidth();
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.getHeight.()I"] = function() {
|
||||
return parseInt(this.textEditor.getStyle("height"));
|
||||
return this.textEditor.getHeight();
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.setPosition0.(II)V"] = function(x, y) {
|
||||
var top = MIDP.Context2D.canvas.offsetTop;
|
||||
this.textEditor.setStyle("left", x + "px");
|
||||
this.textEditor.setStyle("top", (top + y) + "px");
|
||||
this.textEditor.setPosition(x, y);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.getPositionX.()I"] = function() {
|
||||
return parseInt(this.textEditor.getStyle("left")) || 0;
|
||||
return this.textEditor.getLeft();
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.getPositionY.()I"] = function() {
|
||||
var base = MIDP.Context2D.canvas.offsetTop;
|
||||
return (parseInt(this.textEditor.getStyle("top")) - base) || 0;
|
||||
return this.textEditor.getTop();
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/CanvasItem.isVisible.()Z"] = function() {
|
||||
|
@ -1593,22 +1597,25 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.setConstraints.(I)V"] = function(constraints) {
|
||||
this.textEditor.setConstraints(constraints);
|
||||
this.textEditor = TextEditorProvider.getEditor(constraints, this.textEditor, this.textEditorId);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.getConstraints.()I"] = function() {
|
||||
return this.textEditor.getConstraints();
|
||||
return this.textEditor.constraints;
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.setFocus.(Z)V"] = function(shouldFocus) {
|
||||
var promise;
|
||||
if (shouldFocus && (currentlyFocusedTextEditor != this.textEditor)) {
|
||||
this.textEditor.focus();
|
||||
promise = this.textEditor.focus();
|
||||
currentlyFocusedTextEditor = this.textEditor;
|
||||
} else if (!shouldFocus && (currentlyFocusedTextEditor == this.textEditor)) {
|
||||
this.textEditor.blur();
|
||||
promise = this.textEditor.blur();
|
||||
currentlyFocusedTextEditor = null;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
this.focused = shouldFocus;
|
||||
asyncImpl("V", promise);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.hasFocus.()Z"] = function() {
|
||||
|
@ -1616,7 +1623,7 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.setCaret.(I)V"] = function(index) {
|
||||
if (index < 0 || index > this.textEditor.getSize()) {
|
||||
if (index < 0 || index > this.textEditor.getContentSize()) {
|
||||
throw $.newStringIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
|
@ -1628,18 +1635,16 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.getBackgroundColor.()I"] = function() {
|
||||
return this.backgroundColor;
|
||||
return this.textEditor.getBackgroundColor();
|
||||
};
|
||||
Native["com/nokia/mid/ui/TextEditor.getForegroundColor.()I"] = function() {
|
||||
return this.foregroundColor;
|
||||
return this.textEditor.getForegroundColor();
|
||||
};
|
||||
Native["com/nokia/mid/ui/TextEditor.setBackgroundColor.(I)V"] = function(backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.textEditor.setStyle("backgroundColor", abgrIntToCSS(backgroundColor));
|
||||
this.textEditor.setBackgroundColor(backgroundColor);
|
||||
};
|
||||
Native["com/nokia/mid/ui/TextEditor.setForegroundColor.(I)V"] = function(foregroundColor) {
|
||||
this.foregroundColor = foregroundColor;
|
||||
this.textEditor.setStyle("color", abgrIntToCSS(foregroundColor));
|
||||
this.textEditor.setForegroundColor(foregroundColor);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.getContent.()Ljava/lang/String;"] = function() {
|
||||
|
@ -1649,7 +1654,7 @@ var currentlyFocusedTextEditor;
|
|||
Native["com/nokia/mid/ui/TextEditor.setContent.(Ljava/lang/String;)V"] = function(jStr) {
|
||||
var str = util.fromJavaString(jStr);
|
||||
this.textEditor.setContent(str);
|
||||
this.setCaretPosition(this.textEditor.getSize());
|
||||
this.setCaretPosition(this.textEditor.getContentSize());
|
||||
};
|
||||
|
||||
addUnimplementedNative("com/nokia/mid/ui/TextEditor.getLineMarginHeight.()I", 0);
|
||||
|
@ -1662,7 +1667,7 @@ var currentlyFocusedTextEditor;
|
|||
Native["com/nokia/mid/ui/TextEditor.insert.(Ljava/lang/String;I)V"] = function(jStr, pos) {
|
||||
var str = util.fromJavaString(jStr);
|
||||
var len = util.toCodePointArray(str).length;
|
||||
if (this.textEditor.getSize() + len > this.textEditor.getAttribute("maxlength")) {
|
||||
if (this.textEditor.getContentSize() + len > this.textEditor.getAttribute("maxlength")) {
|
||||
throw $.newIllegalArgumentException();
|
||||
}
|
||||
this.textEditor.setContent(this.textEditor.getSlice(0, pos) + str + this.textEditor.getSlice(pos));
|
||||
|
@ -1672,7 +1677,7 @@ var currentlyFocusedTextEditor;
|
|||
Native["com/nokia/mid/ui/TextEditor.delete.(II)V"] = function(offset, length) {
|
||||
var old = this.textEditor.getContent();
|
||||
|
||||
var size = this.textEditor.getSize();
|
||||
var size = this.textEditor.getContentSize();
|
||||
if (offset < 0 || offset > size || length < 0 || offset + length > size) {
|
||||
throw $.newStringIndexOutOfBoundsException("offset/length invalid");
|
||||
}
|
||||
|
@ -1686,7 +1691,7 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.setMaxSize.(I)I"] = function(maxSize) {
|
||||
if (this.textEditor.getSize() > maxSize) {
|
||||
if (this.textEditor.getContentSize() > maxSize) {
|
||||
var oldCaretPosition = this.getCaretPosition();
|
||||
|
||||
this.textEditor.setContent(this.textEditor.getSlice(0, maxSize));
|
||||
|
@ -1705,7 +1710,7 @@ var currentlyFocusedTextEditor;
|
|||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.size.()I"] = function() {
|
||||
return this.textEditor.getSize();
|
||||
return this.textEditor.getContentSize();
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditor.setFont.(Ljavax/microedition/lcdui/Font;)V"] = function(font) {
|
||||
|
@ -1713,23 +1718,16 @@ var currentlyFocusedTextEditor;
|
|||
this.textEditor.setFont(font);
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditorThread.sleep.()V"] = function() {
|
||||
asyncImpl("V", new Promise(function(resolve, reject) {
|
||||
if (!dirtyEditors.length) {
|
||||
textEditorResolve = resolve;
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
Native["com/nokia/mid/ui/TextEditorThread.getNextDirtyEditor.()I"] = function() {
|
||||
if (!dirtyEditors.length) {
|
||||
console.error("ERROR: getNextDirtyEditor called but no dirty editors");
|
||||
return 0;
|
||||
Native["com/nokia/mid/ui/TextEditorThread.getNextDirtyEditor.()Lcom/nokia/mid/ui/TextEditor;"] = function() {
|
||||
if (dirtyEditors.length) {
|
||||
return dirtyEditors.shift();
|
||||
}
|
||||
|
||||
return dirtyEditors.shift();
|
||||
asyncImpl("I", new Promise(function(resolve, reject) {
|
||||
textEditorResolve = function() {
|
||||
resolve(dirtyEditors.shift());
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
var curDisplayableId = 0;
|
||||
|
@ -1746,6 +1744,8 @@ var currentlyFocusedTextEditor;
|
|||
if (currentlyFocusedTextEditor) {
|
||||
currentlyFocusedTextEditor.focus();
|
||||
}
|
||||
} else if (currentlyFocusedTextEditor) {
|
||||
currentlyFocusedTextEditor.blur();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1947,7 +1947,9 @@ var currentlyFocusedTextEditor;
|
|||
}
|
||||
var li = document.createElement("li");
|
||||
var text = util.fromJavaString(command.klass.classInfo.getField("I.shortLabel.Ljava/lang/String;").get(command));
|
||||
li.innerHTML = "<a>" + text + "</a>";
|
||||
var a = document.createElement("a");
|
||||
a.textContent = text;
|
||||
li.appendChild(a);
|
||||
|
||||
li.onclick = function(e) {
|
||||
e.preventDefault();
|
||||
|
|
|
@ -174,7 +174,7 @@ NokiaMessagingLocalMsgConnection.prototype.sendMessageToServer = function(messag
|
|||
|
||||
default:
|
||||
console.error("(nokia.messaging) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -381,7 +381,7 @@ NokiaPhoneStatusLocalMsgConnection.prototype.sendMessageToServer = function(mess
|
|||
|
||||
default:
|
||||
console.error("(nokia.phone-status) Query " + decoder.getName() + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
break;
|
||||
}
|
||||
} else if (queryKind === "Disable") {
|
||||
|
@ -407,7 +407,7 @@ NokiaPhoneStatusLocalMsgConnection.prototype.sendMessageToServer = function(mess
|
|||
|
||||
default:
|
||||
console.error("(nokia.phone-status) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -526,7 +526,7 @@ NokiaContactsLocalMsgConnection.prototype.sendMessageToServer = function(message
|
|||
var numEntries = decoder.getValue(DataType.ULONG);
|
||||
if (numEntries !== 1) {
|
||||
console.error("(nokia.contacts) event getFirst with numEntries != 1 not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
}
|
||||
|
||||
this.getFirstOrNext(trans_id, "getFirst");
|
||||
|
@ -542,12 +542,12 @@ NokiaContactsLocalMsgConnection.prototype.sendMessageToServer = function(message
|
|||
var includeStartEntry = decoder.getValue(DataType.BOOLEAN);
|
||||
if (includeStartEntry == 1) {
|
||||
console.error("(nokia.contacts) event getNext with includeStartEntry == true not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
}
|
||||
var numEntries = decoder.getValue(DataType.ULONG);
|
||||
if (numEntries !== 1) {
|
||||
console.error("(nokia.contacts) event getNext with numEntries != 1 not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
}
|
||||
|
||||
this.getFirstOrNext(trans_id, "getNext");
|
||||
|
@ -555,7 +555,7 @@ NokiaContactsLocalMsgConnection.prototype.sendMessageToServer = function(message
|
|||
|
||||
default:
|
||||
console.error("(nokia.contacts) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -684,7 +684,7 @@ NokiaFileUILocalMsgConnection.prototype.sendMessageToServer = function(message)
|
|||
|
||||
default:
|
||||
console.error("(nokia.file-ui) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -756,7 +756,7 @@ NokiaImageProcessingLocalMsgConnection.prototype.sendMessageToServer = function(
|
|||
|
||||
if (aspect != "FullImage" && aspect != "LockToPartialView") {
|
||||
console.error("(nokia.image-processing) event " + name + " with aspect != 'FullImage' or 'LockToPartialView' not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -859,7 +859,7 @@ NokiaImageProcessingLocalMsgConnection.prototype.sendMessageToServer = function(
|
|||
|
||||
default:
|
||||
console.error("(nokia.image-processing) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -913,7 +913,7 @@ NokiaProductInfoLocalMsgConnection.prototype.sendMessageToServer = function(mess
|
|||
break;
|
||||
default:
|
||||
console.error("(nokia.status-info) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -1038,7 +1038,7 @@ NokiaActiveStandbyLocalMsgConnection.prototype.sendMessageToServer = function(me
|
|||
|
||||
default:
|
||||
console.error("(nokia.active-standby) event " + name + " not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
util.decodeUtf8(new Int8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1124,7 +1124,7 @@ Native["org/mozilla/io/LocalMsgConnection.sendData.([BII)V"] = function(data, of
|
|||
this.connection.sendMessageToClient(message);
|
||||
} else {
|
||||
if (MIDP.FakeLocalMsgServers.indexOf(this.protocolName) != -1) {
|
||||
console.warn("sendData (" + util.decodeUtf8(new Uint8Array(data.buffer, offset, length)) + ") to an unimplemented localmsg server (" + this.protocolName + ")");
|
||||
console.warn("sendData (" + util.decodeUtf8(new Int8Array(data.buffer, offset, length)) + ") to an unimplemented localmsg server (" + this.protocolName + ")");
|
||||
}
|
||||
|
||||
this.connection.sendMessageToServer(message);
|
||||
|
|
|
@ -714,7 +714,7 @@ PlayerContainer.prototype.getRecordedSize = function() {
|
|||
PlayerContainer.prototype.getRecordedData = function(offset, size, buffer) {
|
||||
var toRead = (size < this.audioRecorder.data.length) ? size : this.audioRecorder.data.byteLength;
|
||||
buffer.set(this.audioRecorder.data.subarray(0, toRead), offset);
|
||||
this.audioRecorder.data = new Uint8Array(this.audioRecorder.data.buffer.slice(toRead));
|
||||
this.audioRecorder.data = new Int8Array(this.audioRecorder.data.buffer.slice(toRead));
|
||||
};
|
||||
|
||||
PlayerContainer.prototype.startSnapshot = function(imageType) {
|
||||
|
@ -732,7 +732,7 @@ PlayerContainer.prototype.getDuration = function() {
|
|||
var AudioRecorder = function(aMimeType) {
|
||||
this.mimeType = aMimeType || "audio/3gpp";
|
||||
this.eventListeners = {};
|
||||
this.data = new Uint8Array();
|
||||
this.data = new Int8Array();
|
||||
this.sender = DumbPipe.open("audiorecorder", {
|
||||
mimeType: this.mimeType
|
||||
}, this.recipient.bind(this));
|
||||
|
@ -816,7 +816,7 @@ AudioRecorder.prototype.stop = function() {
|
|||
// The audio data we received are encoded with a proper format, it doesn't
|
||||
// make sense to concatenate them like the socket, so let just override
|
||||
// the buffered data here.
|
||||
var data = new Uint8Array(message.data);
|
||||
var data = new Int8Array(message.data);
|
||||
if (this.getContentType() === "audio/amr") {
|
||||
data = Media.convert3gpToAmr(data);
|
||||
}
|
||||
|
@ -854,7 +854,7 @@ AudioRecorder.prototype.pause = function() {
|
|||
// The audio data we received are encoded with a proper format, it doesn't
|
||||
// make sense to concatenate them like the socket, so let just override
|
||||
// the buffered data here.
|
||||
this.data = new Uint8Array(message.data);
|
||||
this.data = new Int8Array(message.data);
|
||||
resolve(1);
|
||||
}.bind(this);
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ Native["com/sun/mmedia/DirectPlayer.nGetMediaTime.(I)I"] = function(handle) {
|
|||
|
||||
Native["com/sun/mmedia/DirectPlayer.nSetMediaTime.(IJ)I"] = function(handle, ms) {
|
||||
var container = Media.PlayerCache[handle];
|
||||
return container.player.setMediaTime(ms);
|
||||
return container.player.setMediaTime(ms.toInt());
|
||||
};
|
||||
|
||||
Native["com/sun/mmedia/DirectPlayer.nStart.(I)Z"] = function(handle) {
|
||||
|
|
59
midp/midp.js
59
midp/midp.js
|
@ -97,7 +97,7 @@ Native["com/sun/midp/jarutil/JarReader.readJarEntry0.(Ljava/lang/String;Ljava/la
|
|||
if (!bytes)
|
||||
throw $.newIOException();
|
||||
var length = bytes.byteLength;
|
||||
var data = new Uint8Array(bytes);
|
||||
var data = new Int8Array(bytes);
|
||||
var array = J2ME.newByteArray(length);
|
||||
for (var n = 0; n < length; ++n)
|
||||
array[n] = data[n];
|
||||
|
@ -489,7 +489,7 @@ Native["com/sun/midp/main/Configuration.getProperty0.(Ljava/lang/String;)Ljava/l
|
|||
}
|
||||
break;
|
||||
case "com.sun.midp.events.dispatchTableInitSize":
|
||||
value = "16";
|
||||
value = "71";
|
||||
break;
|
||||
case "microedition.locale":
|
||||
value = navigator.language;
|
||||
|
@ -535,7 +535,7 @@ Native["com/sun/midp/util/ResourceHandler.loadRomizedResource0.(Ljava/lang/Strin
|
|||
}
|
||||
var len = data.byteLength;
|
||||
var bytes = J2ME.newByteArray(len);
|
||||
var src = new Uint8Array(data);
|
||||
var src = new Int8Array(data);
|
||||
for (var n = 0; n < bytes.byteLength; ++n)
|
||||
bytes[n] = src[n];
|
||||
return bytes;
|
||||
|
@ -551,11 +551,6 @@ MIDP.Context2D = (function() {
|
|||
c.width = window.innerWidth;
|
||||
c.height = window.innerHeight;
|
||||
document.documentElement.classList.add('autosize');
|
||||
c.style.position = "fixed";
|
||||
c.style.top = "0px";
|
||||
c.style.left = "0px";
|
||||
c.style.height = c.height + "px";
|
||||
c.style.width = c.width + "px";
|
||||
window.addEventListener("resize", MIDP.onWindowResize);
|
||||
} else {
|
||||
document.documentElement.classList.add('debug-mode');
|
||||
|
@ -867,33 +862,29 @@ Native["com/sun/midp/util/isolate/InterIsolateMutex.getID0.(Ljava/lang/String;)I
|
|||
|
||||
Native["com/sun/midp/util/isolate/InterIsolateMutex.lock0.(I)V"] = function(id) {
|
||||
var ctx = $.ctx;
|
||||
var mutex;
|
||||
for (var i = 0; i < MIDP.InterIsolateMutexes.length; i++) {
|
||||
if (MIDP.InterIsolateMutexes[i].id == id) {
|
||||
mutex = MIDP.InterIsolateMutexes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mutex) {
|
||||
throw $.newIllegalStateException("Invalid mutex ID");
|
||||
}
|
||||
|
||||
if (!mutex.locked) {
|
||||
mutex.locked = true;
|
||||
mutex.holder = ctx.runtime.isolate.id;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mutex.holder == ctx.runtime.isolate.id) {
|
||||
throw $.newRuntimeException("Attempting to lock mutex twice within the same Isolate");
|
||||
}
|
||||
|
||||
asyncImpl("V", new Promise(function(resolve, reject) {
|
||||
ctx.setAsCurrentContext();
|
||||
var mutex;
|
||||
for (var i = 0; i < MIDP.InterIsolateMutexes.length; i++) {
|
||||
if (MIDP.InterIsolateMutexes[i].id == id) {
|
||||
mutex = MIDP.InterIsolateMutexes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mutex) {
|
||||
reject($.newIllegalStateException("Invalid mutex ID"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mutex.locked) {
|
||||
mutex.locked = true;
|
||||
mutex.holder = ctx.runtime.isolate.id;
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mutex.holder == ctx.runtime.isolate.id) {
|
||||
reject($.newRuntimeException("Attempting to lock mutex twice within the same Isolate"));
|
||||
return;
|
||||
}
|
||||
|
||||
mutex.waiting.push(function() {
|
||||
mutex.locked = true;
|
||||
mutex.holder = ctx.runtime.isolate.id;
|
||||
|
|
|
@ -65,7 +65,7 @@ Native["com/sun/midp/io/j2me/socket/Protocol.open0.([BI)V"] = function(ipBytes,
|
|||
this.options[SOCKET_OPT.RCVBUF] = 8192;
|
||||
this.options[SOCKET_OPT.SNDBUF] = 8192;
|
||||
|
||||
this.data = new Uint8Array();
|
||||
this.data = new Int8Array();
|
||||
this.waitingData = null;
|
||||
|
||||
this.socket.onopen = function() {
|
||||
|
@ -88,11 +88,11 @@ Native["com/sun/midp/io/j2me/socket/Protocol.open0.([BI)V"] = function(ipBytes,
|
|||
this.socket.ondata = (function(message) {
|
||||
// console.log("this.socket.ondata: " + JSON.stringify(message));
|
||||
if (this.data.byteLength === 0) {
|
||||
this.data = new Uint8Array(message.data);
|
||||
this.data = new Int8Array(message.data);
|
||||
} else {
|
||||
var newArray = new Uint8Array(this.data.byteLength + message.data.byteLength);
|
||||
var newArray = new Int8Array(this.data.byteLength + message.data.byteLength);
|
||||
newArray.set(this.data);
|
||||
newArray.set(new Uint8Array(message.data), this.data.byteLength);
|
||||
newArray.set(new Int8Array(message.data), this.data.byteLength);
|
||||
this.data = newArray;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
var TextEditorProvider = (function() {
|
||||
var eTextArea = document.getElementById('textarea-editor');
|
||||
var ePassword = document.getElementById('password-editor');
|
||||
var currentVisibleEditor = null;
|
||||
|
||||
function extendsObject(targetObj, srcObj) {
|
||||
for (var m in srcObj) {
|
||||
targetObj[m] = srcObj[m];
|
||||
|
@ -9,110 +13,132 @@ var TextEditorProvider = (function() {
|
|||
}
|
||||
|
||||
var CommonEditorPrototype = {
|
||||
destroy: function() {
|
||||
if (this.textEditorElem && this.textEditorElem.parentNode) {
|
||||
this.textEditorElem.parentNode.removeChild(this.textEditorElem);
|
||||
}
|
||||
if (this.textEditorElem) {
|
||||
this.textEditorElem.oninput = null;
|
||||
}
|
||||
this.parentNode = null;
|
||||
this.textEditorElem = null;
|
||||
this.oninputCallback = null;
|
||||
this.constraints = null;
|
||||
this.attributes = null;
|
||||
attached: false,
|
||||
width: 0,
|
||||
height: 0,
|
||||
left: 0,
|
||||
top: 0,
|
||||
constraints: 0,
|
||||
type: "",
|
||||
content: "",
|
||||
visible: false,
|
||||
id: -1,
|
||||
selectionRange: [0, 0],
|
||||
focused: false,
|
||||
oninputCallback: null,
|
||||
|
||||
// opaque white
|
||||
backgroundColor: 0xFFFFFFFF | 0,
|
||||
|
||||
// opaque black
|
||||
foregroundColor: 0xFF000000 | 0,
|
||||
|
||||
attach: function() {
|
||||
this.attached = true;
|
||||
},
|
||||
|
||||
setParent: function(parentNode) {
|
||||
this.parentNode = parentNode;
|
||||
if (!parentNode) {
|
||||
if (this.textEditorElem.parentNode) {
|
||||
this.textEditorElem.parentNode.removeChild(this.textEditorElem);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.textEditorElem) {
|
||||
parentNode.appendChild(this.textEditorElem);
|
||||
}
|
||||
detach: function() {
|
||||
this.attached = false;
|
||||
},
|
||||
|
||||
getParent: function() {
|
||||
return this.parentNode;
|
||||
isAttached: function() {
|
||||
return this.attached;
|
||||
},
|
||||
|
||||
decorateTextEditorElem: function() {
|
||||
if (this.parentNode) {
|
||||
this.parentNode.appendChild(this.textEditorElem);
|
||||
}
|
||||
|
||||
// Set attributes and styles.
|
||||
// Set attributes.
|
||||
if (this.attributes) {
|
||||
for (var attr in this.attributes) {
|
||||
this.textEditorElem.setAttribute(attr, this.attributes[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.styles) {
|
||||
for (var styleKey in this.styles) {
|
||||
this.textEditorElem.style.setProperty(styleKey, this.styles[styleKey]);
|
||||
}
|
||||
}
|
||||
this.setContent(this.content);
|
||||
|
||||
this.setContent(this.content || '');
|
||||
if (this.selectionRange) {
|
||||
this.setSelectionRange(this.selectionRange[0], this.selectionRange[1]);
|
||||
delete this.selectionRange;
|
||||
}
|
||||
|
||||
if (this.focused) this.focus();
|
||||
this.setVisible(this.visible);
|
||||
this.setSelectionRange(this.selectionRange[0], this.selectionRange[1]);
|
||||
this.setSize(this.width, this.height);
|
||||
this.setFont(this.font);
|
||||
this.setPosition(this.left, this.top);
|
||||
this.setBackgroundColor(this.backgroundColor);
|
||||
this.setForegroundColor(this.foregroundColor);
|
||||
},
|
||||
|
||||
setStyle: function(styleKey, styleValue) {
|
||||
// Set input/textarea elem styles.
|
||||
if (!this.styles) {
|
||||
this.styles = {};
|
||||
}
|
||||
|
||||
this.styles[styleKey] = styleValue;
|
||||
if (this.textEditorElem) {
|
||||
_setStyle: function(styleKey, styleValue) {
|
||||
if (this.visible) {
|
||||
this.textEditorElem.style.setProperty(styleKey, styleValue);
|
||||
}
|
||||
},
|
||||
|
||||
getStyle: function(styleKey) {
|
||||
return (this.styles && this.styles[styleKey]) || null;
|
||||
},
|
||||
|
||||
focus: function() {
|
||||
this.focused = true;
|
||||
this.textEditorElem && this.textEditorElem.focus();
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (currentVisibleEditor !== this ||
|
||||
document.activeElement === this.textEditorElem) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
setTimeout(this.textEditorElem.focus.bind(this.textEditorElem));
|
||||
this.textEditorElem.onfocus = resolve;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
blur: function() {
|
||||
this.focused = false;
|
||||
this.textEditorElem && this.textEditorElem.blur();
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (currentVisibleEditor !== this ||
|
||||
document.activeElement !== this.textEditorElem) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
setTimeout(this.textEditorElem.blur.bind(this.textEditorElem));
|
||||
this.textEditorElem.onblur = resolve;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
getVisible: function() {
|
||||
return this.visible || false;
|
||||
return this.visible;
|
||||
},
|
||||
|
||||
setVisible: function(aVisible) {
|
||||
// Check if we need to show or hide the html editor elements.
|
||||
if ((currentVisibleEditor === this && aVisible) ||
|
||||
(currentVisibleEditor !== this && !aVisible)) {
|
||||
this.visible = aVisible;
|
||||
return;
|
||||
}
|
||||
|
||||
this.visible = aVisible;
|
||||
|
||||
if (aVisible) {
|
||||
// Sometimes in Java, setVisible() is called after focus(), to make
|
||||
// sure the native input won't lose focus, we change opacity instead
|
||||
// of visibility.
|
||||
this.setStyle('opaque', 1);
|
||||
this.setStyle('z-index', 999);
|
||||
if (currentVisibleEditor) {
|
||||
currentVisibleEditor.visible = false;
|
||||
}
|
||||
currentVisibleEditor = this;
|
||||
} else {
|
||||
this.setStyle('opaque', 0);
|
||||
// To make sure the j2me control could be clicked again to show the
|
||||
// textEditor, we need to put the textEditor at the bottom.
|
||||
this.setStyle('z-index', -999);
|
||||
currentVisibleEditor = null;
|
||||
}
|
||||
|
||||
if (aVisible) {
|
||||
this.textEditorElem.classList.add("show");
|
||||
} else {
|
||||
this.textEditorElem.classList.remove("show");
|
||||
}
|
||||
|
||||
if (this.visible) {
|
||||
var oldId = this.textEditorElem.getAttribute("editorId") || -1;
|
||||
if (oldId !== this.id) {
|
||||
this.textEditorElem.setAttribute("editorId", this.id);
|
||||
this.decorateTextEditorElem();
|
||||
if (this.focused) {
|
||||
setTimeout(this.textEditorElem.focus.bind(this.textEditorElem));
|
||||
}
|
||||
}
|
||||
this.activate();
|
||||
} else {
|
||||
if (!this.focused) {
|
||||
setTimeout(this.textEditorElem.blur.bind(this.textEditorElem));
|
||||
}
|
||||
this.deactivate();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -137,9 +163,56 @@ var TextEditorProvider = (function() {
|
|||
|
||||
setFont: function(font) {
|
||||
this.font = font;
|
||||
this.setStyle("font-style", font.style);
|
||||
this.setStyle("font-size", font.size + "px");
|
||||
this.setStyle("font-face", font.face);
|
||||
this._setStyle("font", font.css);
|
||||
},
|
||||
|
||||
setSize: function(width, height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this._setStyle("width", width + "px");
|
||||
this._setStyle("height", height + "px");
|
||||
},
|
||||
|
||||
getWidth: function() {
|
||||
return this.width;
|
||||
},
|
||||
|
||||
getHeight: function() {
|
||||
return this.height;
|
||||
},
|
||||
|
||||
setPosition: function(left, top) {
|
||||
this.left = left;
|
||||
this.top = top;
|
||||
var t = MIDP.Context2D.canvas.offsetTop + top;
|
||||
this._setStyle("left", left + "px");
|
||||
this._setStyle("top", t + "px");
|
||||
},
|
||||
|
||||
getLeft: function() {
|
||||
return this.left;
|
||||
},
|
||||
|
||||
getTop: function() {
|
||||
return this.top;
|
||||
},
|
||||
|
||||
setBackgroundColor: function(color) {
|
||||
this.backgroundColor = color;
|
||||
this._setStyle("backgroundColor", util.abgrIntToCSS(color));
|
||||
},
|
||||
|
||||
getBackgroundColor: function() {
|
||||
return this.backgroundColor;
|
||||
},
|
||||
|
||||
setForegroundColor: function(color) {
|
||||
this.foregroundColor = color;
|
||||
this._setStyle("color", util.abgrIntToCSS(color));
|
||||
},
|
||||
|
||||
getForegroundColor: function() {
|
||||
return this.foregroundColor;
|
||||
},
|
||||
|
||||
oninput: function(callback) {
|
||||
|
@ -148,65 +221,71 @@ var TextEditorProvider = (function() {
|
|||
}
|
||||
|
||||
function TextAreaEditor() {
|
||||
this.content = "";
|
||||
this.textEditorElem = document.createElement('div');
|
||||
this.textEditorElem.contentEditable = true;
|
||||
this.setStyle('word-break', 'break-all');
|
||||
this.setStyle('word-wrap', 'break-word');
|
||||
this.setStyle('overflow', 'auto');
|
||||
this.setStyle('white-space', 'pre-wrap');
|
||||
this.setStyle('-moz-appearance', 'textfield-multiline');
|
||||
|
||||
this.textEditorElem.onkeydown = function(e) {
|
||||
if (this.getSize() >= this.getAttribute("maxlength")) {
|
||||
// http://stackoverflow.com/questions/12467240/determine-if-javascript-e-keycode-is-a-printable-non-control-character
|
||||
if ((e.keyCode >= 48 && e.keyCode <= 57) || // number keys
|
||||
e.keyCode === 32 || e.keyCode === 13 || // spacebar & return key(s) (if you want to allow carriage returns)
|
||||
(e.keyCode >= 65 && e.keyCode <= 90) || // letter keys
|
||||
(e.keyCode >= 96 && e.keyCode <= 111) || // numpad keys
|
||||
(e.keyCode >= 186 && e.keyCode <= 192) || // ;=,-./` (in order)
|
||||
(e.keyCode >= 219 && e.keyCode <= 222)) { // [\]' (in order)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
this.textEditorElem.oninput = function(e) {
|
||||
if (e.isComposing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the current selection.
|
||||
var range = this.getSelectionRange();
|
||||
|
||||
// Remove the last <br> tag if any.
|
||||
var content = this.textEditorElem.innerHTML;
|
||||
var lastBr = content.lastIndexOf("<br>");
|
||||
if (lastBr !== -1) {
|
||||
content = content.substring(0, lastBr);
|
||||
}
|
||||
|
||||
// Replace <br> by \n
|
||||
content = content.replace("<br>", "\n", "g");
|
||||
|
||||
// Convert the emoji images back to characters.
|
||||
// The original character is stored in the alt attribute of its
|
||||
// img tag with the format of <img ... alt='X' ..>.
|
||||
content = content.replace(/<img[^>]*alt="(\S*)"[^>]*>/g, '$1');
|
||||
|
||||
this.setContent(content);
|
||||
|
||||
// Restore the current selection after updating emoji images.
|
||||
this.setSelectionRange(range[0].index, range[1].index);
|
||||
|
||||
// Notify TextEditor listeners.
|
||||
if (this.oninputCallback) {
|
||||
this.oninputCallback();
|
||||
}
|
||||
}.bind(this);
|
||||
this.textEditorElem = eTextArea;
|
||||
}
|
||||
|
||||
TextAreaEditor.prototype = extendsObject({
|
||||
html: '',
|
||||
|
||||
activate: function() {
|
||||
this.textEditorElem.onkeydown = function(e) {
|
||||
if (this.getContentSize() >= this.getAttribute("maxlength")) {
|
||||
// http://stackoverflow.com/questions/12467240/determine-if-javascript-e-keycode-is-a-printable-non-control-character
|
||||
if ((e.keyCode >= 48 && e.keyCode <= 57) || // number keys
|
||||
e.keyCode === 32 || e.keyCode === 13 || // spacebar & return key(s) (if you want to allow carriage returns)
|
||||
(e.keyCode >= 65 && e.keyCode <= 90) || // letter keys
|
||||
(e.keyCode >= 96 && e.keyCode <= 111) || // numpad keys
|
||||
(e.keyCode >= 186 && e.keyCode <= 192) || // ;=,-./` (in order)
|
||||
(e.keyCode >= 219 && e.keyCode <= 222)) { // [\]' (in order)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}.bind(this);
|
||||
|
||||
this.textEditorElem.oninput = function(e) {
|
||||
if (e.isComposing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the current selection.
|
||||
var range = this.getSelectionRange();
|
||||
|
||||
// Remove the last <br> tag if any.
|
||||
var html = this.textEditorElem.innerHTML;
|
||||
var lastBr = html.lastIndexOf("<br>");
|
||||
if (lastBr !== -1) {
|
||||
html = html.substring(0, lastBr);
|
||||
}
|
||||
|
||||
// Replace <br> by \n so that textContent attribute doesn't
|
||||
// strip new lines.
|
||||
html = html.replace("<br>", "\n", "g");
|
||||
|
||||
// Convert the emoji images back to characters.
|
||||
// The original character is stored in the alt attribute of its
|
||||
// object tag with the format of <object ... name='X' ..>.
|
||||
html = html.replace(/<object[^>]*name="(\S*)"[^>]*><\/object>/g, '$1');
|
||||
|
||||
this.textEditorElem.innerHTML = html;
|
||||
|
||||
this.setContent(this.textEditorElem.textContent);
|
||||
|
||||
// Restore the current selection after updating emoji images.
|
||||
this.setSelectionRange(range[0], range[1]);
|
||||
|
||||
// Notify TextEditor listeners.
|
||||
if (this.oninputCallback) {
|
||||
this.oninputCallback();
|
||||
}
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
this.textEditorElem.onkeydown = null;
|
||||
this.textEditorElem.oninput = null;
|
||||
},
|
||||
|
||||
getContent: function() {
|
||||
return this.content;
|
||||
},
|
||||
|
@ -217,7 +296,11 @@ var TextEditorProvider = (function() {
|
|||
|
||||
this.content = content;
|
||||
|
||||
if (!this.textEditorElem) {
|
||||
// Escape the content to avoid malicious injection via innerHTML.
|
||||
this.textEditorElem.textContent = content;
|
||||
var html = this.textEditorElem.innerHTML;
|
||||
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -232,15 +315,17 @@ var TextEditorProvider = (function() {
|
|||
style += 'background:url(' + emojiData.img.src + ') -' + (emojiData.x * scale) + 'px 0px no-repeat;';
|
||||
style += 'background-size:' + (emojiData.img.naturalWidth * scale) + 'px ' + this.font.size + 'px;';
|
||||
|
||||
return '<img src="style/blank.gif" style="' + style + '" alt="' + str + '">';
|
||||
// We use <object> instead of <img> to not allow image resizing.
|
||||
return '<object style="' + style + '" name="' + str + '"></object>';
|
||||
}.bind(this);
|
||||
|
||||
// Replace "\n" by <br>
|
||||
var html = content.replace("\n", "<br>", "g");
|
||||
html = html.replace("\n", "<br>", "g");
|
||||
|
||||
html = html.replace(emoji.regEx, toImg) + "<br>";
|
||||
|
||||
this.textEditorElem.innerHTML = html;
|
||||
this.html = html;
|
||||
},
|
||||
|
||||
_getNodeTextLength: function(node) {
|
||||
|
@ -251,19 +336,19 @@ var TextEditorProvider = (function() {
|
|||
return node.nextSibling ? 1 : 0;
|
||||
} else {
|
||||
// It should be an HTMLImageElement of a emoji.
|
||||
return util.toCodePointArray(node.alt).length;
|
||||
return util.toCodePointArray(node.name).length;
|
||||
}
|
||||
},
|
||||
|
||||
_getSelectionOffset: function(node, offset) {
|
||||
if (!this.textEditorElem) {
|
||||
return { index: 0, node: null };
|
||||
if (!this.visible) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (node !== this.textEditorElem &&
|
||||
node.parentNode !== this.textEditorElem) {
|
||||
console.error("_getSelectionOffset called while the editor is unfocused");
|
||||
return { index: 0, node: null };
|
||||
return 0;
|
||||
}
|
||||
|
||||
var selectedNode = null;
|
||||
|
@ -286,7 +371,7 @@ var TextEditorProvider = (function() {
|
|||
selectedNode = children[offset - 1];
|
||||
}
|
||||
|
||||
return { index: count, node: selectedNode };
|
||||
return count;
|
||||
},
|
||||
|
||||
getSelectionEnd: function() {
|
||||
|
@ -303,7 +388,7 @@ var TextEditorProvider = (function() {
|
|||
var start = this.getSelectionStart();
|
||||
var end = this.getSelectionEnd();
|
||||
|
||||
if (start.index > end.index) {
|
||||
if (start > end) {
|
||||
return [ end, start ];
|
||||
}
|
||||
|
||||
|
@ -311,42 +396,42 @@ var TextEditorProvider = (function() {
|
|||
},
|
||||
|
||||
setSelectionRange: function(from, to) {
|
||||
if (!this.textEditorElem) {
|
||||
this.selectionRange = [from, to];
|
||||
} else {
|
||||
if (from != to) {
|
||||
console.error("setSelectionRange not supported when from != to");
|
||||
}
|
||||
this.selectionRange = [from, to];
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
if (from != to) {
|
||||
console.error("setSelectionRange not supported when from != to");
|
||||
}
|
||||
|
||||
var children = this.textEditorElem.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var length = this._getNodeTextLength(cur);
|
||||
var children = this.textEditorElem.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var length = this._getNodeTextLength(cur);
|
||||
|
||||
if (length >= from) {
|
||||
var selection = window.getSelection();
|
||||
var range;
|
||||
if (selection.rangeCount === 0) {
|
||||
// XXX: This makes it so chrome does not break here, but
|
||||
// text boxes still do not behave correctly in chrome.
|
||||
range = document.createRange();
|
||||
selection.addRange(range);
|
||||
} else {
|
||||
range = selection.getRangeAt(0);
|
||||
}
|
||||
if (cur.textContent) {
|
||||
range.setStart(cur, from);
|
||||
} else if (from === 0) {
|
||||
range.setStartBefore(cur);
|
||||
} else {
|
||||
range.setStartAfter(cur);
|
||||
}
|
||||
range.collapse(true);
|
||||
break;
|
||||
if (length >= from) {
|
||||
var selection = window.getSelection();
|
||||
var range;
|
||||
if (selection.rangeCount === 0) {
|
||||
// XXX: This makes it so chrome does not break here, but
|
||||
// text boxes still do not behave correctly in chrome.
|
||||
range = document.createRange();
|
||||
selection.addRange(range);
|
||||
} else {
|
||||
range = selection.getRangeAt(0);
|
||||
}
|
||||
|
||||
from -= length;
|
||||
if (cur.textContent) {
|
||||
range.setStart(cur, from);
|
||||
} else if (from === 0) {
|
||||
range.setStartBefore(cur);
|
||||
} else {
|
||||
range.setStartAfter(cur);
|
||||
}
|
||||
range.collapse(true);
|
||||
break;
|
||||
}
|
||||
|
||||
from -= length;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -355,9 +440,9 @@ var TextEditorProvider = (function() {
|
|||
},
|
||||
|
||||
/*
|
||||
* The TextEditor::size() method returns the length of the content in codepoints
|
||||
* The TextEditor::getContentSize() method returns the length of the content in codepoints
|
||||
*/
|
||||
getSize: function() {
|
||||
getContentSize: function() {
|
||||
return util.toCodePointArray(this.content).length;
|
||||
},
|
||||
|
||||
|
@ -366,77 +451,88 @@ var TextEditorProvider = (function() {
|
|||
* with the same style as the TextEditor element.
|
||||
*/
|
||||
getContentHeight: function() {
|
||||
var div = document.createElement("div");
|
||||
div.style.setProperty("width", this.getStyle("width"));
|
||||
div.style.setProperty("overflow", "none");
|
||||
div.style.setProperty("word-break", "break-all");
|
||||
div.style.setProperty("word-wrap", "break-word");
|
||||
div.style.setProperty("white-space", "pre-wrap");
|
||||
div.style.setProperty("position", "absolute");
|
||||
div.style.setProperty("left", "0px");
|
||||
div.style.setProperty("top", "0px");
|
||||
div.style.setProperty("visibility", "hidden");
|
||||
div.style.setProperty("display", "block");
|
||||
div.style.setProperty("font-style", this.getStyle("font-style"));
|
||||
div.style.setProperty("font-size", this.getStyle("font-size"));
|
||||
div.style.setProperty("font-face", this.getStyle("font-face"));
|
||||
div.innerHTML = this.textEditorElem.innerHTML;
|
||||
document.body.appendChild(div);
|
||||
|
||||
var div = document.getElementById("hidden-textarea-editor");
|
||||
div.style.setProperty("width", this.getWidth() + "px");
|
||||
div.style.setProperty("font", this.font.css);
|
||||
div.innerHTML = this.html;
|
||||
var height = div.offsetHeight;
|
||||
|
||||
document.body.removeChild(div);
|
||||
div.innerHTML = "";
|
||||
|
||||
return height;
|
||||
},
|
||||
}, CommonEditorPrototype);
|
||||
|
||||
function PasswordEditor() {
|
||||
this.textEditorElem = document.createElement('input');
|
||||
this.textEditorElem.type = 'password';
|
||||
|
||||
this.textEditorElem.oninput = function() {
|
||||
this.content = this.textEditorElem.value;
|
||||
if (this.oninputCallback) {
|
||||
this.oninputCallback();
|
||||
}
|
||||
}.bind(this);
|
||||
this.textEditorElem = ePassword;
|
||||
}
|
||||
|
||||
PasswordEditor.prototype = extendsObject({
|
||||
activate: function() {
|
||||
this.textEditorElem.oninput = function() {
|
||||
this.content = ePassword.value;
|
||||
if (this.oninputCallback) {
|
||||
this.oninputCallback();
|
||||
}
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
this.textEditorElem.oninput = null;
|
||||
},
|
||||
|
||||
getContent: function() {
|
||||
return this.content || '';
|
||||
return this.content;
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
this.content = content;
|
||||
|
||||
if (this.textEditorElem) {
|
||||
if (this.visible) {
|
||||
this.textEditorElem.value = content;
|
||||
}
|
||||
},
|
||||
|
||||
getSelectionStart: function() {
|
||||
if (this.textEditorElem) {
|
||||
return { index: this.textEditorElem.selectionStart, node: this.textEditorElem };
|
||||
if (this.visible) {
|
||||
return this.textEditorElem.selectionStart;
|
||||
}
|
||||
|
||||
return { index: 0, node: null };
|
||||
return 0;
|
||||
},
|
||||
|
||||
getSelectionEnd: function() {
|
||||
if (this.visible) {
|
||||
return this.textEditorElem.selectionEnd;
|
||||
}
|
||||
|
||||
return 0;
|
||||
},
|
||||
|
||||
getSelectionRange: function() {
|
||||
var start = this.getSelectionStart();
|
||||
var end = this.getSelectionEnd();
|
||||
|
||||
if (start > end) {
|
||||
return [ end, start ];
|
||||
}
|
||||
|
||||
return [ start, end ];
|
||||
},
|
||||
|
||||
setSelectionRange: function(from, to) {
|
||||
if (!this.textEditorElem) {
|
||||
this.selectionRange = [from, to];
|
||||
} else {
|
||||
this.textEditorElem.setSelectionRange(from, to);
|
||||
this.selectionRange = [from, to];
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
this.textEditorElem.setSelectionRange(from, to);
|
||||
},
|
||||
|
||||
getSlice: function(from, to) {
|
||||
return this.content.slice(from, to);
|
||||
},
|
||||
|
||||
getSize: function() {
|
||||
getContentSize: function() {
|
||||
return this.content.length;
|
||||
},
|
||||
|
||||
|
@ -446,14 +542,8 @@ var TextEditorProvider = (function() {
|
|||
},
|
||||
}, CommonEditorPrototype);
|
||||
|
||||
function TextEditorWrapper(constraints) {
|
||||
this.textEditor = null;
|
||||
this.setConstraints(constraints);
|
||||
this.textEditor.decorateTextEditorElem();
|
||||
}
|
||||
|
||||
TextEditorWrapper.prototype = {
|
||||
setConstraints: function(constraints) {
|
||||
return {
|
||||
getEditor: function(constraints, oldEditor, editorId) {
|
||||
var TYPE_TEXTAREA = 'textarea';
|
||||
var TYPE_PASSWORD = 'password';
|
||||
|
||||
|
@ -461,14 +551,21 @@ var TextEditorProvider = (function() {
|
|||
var CONSTRAINT_ANY = 0;
|
||||
var CONSTRAINT_PASSWORD = 0x10000;
|
||||
|
||||
function _createEditor(type) {
|
||||
function _createEditor(type, constraints, editorId) {
|
||||
var editor;
|
||||
switch(type) {
|
||||
case TYPE_PASSWORD:
|
||||
return new PasswordEditor();
|
||||
case TYPE_TEXTAREA:
|
||||
editor = new PasswordEditor();
|
||||
break;
|
||||
case TYPE_TEXTAREA: // fall through
|
||||
default:
|
||||
return new TextAreaEditor();
|
||||
editor = new TextAreaEditor();
|
||||
break;
|
||||
}
|
||||
editor.type = type;
|
||||
editor.constraints = constraints;
|
||||
editor.id = editorId;
|
||||
return editor;
|
||||
}
|
||||
|
||||
var type = TYPE_TEXTAREA;
|
||||
|
@ -489,129 +586,33 @@ var TextEditorProvider = (function() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!this.textEditor) {
|
||||
this.textEditor = _createEditor(type);
|
||||
this.type = type;
|
||||
this.constraints = constraints;
|
||||
return;
|
||||
var newEditor;
|
||||
|
||||
if (!oldEditor) {
|
||||
newEditor = _createEditor(type, constraints, editorId);
|
||||
return newEditor;
|
||||
}
|
||||
|
||||
// If the type is changed, we need to copy all the attributes/styles.
|
||||
if (type != this.type) {
|
||||
var newEditor = _createEditor(type);
|
||||
if (this.textEditor.styles) {
|
||||
for (var styleKey in this.textEditor.styles) {
|
||||
newEditor.setStyle(styleKey, this.textEditor.styles[styleKey]);
|
||||
}
|
||||
}
|
||||
if (this.textEditor.attributes) {
|
||||
for (var attrName in this.textEditor.attributes) {
|
||||
newEditor.setAttribute(attrName, this.textEditor.attributes[attrName]);
|
||||
}
|
||||
}
|
||||
if (this.textEditor.focused) {
|
||||
newEditor.focus();
|
||||
}
|
||||
newEditor.setVisible(this.textEditor.getVisible());
|
||||
if (this.textEditor.oninputCallback) {
|
||||
newEditor.oninput(this.textEditor.oninputCallback);
|
||||
}
|
||||
if (this.textEditor.parentNode) {
|
||||
newEditor.setParent(this.textEditor.parentNode);
|
||||
}
|
||||
newEditor.setContent(this.textEditor.getContent());
|
||||
|
||||
newEditor.font = this.textEditor.font;
|
||||
|
||||
this.textEditor.destroy();
|
||||
this.textEditor = newEditor;
|
||||
if (type === oldEditor.type) {
|
||||
return oldEditor;
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.constraints = constraints;
|
||||
},
|
||||
// The type is changed and we need to copy all the attributes.
|
||||
var newEditor = _createEditor(type, constraints, editorId);
|
||||
["attributes",
|
||||
"width", "height",
|
||||
"left", "top",
|
||||
"backgroundColor", "foregroundColor",
|
||||
"attached",
|
||||
"content",
|
||||
"font",
|
||||
"oninputCallback"].forEach(function(attr) {
|
||||
newEditor[attr] = oldEditor[attr];
|
||||
});
|
||||
|
||||
getConstraints: function() {
|
||||
return this.constraints || 0;
|
||||
},
|
||||
|
||||
setParent: function(parentNode) {
|
||||
this.textEditor.setParent(parentNode);
|
||||
},
|
||||
|
||||
getParent: function() {
|
||||
return this.textEditor.parentNode;
|
||||
},
|
||||
|
||||
setStyle: function(styleKey, styleValue) {
|
||||
this.textEditor.setStyle(styleKey, styleValue);
|
||||
},
|
||||
|
||||
getStyle: function(styleKey) {
|
||||
return this.textEditor.getStyle(styleKey);
|
||||
},
|
||||
|
||||
getContent: function() {
|
||||
return this.textEditor.getContent()
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
this.textEditor.setContent(content);
|
||||
},
|
||||
|
||||
focus: function() {
|
||||
this.textEditor.focus();
|
||||
},
|
||||
|
||||
blur: function() {
|
||||
this.textEditor.blur();
|
||||
},
|
||||
|
||||
setVisible: function(aVisible) {
|
||||
this.textEditor.setVisible(aVisible);
|
||||
},
|
||||
|
||||
getSelectionStart: function() {
|
||||
return this.textEditor.getSelectionStart();
|
||||
},
|
||||
|
||||
setSelectionRange: function(from, to) {
|
||||
this.textEditor.setSelectionRange(from, to);
|
||||
},
|
||||
|
||||
setAttribute: function(attrName, value) {
|
||||
this.textEditor.setAttribute(attrName, value);
|
||||
},
|
||||
|
||||
getAttribute: function(attrName) {
|
||||
return this.textEditor.getAttribute(attrName);
|
||||
},
|
||||
|
||||
getSize: function() {
|
||||
return this.textEditor.getSize();
|
||||
},
|
||||
|
||||
getSlice: function(from, to) {
|
||||
return this.textEditor.getSlice(from, to);
|
||||
},
|
||||
|
||||
getContentHeight: function() {
|
||||
return this.textEditor.getContentHeight();
|
||||
},
|
||||
|
||||
setFont: function(font) {
|
||||
this.textEditor.setFont(font);
|
||||
},
|
||||
|
||||
oninput: function(callback) {
|
||||
this.textEditor.oninput(callback);
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
createEditor: function(constraints) {
|
||||
return new TextEditorWrapper(constraints);
|
||||
// Call setVisible to update display.
|
||||
newEditor.setVisible(oldEditor.visible);
|
||||
return newEditor;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
|
|
37
native.js
37
native.js
|
@ -69,6 +69,12 @@ Native["java/lang/System.arraycopy.(Ljava/lang/Object;ILjava/lang/Object;II)V"]
|
|||
}
|
||||
};
|
||||
|
||||
var stubProperties = {
|
||||
"com.nokia.multisim.slots": 1,
|
||||
"com.nokia.mid.imsi": "000000000000000",
|
||||
"com.nokia.mid.imei": "",
|
||||
};
|
||||
|
||||
Native["java/lang/System.getProperty0.(Ljava/lang/String;)Ljava/lang/String;"] = function(key) {
|
||||
key = util.fromJavaString(key);
|
||||
var value;
|
||||
|
@ -178,22 +184,10 @@ Native["java/lang/System.getProperty0.(Ljava/lang/String;)Ljava/lang/String;"] =
|
|||
case "com.nokia.keyboard.type":
|
||||
value = "None";
|
||||
break;
|
||||
case "com.nokia.multisim.slots":
|
||||
console.warn("Property 'com.nokia.multisim.slots' is a stub");
|
||||
value = "1";
|
||||
break;
|
||||
case "com.nokia.multisim.imsi.sim2":
|
||||
console.warn("Property 'com.nokia.multisim.imsi.sim2' is a stub");
|
||||
value = null;
|
||||
break;
|
||||
case "com.nokia.mid.batterylevel":
|
||||
// http://developer.nokia.com/community/wiki/Checking_battery_level_in_Java_ME
|
||||
value = Math.floor(navigator.battery.level * 100).toString();
|
||||
break;
|
||||
case "com.nokia.mid.imsi":
|
||||
console.warn("Property 'com.nokia.mid.imsi' is a stub");
|
||||
value = "000000000000000";
|
||||
break;
|
||||
case "com.nokia.mid.ui.version":
|
||||
value = "1.7";
|
||||
break;
|
||||
|
@ -213,10 +207,6 @@ Native["java/lang/System.getProperty0.(Ljava/lang/String;)Ljava/lang/String;"] =
|
|||
value = null;
|
||||
}
|
||||
break;
|
||||
case "com.nokia.mid.imei":
|
||||
console.warn("Property 'com.nokia.mid.imei' is a stub");
|
||||
value = "";
|
||||
break;
|
||||
case "com.nokia.mid.ui.customfontsize":
|
||||
value = "true";
|
||||
break;
|
||||
|
@ -246,9 +236,11 @@ Native["java/lang/System.getProperty0.(Ljava/lang/String;)Ljava/lang/String;"] =
|
|||
default:
|
||||
if (MIDP.additionalProperties[key]) {
|
||||
value = MIDP.additionalProperties[key];
|
||||
} else if (typeof stubProperties[key] !== "undefined") {
|
||||
value = stubProperties[key];
|
||||
} else {
|
||||
console.warn("UNKNOWN PROPERTY (java/lang/System): " + key);
|
||||
value = null;
|
||||
stubProperties[key] = value = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -288,13 +280,6 @@ Native["java/lang/Object.getClass.()Ljava/lang/Class;"] = function() {
|
|||
return J2ME.getRuntimeKlass($.ctx.runtime, this.klass).classObject;
|
||||
};
|
||||
|
||||
Native["java/lang/Object.hashCode.()I"] = function() {
|
||||
var hashCode = this.hashCode;
|
||||
while (!hashCode)
|
||||
hashCode = this.hashCode = util.id();
|
||||
return hashCode;
|
||||
};
|
||||
|
||||
Native["java/lang/Object.wait.(J)V"] = function(timeout) {
|
||||
$.ctx.wait(this, timeout.toNumber());
|
||||
};
|
||||
|
@ -805,7 +790,7 @@ Native["com/sun/cldc/i18n/j2me/UTF_8_Reader.readNative.([CII)I"] = function(cbuf
|
|||
};
|
||||
|
||||
Native["java/io/DataInputStream.bytesToUTF.([B)Ljava/lang/String;"] = function(bytearr) {
|
||||
var array = new Uint8Array(bytearr.buffer);
|
||||
var array = new Int8Array(bytearr.buffer);
|
||||
try {
|
||||
return J2ME.newString(util.decodeUtf8Array(array));
|
||||
} catch(e) {
|
||||
|
@ -868,7 +853,7 @@ Native["com/sun/cldc/i18n/j2me/UTF_8_Writer.encodeUTF8.([CII)[B"] = function(cbu
|
|||
var count = 0;
|
||||
|
||||
while (count < len) {
|
||||
var outputByte = new Uint8Array(4); // Never more than 4 encoded bytes
|
||||
var outputByte = new Int8Array(4); // Never more than 4 encoded bytes
|
||||
inputChar = 0xffff & cbuf[off + count];
|
||||
if (0 != pendingSurrogate) {
|
||||
if (0xdc00 <= inputChar && inputChar <= 0xdfff) {
|
||||
|
|
|
@ -30,7 +30,6 @@ declare var throwYield;
|
|||
module J2ME {
|
||||
declare var Native, Override;
|
||||
declare var VM;
|
||||
declare var Instrument;
|
||||
declare var CompiledMethodCache;
|
||||
|
||||
/**
|
||||
|
@ -827,8 +826,12 @@ module J2ME {
|
|||
}
|
||||
|
||||
export class Lock {
|
||||
ready: Context [];
|
||||
waiting: Context [];
|
||||
|
||||
constructor(public thread: java.lang.Thread, public level: number) {
|
||||
// ...
|
||||
this.ready = [];
|
||||
this.waiting = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -311,7 +311,7 @@ Override["java/lang/String.valueOf.(J)Ljava/lang/String;"] = function(n) {
|
|||
// Additionally, their tests check for coverage of nuanced things like
|
||||
// positive zero vs. negative zero, which we don't currently support.
|
||||
|
||||
var internedStrings = new Map();
|
||||
var internedStrings = J2ME.internedStrings;
|
||||
|
||||
Native["java/lang/String.intern.()Ljava/lang/String;"] = function() {
|
||||
var string = util.fromJavaString(this);
|
||||
|
|
Двоичные данные
style/blank.gif
Двоичные данные
style/blank.gif
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 49 B |
|
@ -37,6 +37,7 @@ body {
|
|||
background: url("headers/images/icons/back.png") rgba(249, 124, 23, 0.7) no-repeat scroll center center;
|
||||
border: medium none;
|
||||
border-radius: 20px 0 0 0;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
#back-button:hover {
|
||||
|
@ -167,6 +168,7 @@ form[role="dialog"][data-type="confirm"].lcdui-alert section {
|
|||
}
|
||||
|
||||
.splash-screen {
|
||||
display: none;
|
||||
z-index: 2;
|
||||
background: #2d2d2d;
|
||||
overflow: hidden;
|
||||
|
@ -175,7 +177,6 @@ form[role="dialog"][data-type="confirm"].lcdui-alert section {
|
|||
}
|
||||
|
||||
.autosize .splash-screen {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
@ -193,6 +194,30 @@ form[role="dialog"][data-type="confirm"].lcdui-alert section {
|
|||
left: calc(50% - 17px);
|
||||
}
|
||||
|
||||
#background-screen {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: auto;
|
||||
bottom: auto;
|
||||
background-color: white;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("../img/icon-128.png");
|
||||
}
|
||||
|
||||
.debug-mode #background-screen {
|
||||
width: 240px;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
.autosize #background-screen {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/**
|
||||
* STYLE OVERRIDES FOR DEBUG MODE:
|
||||
*
|
||||
|
@ -319,3 +344,33 @@ form[role="dialog"][data-type="confirm"].lcdui-alert section {
|
|||
border: none;
|
||||
border-bottom: 1px solid #555;
|
||||
}
|
||||
|
||||
/* Styles for text editors */
|
||||
.text-editor {
|
||||
position: absolute;
|
||||
border: none;
|
||||
resize: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.text-editor.show{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.text-editor {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
overflow: auto;
|
||||
white-space: pre-wrap;
|
||||
-moz-appearance: textfield-multiline;
|
||||
display: block;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#hidden-textarea-editor {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ public class RunTests extends MIDlet {
|
|||
}
|
||||
|
||||
public void report() {
|
||||
System.out.println(testName + ": " + pass + " pass, " + fail + " fail, " + unknownPass + " unknown pass");
|
||||
System.out.println(testName + ": " + pass + " pass, " + fail + " fail, " + knownFail + " known fail, " +
|
||||
unknownPass + " unknown pass");
|
||||
}
|
||||
|
||||
public int passed() {
|
||||
|
@ -76,7 +77,7 @@ public class RunTests extends MIDlet {
|
|||
}
|
||||
};
|
||||
|
||||
int pass = 0, fail = 0, knownFail = 0, unknownPass = 0;
|
||||
int classPass = 0, classFail = 0, pass = 0, fail = 0, knownFail = 0, unknownPass = 0;
|
||||
|
||||
void runTest(String name) {
|
||||
name = name.replace('/', '.');
|
||||
|
@ -107,8 +108,25 @@ public class RunTests extends MIDlet {
|
|||
System.err.println(e);
|
||||
harness.fail("Test threw an unexpected exception");
|
||||
}
|
||||
if (harness.failed() > 0)
|
||||
harness.report();
|
||||
harness.report();
|
||||
boolean classPassed = true;
|
||||
if (harness.passed() != t.getExpectedPass()) {
|
||||
classPassed = false;
|
||||
System.err.println(name + ": test expected " + t.getExpectedPass() + " passes, got " + harness.passed());
|
||||
}
|
||||
if (harness.failed() != t.getExpectedFail()) {
|
||||
classPassed = false;
|
||||
System.err.println(name + ": test expected " + t.getExpectedFail() + " failures, got " + harness.failed());
|
||||
}
|
||||
if (harness.knownFailed() != t.getExpectedKnownFail()) {
|
||||
classPassed = false;
|
||||
System.err.println(name + ": test expected " + t.getExpectedKnownFail() + " known failures, got " + harness.knownFailed());
|
||||
}
|
||||
if (classPassed) {
|
||||
classPass++;
|
||||
} else {
|
||||
classFail++;
|
||||
}
|
||||
pass += harness.passed();
|
||||
fail += harness.failed();
|
||||
knownFail += harness.knownFailed();
|
||||
|
@ -144,8 +162,9 @@ public class RunTests extends MIDlet {
|
|||
runTest(name);
|
||||
}
|
||||
}
|
||||
System.out.println("DONE: " + pass + " pass, " + fail + " fail, " + knownFail + " known fail, " +
|
||||
unknownPass + " unknown pass, " + (JVM.monotonicTimeMillis() - then) + "ms");
|
||||
System.out.println("TOTALS: " + pass + " pass, " + fail + " fail, " + knownFail + " known fail, " +
|
||||
unknownPass + " unknown pass");
|
||||
System.out.println("DONE: " + classPass + " class pass, " + classFail + " class fail, " + (JVM.monotonicTimeMillis() - then) + "ms");
|
||||
}
|
||||
|
||||
public void pauseApp() {
|
||||
|
|
|
@ -69,13 +69,6 @@ var gfxTests = [
|
|||
{ name: "gfx/DrawStringWithCopyrightAndRegisteredSymbols", maxDifferent: 244 },
|
||||
];
|
||||
|
||||
var expectedUnitTestResults = [
|
||||
{ name: "pass", number: 71551 },
|
||||
{ name: "fail", number: 0 },
|
||||
{ name: "known fail", number: 214 },
|
||||
{ name: "unknown pass", number: 0 }
|
||||
];
|
||||
|
||||
/**
|
||||
* Add a step that syncs the virtual filesystem to the persistent datastore,
|
||||
* to ensure all changes are synced before we move to the next step.
|
||||
|
@ -123,23 +116,18 @@ casper.test.begin("unit tests", 16 + gfxTests.length, function(test) {
|
|||
function basicUnitTests() {
|
||||
casper.waitForText("DONE", function() {
|
||||
var content = this.getPageContent();
|
||||
var regex = /DONE: (\d+) pass, (\d+) fail, (\d+) known fail, (\d+) unknown pass/;
|
||||
var regex = /DONE: (\d+) class pass, (\d+) class fail/;
|
||||
var match = content.match(regex);
|
||||
if (!match || !match.length || match.length < 5) {
|
||||
if (!match || !match.length || match.length < 3) {
|
||||
this.echo("data:image/png;base64," + this.captureBase64('png'));
|
||||
test.fail('failed to parse status line of main unit tests');
|
||||
} else {
|
||||
var msg = "";
|
||||
for (var i = 0; i < expectedUnitTestResults.length; i++) {
|
||||
if (match[i+1] != expectedUnitTestResults[i].number) {
|
||||
msg += "\n\tExpected " + expectedUnitTestResults[i].number + " " + expectedUnitTestResults[i].name + ". Got " + match[i+1];
|
||||
}
|
||||
}
|
||||
if (!msg) {
|
||||
var failed = match[2];
|
||||
if (failed === "0") {
|
||||
test.pass('main unit tests');
|
||||
} else {
|
||||
this.echo("data:image/png;base64," + this.captureBase64('png'));
|
||||
test.fail(msg);
|
||||
test.fail(failed + " unit test(s) failed");
|
||||
}
|
||||
}
|
||||
syncFS();
|
||||
|
|
|
@ -11,6 +11,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestFileConnection implements Testlet {
|
||||
public int getExpectedPass() { return 160; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
String dirPath;
|
||||
FileConnection dir;
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ import javax.microedition.io.file.*;
|
|||
import javax.microedition.io.*;
|
||||
|
||||
public class TestLauncher implements Testlet {
|
||||
public int getExpectedPass() { return 3; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
native boolean checkImageModalDialog();
|
||||
|
||||
public void test(TestHarness th) {
|
||||
|
|
|
@ -6,6 +6,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestDataEncodeDecode implements Testlet {
|
||||
public int getExpectedPass() { return 92; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
void testString(TestHarness th) throws IOException {
|
||||
DataEncoder encoder = new DataEncoder("whatever");
|
||||
encoder.putStart(DataType.STRUCT, "event");
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestDeviceControl implements Testlet {
|
||||
public int getExpectedPass() { return 4; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public void test(TestHarness th) {
|
||||
try {
|
||||
DeviceControl.stopVibra();
|
||||
|
|
|
@ -5,6 +5,9 @@ import gnu.testlet.Testlet;
|
|||
import gnu.testlet.TestHarness;
|
||||
|
||||
public class TestDirectGraphics implements Testlet {
|
||||
public int getExpectedPass() { return 6; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 1; }
|
||||
public void test(TestHarness th) {
|
||||
int[] pixels = new int[1];
|
||||
Image image = DirectUtils.createImage(1, 1, 0x0000FF00);
|
||||
|
|
|
@ -11,12 +11,17 @@ import javax.microedition.lcdui.Graphics;
|
|||
import javax.microedition.lcdui.TextField;
|
||||
|
||||
public class TestTextEditor extends Canvas implements Testlet {
|
||||
public int getExpectedPass() { return 146; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public void testConstraints(TestHarness th, int constraints, int tolerance) {
|
||||
TextEditor textEditor = new TextEditor("Hello, world!", 20, 0, 100, 24);
|
||||
String text = "</div>Hello, world!";
|
||||
TextEditor textEditor = new TextEditor(text, 20, 0, 100, 24);
|
||||
textEditor.setVisible(true);
|
||||
|
||||
th.check(textEditor.getContent(), "Hello, world!");
|
||||
th.check(textEditor.getContent(), text);
|
||||
th.check(textEditor.getMaxSize(), 20);
|
||||
th.check(textEditor.getCaretPosition(), 13);
|
||||
th.check(textEditor.getCaretPosition(), text.length());
|
||||
|
||||
textEditor.setConstraints(constraints);
|
||||
th.check(textEditor.getConstraints(), constraints);
|
||||
|
@ -46,11 +51,11 @@ public class TestTextEditor extends Canvas implements Testlet {
|
|||
th.check(textEditor.getWidth(), 120);
|
||||
th.check(textEditor.getHeight(), 28);
|
||||
|
||||
th.check(textEditor.isVisible(), false);
|
||||
textEditor.setVisible(true);
|
||||
th.check(textEditor.isVisible(), true);
|
||||
textEditor.setVisible(false);
|
||||
th.check(textEditor.isVisible(), false);
|
||||
textEditor.setVisible(true);
|
||||
th.check(textEditor.isVisible(), true);
|
||||
|
||||
textEditor.setParent(this);
|
||||
th.check(textEditor.getParent(), this);
|
||||
|
@ -125,6 +130,8 @@ public class TestTextEditor extends Canvas implements Testlet {
|
|||
textEditor.setFont(font);
|
||||
th.check(textEditor.getFont(), font);
|
||||
|
||||
textEditor.setVisible(false);
|
||||
|
||||
textEditor.setParent(null);
|
||||
}
|
||||
|
||||
|
@ -136,7 +143,6 @@ public class TestTextEditor extends Canvas implements Testlet {
|
|||
textEditor.setBackgroundColor(0x00FFFFFF);
|
||||
textEditor.setForegroundColor(0xFF000000);
|
||||
textEditor.setVisible(true);
|
||||
textEditor.setFocus(true);
|
||||
textEditor.setPosition(0, 0);
|
||||
|
||||
th.check(textEditor.getCaretPosition(), 13);
|
||||
|
@ -250,6 +256,8 @@ public class TestTextEditor extends Canvas implements Testlet {
|
|||
textEditor.setMaxSize(2);
|
||||
th.check(textEditor.size(), 2);
|
||||
th.check(textEditor.getCaretPosition(), 2);
|
||||
|
||||
textEditor.setVisible(false);
|
||||
}
|
||||
|
||||
public void test(TestHarness th) {
|
||||
|
|
|
@ -46,6 +46,9 @@ class TestKeyboardVisibilityListener implements com.nokia.mid.ui.KeyboardVisibil
|
|||
}
|
||||
|
||||
public class TestVirtualKeyboard extends Canvas implements Testlet {
|
||||
public int getExpectedPass() { return 9; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public native static void hideKeyboard();
|
||||
public native static void showKeyboard();
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestFrameAnimator implements Testlet, FrameAnimatorListener {
|
||||
public int getExpectedPass() { return 13; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public void test(TestHarness th) {
|
||||
FrameAnimator animator = new FrameAnimator();
|
||||
th.check(animator.isRegistered(), false);
|
||||
|
|
|
@ -32,6 +32,9 @@ import gnu.testlet.Testlet;
|
|||
import java.io.*;
|
||||
|
||||
public class TestUtfReaders implements Testlet {
|
||||
public int getExpectedPass() { return 63; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 3; }
|
||||
TestHarness th;
|
||||
|
||||
public String teststr1 = "你好世界";
|
||||
|
|
|
@ -6,6 +6,9 @@ import gnu.testlet.Testlet;
|
|||
import java.io.*;
|
||||
|
||||
public class TestResourceInputStream implements Testlet {
|
||||
public int getExpectedPass() { return 4; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
TestHarness th;
|
||||
|
||||
private String readLine(InputStreamReader reader) throws IOException {
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestAES implements Testlet {
|
||||
public int getExpectedPass() { return 20; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public static byte[] hexToBytes(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestARC4 implements Testlet {
|
||||
public int getExpectedPass() { return 31; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public static byte[] hexToBytes(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestDES implements Testlet {
|
||||
public int getExpectedPass() { return 20; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public static byte[] hexToBytes(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestMD5 implements Testlet {
|
||||
public int getExpectedPass() { return 13; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public static byte[] hexToBytes(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestRSA implements Testlet {
|
||||
public int getExpectedPass() { return 16; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public static byte[] hexToBytes(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
|
|
|
@ -4,6 +4,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestSHA implements Testlet {
|
||||
public int getExpectedPass() { return 13; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public static byte[] hexToBytes(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
|
|
|
@ -33,6 +33,9 @@ import gnu.testlet.Testlet;
|
|||
* Unit tests for the EventQueue class.
|
||||
*/
|
||||
public class TestEventQueue implements Testlet {
|
||||
public int getExpectedPass() { return 47; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
TestHarness th;
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,6 +33,9 @@ import gnu.testlet.Testlet;
|
|||
* Unit tests for the NativeEventPool class.
|
||||
*/
|
||||
public class TestNativeEventPool implements Testlet {
|
||||
public int getExpectedPass() { return 25; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
TestHarness th;
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestHttpUrl implements Testlet {
|
||||
public int getExpectedPass() { return 110; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 5; }
|
||||
/**
|
||||
* Runs all the tests.
|
||||
*/
|
||||
|
|
|
@ -30,6 +30,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestUrl implements Testlet {
|
||||
public int getExpectedPass() { return 28; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
TestHarness th;
|
||||
|
||||
private void testUrl(String url, boolean isCorrect) {
|
||||
|
|
|
@ -6,6 +6,9 @@ import java.io.*;
|
|||
import javax.microedition.io.*;
|
||||
|
||||
public class TestHttpConnection implements Testlet {
|
||||
public int getExpectedPass() { return 0; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 2; }
|
||||
public void test(TestHarness th) {
|
||||
try {
|
||||
HttpConnection hc = (HttpConnection)Connector.open("http://localhost:8000/tests/test.html");
|
||||
|
|
|
@ -40,6 +40,9 @@ import javax.microedition.io.StreamConnection;
|
|||
import javax.microedition.io.Connector;
|
||||
|
||||
public class TestHttpHeaders implements Testlet {
|
||||
public int getExpectedPass() { return 12; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
final String URL = "//nonexistent.example.com:8080/foo/bar?bazz#mumble";
|
||||
|
||||
StubHttpProtocol conn;
|
||||
|
|
|
@ -6,6 +6,9 @@ import java.io.*;
|
|||
import javax.microedition.io.*;
|
||||
|
||||
public class StressTestSocket implements Testlet {
|
||||
public int getExpectedPass() { return 0; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 1; }
|
||||
TestHarness th;
|
||||
static final String URL = "socket://localhost:50003";
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@ import java.io.*;
|
|||
import javax.microedition.io.*;
|
||||
|
||||
public class TestSocket implements Testlet {
|
||||
public int getExpectedPass() { return 0; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 2; }
|
||||
public void test(TestHarness th) {
|
||||
try {
|
||||
testBasicSocketConnection(th);
|
||||
|
|
|
@ -8,6 +8,9 @@ import gnu.testlet.TestHarness;
|
|||
import gnu.testlet.Testlet;
|
||||
|
||||
public class TestRandomAccessStream implements Testlet {
|
||||
public int getExpectedPass() { return 108; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public void test(TestHarness th) {
|
||||
RandomAccessStream ras = new RandomAccessStream();
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ import java.io.*;
|
|||
import com.sun.midp.io.j2me.storage.RandomAccessStream;
|
||||
|
||||
public class TestInputOutputStorage implements Testlet {
|
||||
public int getExpectedPass() { return 13; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
void testWrite(TestHarness th, OutputStream out) throws IOException {
|
||||
OutputStorage outStorage = new OutputStorage(out);
|
||||
outStorage.writeValue((byte)1, "Marco");
|
||||
|
@ -33,7 +36,9 @@ public class TestInputOutputStorage implements Testlet {
|
|||
public void test(TestHarness th) {
|
||||
try {
|
||||
FileConnection file = (FileConnection)Connector.open("file:////prova");
|
||||
th.check(!file.exists());
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
file.create();
|
||||
|
||||
RandomAccessStream ras = new RandomAccessStream();
|
||||
|
|
|
@ -11,6 +11,9 @@ import com.sun.midp.security.*;
|
|||
import com.sun.midp.main.Configuration;
|
||||
|
||||
public class TestWebPublicKeyStore implements Testlet {
|
||||
public int getExpectedPass() { return 3; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
static final byte[] GoDaddySecureCertificationAuthorityDER = hexToBytes("308204de308203c6a00302010202020301300d06092a864886f70d01010505003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3036313131363031353433375a170d3236313131363031353433375a3081ca310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e31333031060355040b132a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72793130302e06035504031327476f204461646479205365637572652043657274696669636174696f6e20417574686f726974793111300f06035504051308303739363932383730820122300d06092a864886f70d01010105000382010f003082010a0282010100c42dd5158c9c264cec3235eb5fb859015aa66181593b7063abe3dc3dc72ab8c933d379e43aed3c3023848eb33014b6b287c33d9554049edf99dd0b251e21de65297e35a8a954ebf6f73239d4265595adeffbfe5886d79ef4008d8c2a0cbd4204cea73f04f6ee80f2aaef52a16966dabe1aad5dda2c66ea1a6bbbe51a514a002f48c79875d8b929c8eef8666d0a9cb3f3fc787ca2f8a3f2b5c3f3b97a91c1a7e6252e9ca8ed12656e6af6124453703095c39c2b582b3d08744af2be51b0bf87d04c27586bb535c59daf1731f80b8feead813605890898cf3aaf2587c049eaa7fd67f7458e97cc1439e23685b57e1a37fd16f671119a743016fe1394a33f840d4f0203010001a38201323082012e301d0603551d0e04160414fdac6132936c45d6e2ee855f9abae7769968cce7301f0603551d23041830168014d2c4b0d291d44c1171b361cb3da1fedda86ad4e330120603551d130101ff040830060101ff020100303306082b0601050507010104273025302306082b060105050730018617687474703a2f2f6f6373702e676f64616464792e636f6d30460603551d1f043f303d303ba039a0378635687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f6764726f6f742e63726c304b0603551d200444304230400604551d20003038303606082b06010505070201162a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f7279300e0603551d0f0101ff040403020106300d06092a864886f70d01010505000382010100d286c0ecbdf9a1b667ee660ba2063a04508e1572ac4a749553cb37cb4449ef07906b33d996f09456a51330053c8532217bc9c70aa824a490de46d32523140367c210d66f0f5d7b7acc9fc5582ac1c49e21a85af3aca446f39ee463cb2f90a4292901d9722c29df370127bc4fee68d3218fc0b3e4f509edd210aa53b4bef0cc590bd63b961c952449dfceecfda7489114450e3a366fda45b345a241c9d4d7444e3eb97476d5a213552cc687a3b599ac0684877f7506fcbf144c0ecc6ec4df3db71271f4e8f15140222849e01d4b87a834cc06a2dd125ad186366403356f6f776eebf28550985eab0353ad9123631f169ccdb9b205633ae1f4681b1705359553ee");
|
||||
|
||||
static final byte[] GoDaddyDotComDER = hexToBytes("308205d6308204bea00302010202074afcc0e2e233aa300d06092a864886f70d01010505003081ca310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e31333031060355040b132a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72793130302e06035504031327476f204461646479205365637572652043657274696669636174696f6e20417574686f726974793111300f060355040513083037393639323837301e170d3134303432383134343633345a170d3135313230363137333732345a3081cd31133011060b2b0601040182373c0201031302555331183016060b2b0601040182373c02010213074172697a6f6e61311d301b060355040f131450726976617465204f7267616e697a6174696f6e311430120603550405130b522d313732343733332d36310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c6531193017060355040a1310476f44616464792e636f6d2c204c4c43311830160603550403130f7777772e676f64616464792e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100c5b14c056beb6b77ab00ff5e9352ef6c7c4564e5cf0a14ac038ab4635dcf4fa9b0cbb62a3222722759af530e17b4a0e8aa9f28cf2d828f12f020fb6c7fc8d945943fbaba873f9892e02510f71312775cf26ccc0696d272d3d774e7e4a580d399f13a22b34ec12fe14ad74e220b3f155b360b59a61f380046bcaa65ca6426c2e8a5f50f5f8f50fce0a1cee4b9cedecc8742d7e107bb57388485d9bfc08a87bd4ab815ce753be4618c86e20cc01c53ba36e02a093c0ddd958c4abda53468320b12fb41437dc3fbf3aa1737d56b7eb9012611cdcf51ad788ffda2198ffac5722ba15b2994d533ff51daa757784bd5853f94a0f185da5e9e49cf6b13d0cf801fd9df0203010001a38201ba308201b6300f0603551d130101ff04053003010100301d0603551d250416301406082b0601050507030106082b06010505070302300e0603551d0f0101ff0404030205a030330603551d1f042c302a3028a026a0248622687474703a2f2f63726c2e676f64616464792e636f6d2f676473332d39322e63726c30530603551d20044c304a3048060b6086480186fd6d010717033039303706082b06010505070201162b687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f30818006082b0601050507010104743072302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f304a06082b06010505073002863e687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f67645f696e7465726d6564696174652e637274301f0603551d23041830168014fdac6132936c45d6e2ee855f9abae7769968cce730270603551d110420301e820f7777772e676f64616464792e636f6d820b676f64616464792e636f6d301d0603551d0e0416041447b5046b1a8403da6902bb833995879edeb63779300d06092a864886f70d01010505000382010100bb60237e7a48f6d1c86011b1cea9f2fd3eec7215e1c105e4f261ebe11cdbdb8a82d5faa3f1a622931ef1ee81fa8101e096b2f6582ef84b534fc3d00790eefc955d3f53e4122c8c22b212f8512c51a41a6bfe0a54f9feddab539764f359f3eae21640b72166038705cb7d26864763f036699a36fcca5d1c4fdcf5b370561d469c792fc38ae383efbb3fb0382a390defe1d248dc1c9d82e4feb7413852e899d3582f0a343ff0bf83025a5510d352914d5f43caf7e05b5e93640ec2d71f912c74fdbed6584e175257c0ff27f22f89a17760766dcb76e9a553601a7b7653a5810e7fe0fff429d9df54c4dc11e72a55e79914dd0421dcb303e03e908f94093bde49bb");
|
||||
|
|
|
@ -7,6 +7,9 @@ import javax.microedition.io.file.FileConnection;
|
|||
import javax.microedition.rms.RecordStoreException;
|
||||
|
||||
public class TestRecordStoreFileNatives implements Testlet, SuiteContainer {
|
||||
public int getExpectedPass() { return 14; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
// SuiteContainer stubs
|
||||
public int getCallersSuiteId() { return 0; }
|
||||
public int getSuiteId(String vendorName, String suiteName) { return 0; }
|
||||
|
|
|
@ -13,6 +13,9 @@ import javax.microedition.io.Connector;
|
|||
import javax.microedition.io.StreamConnection;
|
||||
|
||||
public class TestSSLStreamConnection implements Testlet {
|
||||
public int getExpectedPass() { return 0; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 1; }
|
||||
static final String SOCKET_URL = "socket://localhost:54443";
|
||||
static final String HOST = "localhost";
|
||||
static final int PORT = 54443;
|
||||
|
|
|
@ -49,7 +49,24 @@ class LockerIsolate2 {
|
|||
}
|
||||
}
|
||||
|
||||
class LockerThread extends Thread {
|
||||
public void run() {
|
||||
SecurityToken t = SecurityTokenProvider.getToken();
|
||||
InterIsolateMutex m = InterIsolateMutex.getInstance(t, "mutex");
|
||||
|
||||
m.lock();
|
||||
try {
|
||||
// Give the test some time to test waiting for the lock
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {}
|
||||
m.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public class TestInterIsolateMutex implements Testlet {
|
||||
public int getExpectedPass() { return 3; }
|
||||
public int getExpectedFail() { return 0; }
|
||||
public int getExpectedKnownFail() { return 0; }
|
||||
public void test(TestHarness th) {
|
||||
SecurityToken t = SecurityTokenProvider.getToken();
|
||||
InterIsolateMutex m = InterIsolateMutex.getInstance(t, "mutex");
|
||||
|
@ -128,5 +145,59 @@ public class TestInterIsolateMutex implements Testlet {
|
|||
} catch (Exception e) {
|
||||
th.fail("Unexpected exception: " + e);
|
||||
}
|
||||
|
||||
m.unlock();
|
||||
|
||||
try {
|
||||
Isolate iso1 = new Isolate("com.sun.midp.util.isolate.LockerIsolate1", new String[] {});
|
||||
Isolate iso2 = new Isolate("com.sun.midp.util.isolate.LockerIsolate2", new String[] {});
|
||||
|
||||
iso2.start();
|
||||
iso1.start();
|
||||
|
||||
m.lock();
|
||||
m.unlock();
|
||||
|
||||
iso2.waitForExit();
|
||||
iso1.waitForExit();
|
||||
} catch (Exception e) {
|
||||
th.fail("Unexpected exception: " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
Isolate iso = new Isolate("com.sun.midp.util.isolate.LockerIsolate2", new String[] {});
|
||||
LockerThread lockerThread = new LockerThread();
|
||||
|
||||
lockerThread.start();
|
||||
|
||||
try {
|
||||
Thread.yield();
|
||||
} catch (Exception e) {}
|
||||
|
||||
iso.start();
|
||||
|
||||
iso.waitForExit();
|
||||
lockerThread.join();
|
||||
} catch (Exception e) {
|
||||
th.fail("Unexpected exception: " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
Isolate iso = new Isolate("com.sun.midp.util.isolate.LockerIsolate2", new String[] {});
|
||||
LockerThread lockerThread = new LockerThread();
|
||||
|
||||
iso.start();
|
||||
|
||||
try {
|
||||
Thread.yield();
|
||||
} catch (Exception e) {}
|
||||
|
||||
lockerThread.start();
|
||||
|
||||
iso.waitForExit();
|
||||
lockerThread.join();
|
||||
} catch (Exception e) {
|
||||
th.fail("Unexpected exception: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче