Implemented Paul's solution to the basic/regular build problem -- a sort of pseudo-reflection approach that works in J2ME. Now we have only a build target, not separate products for the basic version.

git-svn-id: https://zxing.googlecode.com/svn/trunk@481 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-06-26 15:35:39 +00:00
parent f652a4b100
commit 7780ada5ad
8 changed files with 104 additions and 97 deletions

View file

@ -9,5 +9,6 @@ Daniel Switkin (Google)
David Albert (Bug Labs)
John Connolly (Bug Labs)
Matthew Schulkind (Google)
Paul Hackenberger
Sean Owen (Google)
Vince Francis

View file

@ -26,7 +26,6 @@
<ant dir="javame" target="build"/>
<ant dir="javase" target="build"/>
<ant dir="android" target="package"/>
<ant dir="javame" target="build-basic"/>
<ant dir="rim" target="build"/>
<ant dir="zxingorg" target="build"/>
</target>

View file

@ -65,7 +65,7 @@
</fail>
</target>
<target name="compile" depends="init">
<target name="build" depends="init">
<mkdir dir="build"/>
<javac srcdir="src"
destdir="build"
@ -79,39 +79,7 @@
<classpath refid="wtk-build-path"/>
</javac>
<jar jarfile="javame.jar" basedir="build"/>
</target>
<target name="compile-basic" depends="init">
<mkdir dir="build"/>
<!-- For an explanation of this odd build command, see javadoc in
src/com/google/zxing/client/j2me/AdvancedMultimediaManager.java -->
<javac srcdir="src-basic"
destdir="build"
source="1.2"
target="1.2"
bootclasspath="${javame-compile-bootclasspath-path}"
optimize="true"
debug="true"
deprecation="true"
fork="true">
<classpath refid="wtk-build-path"/>
</javac>
<javac srcdir="src"
destdir="build"
source="1.2"
target="1.2"
bootclasspath="${javame-compile-bootclasspath-path}"
optimize="true"
debug="true"
deprecation="true"
fork="true">
<classpath refid="wtk-build-path"/>
<exclude name="com/google/zxing/client/j2me/AdvancedMultimediaManager.java"/>
</javac>
<jar jarfile="javame-basic.jar" basedir="build"/>
</target>
<target name="package">
<unzip src="../core/core.jar" dest="build"/>
<mkdir dir="build-j2me"/>
@ -128,24 +96,27 @@
<copy file="src/com/google/zxing/client/j2me/MANIFEST.MF.template"
tofile="src/com/google/zxing/client/j2me/MANIFEST.MF" overwrite="true">
<filterset>
<filter token="APP_NAME" value="${jar-name}"/>
<filter token="APP_NAME" value="BarcodeReader"/>
<filter token="VERSION" value="${version}"/>
</filterset>
</copy>
<jar jarfile="${jar-name}.jar" basedir="build-j2me" manifest="src/com/google/zxing/client/j2me/MANIFEST.MF"/>
<jar jarfile="BarcodeReader.jar" basedir="build-j2me" manifest="src/com/google/zxing/client/j2me/MANIFEST.MF"/>
<move file="${jar-name}.jar" tofile="temp.jar"/>
<move file="BarcodeReader.jar" tofile="temp.jar"/>
<java jar="${WTK-home}/bin/proguard.jar" fork="true" failonerror="true">
<jvmarg value="-Dmaximum.inlined.code.length=32"/>
<arg value="-injars temp.jar"/>
<arg value="-outjars ${jar-name}.jar"/>
<arg value="-outjars BarcodeReader.jar"/>
<arg value="-libraryjars ${WTK-home}/lib/cldcapi11.jar"/>
<arg value="-libraryjars ${WTK-home}/lib/midpapi20.jar"/>
<arg value="-libraryjars ${WTK-home}/lib/mmapi.jar"/>
<arg value="-libraryjars ${WTK-home}/lib/jsr234.jar"/>
<arg value="-microedition"/>
<arg value="-keep public class com.google.zxing.client.j2me.ZXingMIDlet"/>
<arg value="-keep class com.google.zxing.client.j2me.AdvancedMultimediaManager"/>
<arg value="-keep class com.google.zxing.client.j2me.DefaultMultimediaManager"/>
<arg value="-keep class com.google.zxing.client.j2me.MultimediaManager"/>
<arg value="-optimizationpasses 7"/>
<arg value="-overloadaggressively"/>
<arg value="-allowaccessmodification"/>
@ -154,34 +125,18 @@
<delete file="temp.jar"/>
<!-- get .jar size to include it in the .jad file -->
<length file="${jar-name}.jar" property="jar-size"/>
<length file="BarcodeReader.jar" property="jar-size"/>
<copy file="BarcodeReader.jad.template" tofile="${jar-name}.jad" overwrite="true">
<copy file="BarcodeReader.jad.template" tofile="BarcodeReader.jad" overwrite="true">
<filterset>
<filter token="JAR_SIZE" value="${jar-size}"/>
<filter token="APP_NAME" value="${jar-name}"/>
<filter token="APP_NAME" value="BarcodeReader"/>
<filter token="VERSION" value="${version}"/>
</filterset>
</copy>
</target>
<target name="build">
<description>Builds the main reader .jar file</description>
<property name="jar-name" value="BarcodeReader"/>
<antcall target="clean"/>
<antcall target="compile"/>
<antcall target="package"/>
</target>
<target name="build-basic">
<description>Builds the basic reader .jar file</description>
<property name="jar-name" value="BarcodeReaderBasic"/>
<antcall target="clean"/>
<antcall target="compile-basic"/>
<antcall target="package"/>
</target>
<target name="dump">
<java jar="${WTK-home}/bin/proguard.jar" fork="true">
<arg value="-injars BarcodeReader.jar"/>

View file

@ -23,29 +23,20 @@ import javax.microedition.media.Controllable;
import javax.microedition.media.MediaException;
/**
* <p>This odd class encapsulates all access to functionality exposed by JSR-234,
* which provides access to things like focus and zoom. Not all phones support this though.
* Normally we might handle loading of code like this via reflection but this is
* not available to us in Java ME. So, we create two implementations of the same class --
* this one, and another found under source root "src-basic". This one actually calls
* JSR-234 methods. The other does nothing. The build script creates two build products then
* one compiled with this class and one with other, to create both the JSR-234 version
* and the "basic" non-JSR-234 version.</p>
* <p>See {@link DefaultMultimediaManager} documentation for details.</p>
*
* <p>This class should never be directly imported or reference in the code.</p>
*
* @author Sean Owen (srowen@google.com)
*/
final class AdvancedMultimediaManager {
final class AdvancedMultimediaManager implements MultimediaManager {
private static final int NO_ZOOM = 100;
private static final int MAX_ZOOM = 200;
private static final long FOCUS_TIME_MS = 750L;
private static final String DESIRED_METERING = "center-weighted";
private AdvancedMultimediaManager() {
// do nothing
}
static void setFocus(Controllable player) {
public void setFocus(Controllable player) {
FocusControl focusControl = (FocusControl)
player.getControl("javax.microedition.amms.control.camera.FocusControl");
if (focusControl != null) {
@ -68,7 +59,7 @@ final class AdvancedMultimediaManager {
}
}
static void setZoom(Controllable player) {
public void setZoom(Controllable player) {
ZoomControl zoomControl = (ZoomControl) player.getControl("javax.microedition.amms.control.camera.ZoomControl");
if (zoomControl != null) {
// We zoom in if possible to encourage the viewer to take a snapshot from a greater distance.
@ -86,7 +77,7 @@ final class AdvancedMultimediaManager {
}
}
static void setExposure(Controllable player) {
public void setExposure(Controllable player) {
ExposureControl exposureControl =
(ExposureControl) player.getControl("javax.microedition.amms.control.camera.ExposureControl");
if (exposureControl != null) {

View file

@ -0,0 +1,69 @@
/*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.j2me;
import javax.microedition.media.Controllable;
/**
* <p>This class encapsulates optional multimedia-related operations that the device
* may support, like setting focus and zoom. This implementation itself will do nothing.
* It will attempt to dynamically instantiate {@link com.google.zxing.client.j2me.AdvancedMultimediaManager}
* which has methods that call JSR-234 APIs to actually set focus, zoom, etc. If successful,
* this class will delegate to that implementation. But if the phone does not support these
* APIs, instantiation will simply fail and this implementation will do nothing.</p>
*
* <p>Credit to Paul Hackenberger for the nice workaround</p>
*
* @author Sean Owen (srowen@google.com)
* @author Paul Hackenberger
*/
class DefaultMultimediaManager implements MultimediaManager {
private MultimediaManager advancedMultimediaManager;
DefaultMultimediaManager() {
try {
advancedMultimediaManager = (MultimediaManager)
Class.forName("com.google.zxing.client.j2me.AdvancedMultimediaManager").newInstance();
} catch (ClassNotFoundException cnfe) {
// continue
} catch (IllegalAccessException iae) {
// continue
} catch (InstantiationException ie) {
// continue
}
}
public void setFocus(Controllable player) {
if (advancedMultimediaManager != null) {
advancedMultimediaManager.setFocus(player);
}
}
public void setZoom(Controllable player) {
if (advancedMultimediaManager != null) {
advancedMultimediaManager.setZoom(player);
}
}
public void setExposure(Controllable player) {
if (advancedMultimediaManager != null) {
advancedMultimediaManager.setExposure(player);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2007 ZXing authors
* Copyright 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,30 +19,19 @@ package com.google.zxing.client.j2me;
import javax.microedition.media.Controllable;
/**
* <p>See this exact same class under the "src" source root for a full explanation.
* This is a "no-op" version of the class that gets built into the .jar file
* which is suitable for non-JSR-234 devices.</p>
* <p>Implemented by {@link com.google.zxing.client.j2me.DefaultMultimediaManager} and
* {@link com.google.zxing.client.j2me.AdvancedMultimediaManager} in order to dynamically
* load support for JSR-234 APIs where possible.</p>
*
* @author Sean Owen (srowen@google.com)
* @author Paul Hackenberger
*/
final class AdvancedMultimediaManager {
interface MultimediaManager {
private AdvancedMultimediaManager() {
// do nothing
}
void setFocus(Controllable player);
// These signatures must match those in the other class exactly
void setZoom(Controllable player);
static void setFocus(Controllable player) {
// do nothing
}
static void setZoom(Controllable player) {
// do nothing
}
static void setExposure(Controllable player) {
// do nothing
}
void setExposure(Controllable player);
}

View file

@ -37,11 +37,13 @@ final class SnapshotThread implements Runnable {
private final ZXingMIDlet zXingMIDlet;
private final Object waitLock;
private boolean done;
private final MultimediaManager multimediaManager;
SnapshotThread(ZXingMIDlet zXingMIDlet) {
this.zXingMIDlet = zXingMIDlet;
waitLock = new Object();
done = false;
multimediaManager = new DefaultMultimediaManager();
}
void continueRun() {
@ -70,7 +72,7 @@ final class SnapshotThread implements Runnable {
do {
waitForSignal();
try {
AdvancedMultimediaManager.setFocus(player);
multimediaManager.setFocus(player);
byte[] snapshot = takeSnapshot();
Image capturedImage = Image.createImage(snapshot, 0, snapshot.length);
MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage);

View file

@ -72,8 +72,9 @@ public final class ZXingMIDlet extends MIDlet {
try {
player = createPlayer();
player.realize();
AdvancedMultimediaManager.setZoom(player);
AdvancedMultimediaManager.setExposure(player);
MultimediaManager multimediaManager = new DefaultMultimediaManager();
multimediaManager.setZoom(player);
multimediaManager.setExposure(player);
videoControl = (VideoControl) player.getControl("VideoControl");
canvas = new VideoCanvas(this);
canvas.setFullScreenMode(true);