Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/main/java/javax/microedition/lcdui/Canvas.java
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public static void setSettings(ProfileModel settings) {
parallelRedraw = (mode == 0 || mode == 3) && settings.parallelRedrawScreen;
}

/** Enables the diagnostic only when the loaded artifact advertises the timing transform ABI. */
/** Enables the diagnostic only when the loaded artifact has the current universal transform. */
public static void setTimingOverlayEnabled(boolean enabled) {
timingOverlayEnabled = enabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
* provide or shadow this class.
*/
public final class GuestTimingBridge {
public static final int ABI_VERSION = 4;

private static final Object LOCK = new Object();
private static TimingSession activeSession;

Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/javax/microedition/shell/MicroLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
import javax.microedition.shell.timing.EmulationSpeed;
import javax.microedition.shell.timing.TimingSession;
import javax.microedition.shell.timing.TimingMode;
import javax.microedition.shell.timing.TimingTransformMetadata;
import javax.microedition.shell.transform.MidletTransformMetadata;

public class MicroLoader {
private static final String TAG = MicroLoader.class.getName();
Expand Down Expand Up @@ -200,9 +200,9 @@ private boolean hasCompatibleTimingTransform() {
try {
Descriptor descriptor = new Descriptor(
new File(appDir, Config.MIDLET_MANIFEST_FILE), false);
return TimingTransformMetadata.isCompatible(descriptor.getAttrs());
return MidletTransformMetadata.isCompatible(descriptor.getAttrs());
} catch (IOException | RuntimeException e) {
Log.w(TAG, "Timing transform metadata is unavailable", e);
Log.w(TAG, "MIDlet transform metadata is unavailable", e);
return false;
}
}
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/java/javax/microedition/shell/MidletSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,19 @@ public static String getProperty(String key, String def) {
return value;
}

/**
* Handles an advisory garbage-collection request made by a MIDlet.
*
* <p>Forwarding every guest request to Android can start a compacting collection inside hot
* MIDlet loops. ART still collects normally when allocation pressure requires it.</p>
*/
public static void gc() {
// Java ME only requires the VM to make a best effort, so the emulator may ignore the hint.
}

/** Preserves the receiver null check while suppressing {@link Runtime#gc()} from guest code. */
public static void gc(Runtime runtime) {
if (runtime == null) throw new NullPointerException("runtime");
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 javax.microedition.shell.transform;

import java.util.Map;

/**
* Universal compatibility marker for an installed MIDlet's transformed bytecode.
*
* <p>Increment {@link #TRANSFORM_VERSION} whenever the converter changes emitted bytecode or a
* runtime bridge contract used by that bytecode. Installed MIDlets with an older or missing marker
* are then rebuilt by the normal app reconversion path when their retained source is available.</p>
*/
public final class MidletTransformMetadata {
/** Version 1 includes guest-time virtualization and suppression of advisory explicit GC. */
public static final int TRANSFORM_VERSION = 1;
public static final String TRANSFORM_VERSION_ATTRIBUTE = "JLMod-Transform-Version";
private static final String LEGACY_TIMING_TRANSFORM_ATTRIBUTE =
"JLMod-Timing-Transform-Version";
private static final String LEGACY_TIMING_BRIDGE_ATTRIBUTE = "JLMod-Timing-Bridge-ABI";

private MidletTransformMetadata() {
}

public static void mark(Map<String, String> attributes) {
if (attributes == null) {
throw new NullPointerException("attributes");
}
attributes.remove(LEGACY_TIMING_TRANSFORM_ATTRIBUTE);
attributes.remove(LEGACY_TIMING_BRIDGE_ATTRIBUTE);
attributes.put(TRANSFORM_VERSION_ATTRIBUTE, Integer.toString(TRANSFORM_VERSION));
}

public static boolean isCompatible(Map<String, String> attributes) {
return attributes != null
&& Integer.toString(TRANSFORM_VERSION).equals(
attributes.get(TRANSFORM_VERSION_ATTRIBUTE));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
import java.util.List;
import java.util.Set;

import javax.microedition.shell.timing.TimingTransformMetadata;
import javax.microedition.shell.transform.MidletTransformMetadata;
import javax.microedition.util.ContextHolder;

import kotlin.io.FilesKt;
Expand Down Expand Up @@ -996,7 +996,7 @@ private boolean hasCompatibleTimingTransform() {
try {
Descriptor descriptor = new Descriptor(
new File(appDir, Config.MIDLET_MANIFEST_FILE), false);
return TimingTransformMetadata.isCompatible(descriptor.getAttrs());
return MidletTransformMetadata.isCompatible(descriptor.getAttrs());
} catch (IOException | RuntimeException e) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/ru/woesss/j2me/installer/AppInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
import ru.woesss.j2me.jar.Descriptor;
import ru.woesss.util.TextUtils;
import ru.woesss.util.zip.ZipFile;
import javax.microedition.shell.timing.TimingTransformMetadata;
import javax.microedition.shell.transform.MidletTransformMetadata;

public class AppInstaller {
private static final String TAG = AppInstaller.class.getSimpleName();
Expand Down Expand Up @@ -431,7 +431,7 @@ void install(SingleEmitter<Integer> emitter) throws ConverterException, IOExcept
manifest.merge(newDesc);
newDesc = manifest;
}
TimingTransformMetadata.mark(newDesc.getAttrs());
MidletTransformMetadata.mark(newDesc.getAttrs());

File resJar = child(tmpDir, Config.MIDLET_RES_FILE);
FileUtils.copyFileUsingChannel(srcJar, resJar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import java.io.IOException;
import java.util.jar.JarFile;

import javax.microedition.shell.timing.TimingTransformMetadata;
import javax.microedition.shell.transform.MidletTransformMetadata;

import ru.playsoftware.j2meloader.config.Config;
import ru.playsoftware.j2meloader.librarydb.LibraryIconOverride;
Expand Down Expand Up @@ -61,9 +61,9 @@ public static boolean needsReconversion(File appDir) {
if (payload == null || !Config.isUsableFile(descriptorFile)) return true;
try {
Descriptor descriptor = new Descriptor(descriptorFile, false);
return !TimingTransformMetadata.isCompatible(descriptor.getAttrs());
return !MidletTransformMetadata.isCompatible(descriptor.getAttrs());
} catch (IOException | RuntimeException error) {
Log.w(TAG, "Unable to validate converted timing marker: " + appDir, error);
Log.w(TAG, "Unable to validate converted transform marker: " + appDir, error);
return true;
}
}
Expand Down Expand Up @@ -129,7 +129,7 @@ public static void reconvert(File requestedAppDir) throws IOException, Converter
if (!generatedPayload.isFile() || generatedPayload.length() <= 0L) {
throw new ConverterException("DX produced no converted MIDlet payload");
}
TimingTransformMetadata.mark(descriptor.getAttrs());
MidletTransformMetadata.mark(descriptor.getAttrs());
FileUtils.copyFileUsingChannel(retainedJar, fileWithSuffix(staging, Config.MIDLET_RES_FILE));
extractIcon(descriptor, retainedJar, staging);
descriptor.writeTo(fileWithSuffix(staging, Config.MIDLET_MANIFEST_FILE));
Expand Down
30 changes: 30 additions & 0 deletions app/src/test/java/javax/microedition/shell/MidletSystemTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 javax.microedition.shell;

import org.junit.Test;

public class MidletSystemTest {
@Test
public void advisoryGcRequestsReturnWithoutCollecting() {
MidletSystem.gc();
MidletSystem.gc(Runtime.getRuntime());
}

@Test(expected = NullPointerException.class)
public void runtimeGcBridgePreservesReceiverNullCheck() {
MidletSystem.gc((Runtime) null);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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 javax.microedition.shell.transform;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class MidletTransformMetadataTest {
@Test
public void currentVersionIsCompatibleAfterMarking() {
Map<String, String> attributes = new HashMap<>();
MidletTransformMetadata.mark(attributes);

assertTrue(MidletTransformMetadata.isCompatible(attributes));
}

@Test
public void missingOrChangedUniversalVersionIsRejected() {
Map<String, String> attributes = new HashMap<>();
MidletTransformMetadata.mark(attributes);
attributes.put(MidletTransformMetadata.TRANSFORM_VERSION_ATTRIBUTE, "999");

assertFalse(MidletTransformMetadata.isCompatible(attributes));
assertFalse(MidletTransformMetadata.isCompatible(new HashMap<>()));
assertFalse(MidletTransformMetadata.isCompatible(null));
}

@Test
public void legacyTimingOnlyMarkerTriggersUniversalReconversion() {
Map<String, String> attributes = new HashMap<>();
attributes.put("JLMod-Timing-Transform-Version", "6");
attributes.put("JLMod-Timing-Bridge-ABI", "4");

assertFalse(MidletTransformMetadata.isCompatible(attributes));

MidletTransformMetadata.mark(attributes);

assertTrue(MidletTransformMetadata.isCompatible(attributes));
assertNull(attributes.get("JLMod-Timing-Transform-Version"));
assertNull(attributes.get("JLMod-Timing-Bridge-ABI"));
}
}
Loading