/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 1998, 1999 Wabasoft <www.wabasoft.com> * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine 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. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.sys; import totalcross.*; import totalcross.ui.*; import totalcross.util.*; /** * Vm contains various system-level methods. * <p> * This class contains methods to copy arrays, obtain a timestamp, sleep and get platform and version information, among * many other things. */ public final class Vm { /** Internal use only. Used only at desktop. */ public static int[] keysBeingIntercepted; /** Pass this to Vm.debug to erase the memo/txt file used to store the output. */ public final static String ERASE_DEBUG = "!erase debug!"; /** Pass this to Vm.debug to redirect the output to an alternative debugging viewer. The current platforms that support * this command are: * <ul> * <li> Android: use the logging window throught ADB, which can be viewed by calling * <code>\TotalCross3\etc\tools\android\debug_console.bat</code> * </ul> * This flag can be used only once, at the Application's constructor. Calling it afterwards can result in debugging data loss. */ public final static String ALTERNATIVE_DEBUG = "!alt_debug!"; // guich@tc122_14 /** * Set to <code>true</code> to disable <code>Vm.debug</code> message output. Note that the method calls will still * remain, and can slowdown your program. Note also that Vm.warning is not affected by this flag. * * @since SuperWaba 5.52 */ public static boolean disableDebug; // guich@552_30 private static long startTS = System.currentTimeMillis(); // guich@567_15 private Vm() { } /** * Copies the elements of one array to another array. This method returns true if the copy is successful. It will * return false if the array types are not compatible or if either array is null. If the length parameter would cause * the copy to read or write past the end of one of the arrays, an index out of range error will occur. If false is * returned then no copying has been performed. * * @param srcArray the array to copy elements from * @param srcStart the starting position in the source array * @param dstArray the array to copy elements to * @param dstStart the starting position in the destination array * @param length the number of elements to copy * @throws ArrayStoreException If the source array and destination array are not compatible */ public static boolean arrayCopy(Object srcArray, int srcStart, Object dstArray, int dstStart, int length) { if (length < 0 || srcArray == null || dstArray == null) // guich@566_27: // check if null return false; try { if (length > 0) // guich@tc110_80: Java throws AIOOBE if length is 0 System.arraycopy(srcArray, srcStart, dstArray, dstStart, length); } catch (ArrayIndexOutOfBoundsException aioobe) { throw aioobe; // guich@566_27: do the same thing as the device. } catch (ArrayStoreException ase) // this one must be passed along { throw ase; } catch (Exception e) { if (e.getMessage() != null) // guich@566_35: VmTest throws this Launcher.print("Exception thrown in arrayCopy: " + e.getMessage()); return false; } return true; } /** * Returns a time stamp in milliseconds. The time stamp is the time in milliseconds since the program started. The * maximum time stamp value is (1 << 30) which represents near 14 days of continuous use, and when it is reached, * the timer will reset to 0 and will continue counting from there. */ public static int getTimeStamp() { return (int) (System.currentTimeMillis() - startTS); } /** * Sets the device time to the given arguments. Note that in some systems, the millis field is ignored. Some devices * require that you add <code>Settings.timeZone</code>. * Does not work on Android, which does not allow to do this programatically. * @since TotalCross 1.0 * @deprecated It won't work on most devices. */ public static void setTime(Time t) { //startTS = System.currentTimeMillis() - t.getTimeLong(); - guich@tc100b5_18: prevent timer problems when running in Java } /** * Reboots the device. This is the equivalent of a warm boot (or soft reset). Calling this method terminates the * program, closes all open files, calls MainWindow.onExit and, finaly, resets the device. <br> * The implementation in JDK just exits the program: there's no reboot at all. * * @since SuperWaba 4.01 */ public static void exitAndReboot() { MainWindow.exit(0); } /** * Executes a command. * <p> * As an example, the following call could be used to run the command "scandir /p mydir" under Java, Win32 or WinCE: * * <pre> * int result = Vm.exec("scandir", "/p mydir", 0, true); * </pre> * * This example executes the Scribble program under PalmOS: * * <pre> * Vm.exec("Scribble", null, 0, false); * </pre> * * This example executes the web clipper program under PalmOS, telling it to display a web page by using launchCode * 54 (CmdGoToURL). * * <pre> * Vm.exec("Clipper", "http://www.yahoo.com", 54, true); * </pre> * * The args parameter passed to this method is the arguments string to pass to the program being executed. * <p> * The launchCode parameter is only used under PalmOS. Under PalmOS, it is the launch code value to use when the Vm * calls SysUIAppSwitch(). If 0 is passed, the default launch code (CmdNormalLaunch) is used to execute the program. * <p> * The wait parameter passed to this method determines whether to execute the command asynchronously. If false, then * the method will return without waiting for the command to complete execution. If true, the method will wait for * the program to finish executing and the return value of the method will be the value returned from the application * under Java, Win32 and WinCE. * <p> * To run another TotalCross program from Windows CE devices, use: * * <pre> * Vm.exec("\\TotalCross\\Path\\Program.exe", null, 0, false); * </pre> * Here's a sample of how to run the Internet Explorer in Windows CE: * <pre> * Vm.exec("\\windows\\iexplore.exe","about:blank",0,false); * </pre> * You cannot pass null nor "" in the args, or you'll get error 87. IExplore requires a page to open; in this case, * we open the blank page. * * In other words, you must call the program's executable. * <p> * When calling a TotalCross program, you can pass a command line parameter to the calling application, just placing * the parameters in the proper argument. It can be retrieved with <code>getCommandLine</code> method from the * MainWindow. * <p> * In some platforms, the caller application must be quit by calling <code>exit</code>. * <p> * In Windows 98 and beyond, if you don't pass the full path to the file, it is searched in the current PATH * environment variable. The command must contain only the exe name, and all the other arguments must bein the args * parameter. For example, the following code uses the CMD to open a file with the proper editor: * * <pre> * Vm.exec("cmd.exe", "/c start C:\\WINNT\\DirectX.log", 0, false); * </pre> * Important notes about path separators: * <ul> * <li>In the companion we tell to always use / as the path separator. Vm.exec must be used differently of the other * places, because you don't pass only paths in the args parameter, pass other things too. So, when you use a path * in File, we convert the / to the target separator (\ or /), but in Vm.exec we can't do that, for example, * changing "/c start" to "\c start" will make the execution fail. So, you'll have to choose the right separator in the * parameters. * <li> Make sure that, in Windows, the paths and parameters use \\, not / as path separator, or the command will not * run. * </ul> * If you're using /cmd and the command fails, change /c option to /k, which will keep the open window instead * of closing it, so you can see the error cause. *<p> * In BlackBerry, the command must be a module name. For instance, you can open TotalCross programs, just providing its * module (cod) name. * <ul> * <li> Vm.exec("net_rim_bb_browser_daemon", "http://www.google.com/search?hl=en&source=hp&q=abraham+lincoln",0,true); -- launchers a url </li> * </ul> * <p> * In Android, you can launch an application, an url at the browser, execute a shell command, or install an apk: * <ul> * <li> Vm.exec("cmd","logcat -d -f /sdcard/error.log -v time *:I",0,true); -- creates the adb report (useful to get errors - note that you must wait for the file to be created, since the wait parameter does not work - like File f = new File("/sdcard/error.log"); while (!f.exists()) Vm.sleep(500);) * <li> Vm.exec("url","http://www.google.com/search?hl=en&source=hp&q=abraham+lincoln",0,true): -- launches a url * <li> Vm.exec("totalcross.app.uigadgets","UIGadgets",0,false): -- launches another TotalCross' application * <li> Vm.exec("com.android.calculator2","Calculator",0,true); -- runs the Calculator program * <li> Vm.exec("/sdcard/myapp.apk",null,0,false); -- calls the apk installation tool. To access the card in Android devices, prefix the path with <code>/sdcard</code>. Be sure that the sdcard is NOT MOUNTED, otherwise your application will not have access to it. * <li> Vm.exec("viewer","file:///sdcard/files/chlorine-bogusInfo.txt", 0, true); -- uses an internal viewer to show the txt file to the user (here, stored in the sdcard, but could be anywhere). Also accepts HTM(L). Also accepts HTM(L) and JPG files. * <li> Vm.exec("viewer","/sdcard/Download/handbook.pdf",0,true); -- opens a pdf. Note: you must have a pdf reader installed; search for the free adobe reader in your favorite store. Returns -1 if args is null, -2 if file was not found. * <li> Vm.exec("viewer","/sdcard/photo1.jpg",0,true); -- opens a jpeg/jpg/png image so the image can be panned and zoomed. Returns -1 if args is null, -2 if file was not found. * <li> Vm.exec("totalcross.appsrvc","TCService",0,true); -- starts the given service * <li> Vm.exec("broadcast","broadcast package",flags,true); -- sends a broadcast intent. "flag" is used in intent.addFlags if different of 0. * </ul> * <p> * In iOS, the following work as in Android. Note that since iOS does not have a sdcard, you must extract or copy the files to your application's directory (Settings.appPath). * <ul> * <li> Vm.exec("url","http://www.google.com/search?hl=en&source=hp&q=abraham+lincoln",0,true): -- launches a url * <li> Vm.exec("viewer",Settings.appPath+"/chlorine-bogusInfo.txt", 0, true); -- uses an internal viewer to show the txt file to the user (here, stored in the sdcard, but could be anywhere). Also accepts HTM(L). Also accepts HTM(L) and JPG files. * <li> Vm.exec("viewer",Settings.appPath+"/handbook.pdf",0,true); -- opens a pdf. WORKS also for XLS, DOC, and all file types that the <code>UIWebView</code> component can show. A PDF reader is NOT required. * <li> Vm.exec("viewer",Settings.appPath+"/photo1.jpg",0,true); -- opens a jpeg/jpg/png image so the image can be panned and zoomed. * </ul> * In Win32, you can also use the "viewer" or "url" to open files and web pages: * <ul> * <li> Vm.exec("url","http://www.google.com/search?hl=en&source=hp&q=abraham+lincoln",0,true): -- launches a url * <li> Vm.exec("viewer","c:\\handbook.pdf",0,true); -- opens a pdf. WORKS also for XLS, DOC, and other registered extensions. * </ul> * * To be able to find what's the class name of a program you want to launch, install it in the Android Emulator * (which is inside the Android SDK) and run the "Dev Tools" / Package Browser. Then click on the package, and click * in the desired Activities button. The <code>command</code> parameter for Vm.exec is the "Process" description, and the * <code>args</code> parameter is the activitie's name. Note, however, that there's no guarantee that the program * will be available in a real device. * <p> * To install a cab file in Windows Mobile, you can use: * <pre> * Vm.exec("wceload.exe", fullPathToCabFile, 0, true); * </pre> * However, trying to update the program itself or the vm will close the program. So, update it at last. * * @param command the command to execute * @param args command arguments. Does not work on Android. * @param launchCode launch code for PalmOS applications. * @param wait whether to wait for the command to complete execution before returning. If wait is false, * don't forget to call the <code>exit</code> method right after this command is called, otherwise the application may * not be called. In Android, if you're calling a TotalCross program, the wait parameter is ignored (and defaults to false). * @return Usually is 0 if no error occured, or a system error code. -999 means that the file was not found. In Android, is always 0. */ public static int exec(String command, String args, int launchCode, boolean wait) { // guich@tc: if (!wait) totalcross.ui.MainWindow.getMainWindow().killThreads(); int status = -1; try { if (launchCode == -1) // guich@120 { // guich@120: the ideal were that all classes should be re-instantiated, because any static methods that // used the last MainWindow are now pointing to invalid data. Launcher.instance.setNewMainWindow((totalcross.ui.MainWindow) Class.forName(command).newInstance(), args); status = 0; } else if (command.equals("viewer")) { java.awt.Desktop.getDesktop().browse(new java.net.URI(args.replace(' ','+'))); } else { java.lang.Runtime runtime = java.lang.Runtime.getRuntime(); if (args != null) command = command + " " + args; java.lang.Process p = runtime.exec(command); if (wait) status = p.waitFor(); else status = 0; } } catch (Exception e) { e.printStackTrace(); } return status; } /** * Enables or disables device automatic turn-off, which happens after a period of inactivity of the device. If you disable the * auto-off, the original auto-off time will be restored automatically when the program exits. Keeping the device * always on is desired only when you're working with Sockets. Use it carefully, because it drains the battery. */ public static void setAutoOff(boolean enabled) { } /** * Causes the VM (or the current thread, if called from it) to pause execution for the given number of milliseconds. * * @param millis time to sleep in milliseconds */ public static void sleep(int millis) { try { java.lang.Thread.sleep(millis); } catch (InterruptedException e) { } } /** * Causes the VM (or the current thread, if called from it) to pause execution for aproximately the given number * of milliseconds. * * This method does not block the user interface engine, as Vm.sleep does, since it keeps calling Window.pumpEvents. * So, if you rotate the screen during a Vm.sleep, the rotation is blocked; but during a Vm.safeSleep, the rotation * occurs normally. Button presses and other user interface operation also occurs normally during this method. * * Obviously, if you call Vm.safeSleep(100) and a screen rotation (or any other event) occurs, this method will take * to return much more than 100ms. * * This method only makes sense for sleeps above 500ms, unless you're calling it from a loop (which is reasonable * to keep call it), and should not be called from threads. * * @param millis time to sleep in milliseconds * @since TotalCross 1.3.4 */ public static void safeSleep(int millis) { int cur = getTimeStamp(); int end = cur + millis; while (cur <= end) { millis = end - cur; int s = millis > 100 ? 100 : millis; try {java.lang.Thread.sleep(s);} catch (InterruptedException e) {} //if (Event.isAvailable()) // always call pumpEvents, otherwise a thread that use this method will not be able to update the screen Window.pumpEvents(); cur = getTimeStamp(); } } /** Vibrates the device for the specified number of milliseconds. * The millis is ignored in iOS, since there's no way to define the duration in that platform. * Note that on WP8 the maximum vibration time is 5 seconds. If millis is greater than 5000, it will vibrate only for 5 seconds. * * @since TotalCross 1.22 */ public static void vibrate(int millis) { Launcher.instance.vibrate(millis); } /** * Returns the free memory in the device. * Returns maximum of 2GB free, even if the device has more than that. * * @since SuperWaba 2.0 beta 4 */ public static int getFreeMemory() { return (int) Runtime.getRuntime().freeMemory(); } /** * Calls the Garbage Collector. Usually, this isn't necessary; the gc is called everytime theres * no more memory to allocate, but you may call it before running a memory-consuming routine. */ public static void gc() { Runtime.getRuntime().gc(); System.runFinalization(); } /** * Specify which special keys to intercept; use the constants available in SpecialKeys or pass device-specific * constants, which can be retrieved calling Vm.showKeyCodes(true). * * Note that the HOME key cannot be intercepted in Android due to OS restrictions. * * @since TotalCross 1.0 */ public static void interceptSpecialKeys(int[] keys) { keysBeingIntercepted = keys; // for desktop } /** * Gets the current keys being pressed. You must set which keys you want to receive notification with the * interceptSpecialKeys method. Note that you can use this method to verify if more than one key is pressed at once, * just keep pooling with this method to see when a state has changed. If you just want to intercept the key with a * single press, handle it in the onEvent method, with a KeyEvent event. * * @see #interceptSpecialKeys * @since TotalCross 1.0 */ public static boolean isKeyDown(int key) { try { return Launcher.instance.keysPressed.get(key) == 1; } catch (ElementNotFoundException e) { return false; } } /** * Sends a text, preceeded with the current time stamp and followed by a line feed, to: * <ul> * <li>Windows CE / 32: the "DebugConsole.txt" file at the current application's folder * <li>Blackberry: the event logger, which can be accessed using alt+LGLG * <li>iPhone: the "DebugConsole.txt" file in the application's folder. * <li>Java SE: the System.err console * </ul> * You can delete the debug memo/txt file passing the ERASE_DEBUG, a constant String declared in this class. E.g.: * <code>Vm.debug(Vm.ERASE_DEBUG);</code>. * <p> * Note: if you're debugging a String that contains \0 in it, all chars after the first \0 are ignored. * @see Settings#nvfsVolume * @see #disableDebug * @see #ALTERNATIVE_DEBUG * @see #ERASE_DEBUG */ public static void debug(String s) { if (disableDebug) return; if (s == null) s = "null"; if (!ERASE_DEBUG.equals(s)) // guich@420_18 - guich@510_19: fixed NPE when s==null System.err.println(Settings.showDebugTimestamp ? (getTimeStamp() + " - " + s) : s); // alexmuc@400_63 - guich@567_16: now using getTimeStamp - guich@tc115_50: don't display timestamp if user don't want else System.err.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); // just scroll the screen System.err.flush(); // guich@570_36 } /** * Shows an alert IMMEDIATELY on screen. It uses the sytem message box to show the alert, * not the totalcross.ui.MessageBox class. * <br><br>Note that unicode characters are not displayed on alerts. * * @since TotalCross 1.0 */ public static void alert(String s) { if (s == null) throw new NullPointerException("Argument 's' cannot have a null value"); Launcher.instance.alert(s); } /** * This function can be used to show permanent warnings. It was created because Vm.debug is, in theory, just for * debugging. Some TotalCross classes displays warnings to the user, and are not debug (i.e., temporary) messages. It * just calls <code>Vm.debug("Warning! "+s)</code>, so it differs from it only in a semanthical way. * <p> * Note: you cannot use this function with ERASE_DEBUG; it won't work. * * @since SuperWaba 4.21 */ public static void warning(String s) // guich@421_4 { debug("Warning! " + s); } private static class ClipboardObserver implements java.awt.datatransfer.ClipboardOwner { public void lostOwnership(java.awt.datatransfer.Clipboard clipboard, java.awt.datatransfer.Transferable contents) { } } private static java.awt.datatransfer.ClipboardOwner defaultClipboardOwner = new ClipboardObserver(); /** Copies the specific string to the clipboard. */ public static void clipboardCopy(String s) { java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new java.awt.datatransfer.StringSelection(s), defaultClipboardOwner); } /** Gets the last string from the clipboard. if none, returns "". */ public static String clipboardPaste() { java.awt.datatransfer.Transferable content = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().getContents(defaultClipboardOwner); if (content != null) try { return (String) (content.getTransferData(java.awt.datatransfer.DataFlavor.stringFlavor)); } catch (Exception e) { } return ""; } /** * Attaches a library to this application instance. TotalCross libraries are files that have a <b>Lib</b> * suffix. * <p> * This method is useful if you have a library and want to make its classes available to your app. At the * initialization, TotalCross scans all libraries in the device and automatically attach them. However, if * you downloaded a new library from a server or saved a bitmap into a file, you will need to attach the * file where it is located so you can instantiate its classes or load the image using <code>new Image(filename)</code>. * <p> * After a library is added, its file is blocked and thus cannot be modified. * <p> * To see what libraries are in the device, you can use <code>PDBFile.listPDBFiles</code> or * <code>File.listFiles</code> and check the files that ends with Lib * <p> * A check is made to prevent a library from being loaded twice. * @param name the library's name, with a 'Lib' suffix. Cannot contain a creator neither a type. * @return true if the library was found and attached, false otherwise. * @deprecated This method never worked in TotalCross. Previously, in SuperWaba, all class and resources were placed in a PDB file, * so attaching a pdb file was ok. However, in TotalCross, everything is placed in TCZ files, so attaching a PDB is useless. * To load an image that you saved with Image.saveTo, use Image.loadFrom. * @see totalcross.ui.image.Image#loadFrom */ public static boolean attachLibrary(String name) { return false; } private static Hashtable htLoadedNatLibs = new Hashtable(13); /** * Attaches a native library to this application instance (only works at device). You must attach the native library * before use any native methods from your library, otherwise you'll get errors like "cannot find native method * implementation for ...". To learn how to create a native library, look at the Library Tutorial chapter. In desktop, * always returns true. A check is made to prevent a library from being loaded twice. * <br><br>Does not work on Android. * @param name the library's name. The suffix 'Lib' is not mandatory. Cannot contain a creator neither a type. */ public static boolean attachNativeLibrary(String name) { if (htLoadedNatLibs.exists(name)) // guich@500_6: already loaded? return true; if (privateAttachNativeLibrary(name)) { htLoadedNatLibs.put(name, name); return true; } return false; } private static boolean privateAttachNativeLibrary(String name) { return true; } /** * Returns a byte array of a file contained in the same tcz where this one resides, or in some attached library (or JAR, * if application is running in a browser). The * returned array is a <i>fake</i> pointer; does NOT point directly to the file (a new buffer is created to store the * contents). Example: * * <pre> * byte[] b = Vm.getFile("textfiles/About.txt"); * if (b != null) * new MessageBox("About", new String(b, 0, b.length)).popup(); * </pre> * * The TotalCross deployer will insert the .txt file into the program's tcz/pdb. * * @param name The name of the file, exactly as shown by tc.Deploy in the output window. In desktop it is case * insensitive, while in device it is CASE SENSITIVE. * @return a byte array with the file or null if file not found */ public static byte[] getFile(String name) { return Launcher.instance.readBytes(name); } /** * Returns the percentage of the remaining battery life of this device. In systems that can have an auxiliary * battery, it will return the sum of the main and the auxiliary battery, but this sum will always be limited to * 100%. In desktop, it will always return 100. Note that in some OSes, when on the cradle, the returned value may be * 100% even when charging. * * @since SuperWaba 4.21 */ public static int getRemainingBattery() { return 100; } /** Each time the garbage collector runs, it will issue a beep. To be used in the tweak method. */ public static final int TWEAK_AUDIBLE_GC = 1; /** When the program ends, it will dump the memory status of the program with the following information: * <ul> * <li> Times gc was called: number of times the garbage collector was called. * <li> Total gc time: total time in milisseconds that the gc took * <li> Chunks created: number of chunks (block of memory used to store objects, each one with 65500 bytes) * <li> Max allocated: maximum memory allocated. * </ul> * To be used in the tweak method. */ public static final int TWEAK_DUMP_MEM_STATS = 2; /** Computes the maximum memory in use between two consecutive calls. For example: * <pre> * Vm.debug("P Starting profiler for xxxx"); * Vm.tweak(Vm.TWEAK_MEM_PROFILER,true); * // now run the program during some time * Vm.tweak(Vm.TWEAK_MEM_PROFILER,false); * Vm.debug("P Stopping profiler for xxxx"); * </pre> * When it starts, it prints the currently used memory. * When you set it off, it will dump the currently used memory (if different of the maximum), * and then the maximum memory used between the two calls. * For example: * <pre> * P Now allocated: 40852408 // printed when turning on * P Now allocated: 1137060 // printed when turning off * P Max allocated: 40868844 // printed when turning off * </pre> * All profiler messages are prefixed with P in the debug console, because it makes easy to filter them. * To be used in the tweak method. * @since TotalCross 1.11 */ public static final int TWEAK_MEM_PROFILER = 3; /** Disables the Garbage Collector. This can greatly decrease the time to load some things, but note that you * must re-enable it later, otherwise, the system will run out of memory quickly. * Example: * <pre> * Vm.tweak(TWEAK_DISABLE_GC,true); * ... * Vm.tweak(TWEAK_DISABLE_GC,false); // the gc is automatically called here * </pre> * @since TotalCross 1.14 */ public static final int TWEAK_DISABLE_GC = 4; /** This flag turns on the trace of created class objects. This helps you track objects that are not * being freed because are held in some way into memory. * This tweak increases memory usage, slows down the garbage collector and thus should not be used in production. * The output goes to the debug console. * @since TotalCross 3.1 */ public static final int TWEAK_TRACE_CREATED_CLASSOBJS = 5; /** This flag turns on the trace of locked objects, which are objects that are locked by the vm and will * never be released. * This tweak increases memory usage, slows down the garbage collector and thus should not be used in production. * The output goes to the debug console. * @since TotalCross 3.1 */ public static final int TWEAK_TRACE_LOCKED_OBJS = 6; /** This flag turns on the trace objects that are left behind between two garbage collector calls. * This helps you to find objects that are being held into memory by your program and that are thus never collected. * This tweak increases memory usage, slows down the garbage collector and thus should not be used in production. * The output goes to the debug console. * @since TotalCross 3.1 */ public static final int TWEAK_TRACE_OBJECTS_LEFT_BETWEEN_2_GCS = 7; /** Enables dump of executed methods to the console. CAUTION: this makes the program slower since hundreds of * method calls are sent to the console, use with caution. * The output format is: T timestamp thread class - method * @since TotalCross 3.1 */ public static final int TWEAK_TRACE_METHODS = 8; /** * Tweak some parameters of the virtual machine. Note that these * parameters are only available at the device, NOT when running as Java. * Also, the configuration is not persisted: * you must set this every time you run the program. * Each tweak must be made separately; they are NOT bit masks. For example: * <pre> * Vm.tweak(Vm.TWEAK_AUDIBLE_GC,true); * Vm.tweak(Vm.TWEAK_DUMP_MEM_STATS,true); * </pre> * * @since SuperWaba 5.82 * @see #TWEAK_AUDIBLE_GC * @see #TWEAK_DUMP_MEM_STATS * @see #TWEAK_MEM_PROFILER */ public static void tweak(int param, boolean set) // guich@582_3 { } /** * Returns the given throwable stack trace as a String. * A good alternative to show an exception to the user is: * <pre> * try * { * ... * } * catch (Exception e) * { * MessageBox.showException(e, false); // last parameter dumps to the console if true * } * </pre> * * @since SuperWaba 5.82 */ public static String getStackTrace(Throwable t) // guic@582_6 { java.io.StringWriter sw = new java.io.StringWriter(); // guich@tc100b4_6: with StringWriter it always works t.printStackTrace(new java.io.PrintWriter(sw)); String stacktrace = sw.toString(); if (stacktrace != null) stacktrace = Convert.replace(stacktrace, Convert.CRLF, "\n").replace("\tat ",""); return stacktrace; } /** * Set to true to popup an alert for each key pressed. This is useful for you to discover key codes that may be * intercepted with Vm.interceptSpecialKeys. Note that this will probably block the application and you will have to * provide a button to exit from it or just reset the device. <br> * <br> * On Windows CE, the key 91 is always displayed when a hotkey is pressed, so the vm will silently ignore it. * * @since TotalCross 1.0 */ public static void showKeyCodes(boolean on) { Launcher.instance.showKeyCodes = on; } /** * Turns the screen on or off, but keeps the device running. This greatly improves battery performance. * @return If the method succeed. * @since TotalCross 1.15 */ public static boolean turnScreenOn(boolean on) // guich@tc115_75 { return true; } /** Prints the stack trace to the debug console file. * Implemented as: * <pre> try { throw new Exception("Stack trace"); } catch (Exception e) { e.printStackTrace(); } * </pre> * @since TotalCross 1.3 */ public static void printStackTrace() { try { throw new Exception("Stack trace"); } catch (Exception e) { e.printStackTrace(); } } /** This method pre-allocates space for an array of objects with the given length. * It can reduce the number of calls to GC when allocating big arrays. * If the total size (Object size * length) is small, calling this method is useless * and will not result in any performance gain. * * You can always measure how the gc affects your program by doing this: * * <pre> * int gcc = Settings.gcCount, gct = Settings.gcTime, ini = Vm.getTimeStamp(); * ... run some memory-consuming routine * Vm.debug("gcCount: "+(Settings.gcCount-gcc)+" ("+(Settings.gcTime-gct)+"ms), elapsed: "+(Vm.getTimeStamp()-ini)+"ms"); * </pre> * * This is a sample that pre-allocates space for a ListContainer, taken from the PopupMenu class: * * <pre> * Vm.preallocateArray(new ListContainer.Item(layout), itemCount); * </pre> * * This method does nothing under Blackberry and Java SE. * * @since TotalCross 1.5 */ public static void preallocateArray(Object sample, int length) { } /** * Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class * overrides <code>hashCode()</code>. * The hash code for the <code>null</code> reference is zero. * * @param object Object for which the hash code is to be calculated. * @return The desired hash code. */ public static int identityHashCode(Object object) { return System.identityHashCode(object); } /** used internally for enum */ static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length) { arrayCopy(src,srcPos,dest,destPos,length); } }