summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:23 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:23 -0800
commitb798689749c64baba81f02e10cf2157c747d6b46 (patch)
treeda394a395ddb1a6cf69193314846b03fe47a397e /tools
parentf013e1afd1e68af5e3b868c26a653bbfb39538f8 (diff)
downloadframeworks_base-b798689749c64baba81f02e10cf2157c747d6b46.zip
frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.gz
frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.bz2
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'tools')
-rw-r--r--tools/aapt/Images.cpp222
-rw-r--r--tools/aapt/Package.cpp2
-rw-r--r--tools/aapt/ResourceTable.cpp3
-rw-r--r--tools/aidl/aidl.cpp2
-rw-r--r--tools/aidl/generate_java.cpp2
-rw-r--r--tools/aidl/options.cpp4
-rw-r--r--tools/aidl/search_path.cpp1
-rw-r--r--tools/aidl/search_path.h1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java96
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java3
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java4
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java91
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java76
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java102
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java97
-rw-r--r--tools/localize/Perforce.cpp2
-rw-r--r--tools/localize/XLIFFFile.cpp1
-rw-r--r--tools/localize/XMLHandler.cpp1
-rw-r--r--tools/localize/file_utils.cpp3
-rw-r--r--tools/localize/localize.cpp1
20 files changed, 616 insertions, 98 deletions
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 9d5937c..7c4963f 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -618,10 +618,151 @@ static bool patch_equals(Res_png_9patch& patch1, Res_png_9patch& patch2) {
return true;
}
+
+static void analyze_image(image_info &imageInfo, png_colorp rgbPalette, png_bytep alphaPalette,
+ int *paletteEntries, bool *hasTransparency, int *colorType,
+ png_bytepp outRows)
+{
+ int w = imageInfo.width;
+ int h = imageInfo.height;
+ bool trans = imageInfo.hasTransparency;
+ int i, j, rr, gg, bb, aa, idx;
+ uint32_t colors[256], col;
+ int num_colors = 0;
+
+ bool isOpaque = true;
+ bool isPalette = true;
+ bool isGrayscale = true;
+
+ // Scan the entire image and determine if:
+ // 1. Every pixel has R == G == B (grayscale)
+ // 2. Every pixel has A == 255 (opaque)
+ // 3. There are no more than 256 distinct RGBA colors
+ for (j = 0; j < h; j++) {
+ png_bytep row = imageInfo.rows[j];
+ png_bytep out = outRows[j];
+ for (i = 0; i < w; i++) {
+ rr = *row++;
+ gg = *row++;
+ bb = *row++;
+ aa = *row++;
+ if (!trans) {
+ // Ignore the actually byte and assume alpha == 255
+ aa = 0xff;
+ }
+
+ // Check if image is really grayscale
+ if (isGrayscale) {
+ if (rr != gg || rr != bb) {
+ isGrayscale = false;
+ }
+ }
+
+ // Check if image is really opaque
+ if (isOpaque) {
+ if (aa != 0xff) {
+ isOpaque = false;
+ }
+ }
+
+ // Check if image is really <= 256 colors
+ if (isPalette) {
+ col = (uint32_t) ((rr << 24) | (gg << 16) | (bb << 8) | aa);
+ bool match = false;
+ for (idx = 0; idx < num_colors; idx++) {
+ if (colors[idx] == col) {
+ match = true;
+ break;
+ }
+ }
+
+ // Write the palette index for the pixel to outRows optimistically
+ // We might overwrite it later if we decide to encode as gray or
+ // gray + alpha
+ *out++ = idx;
+ if (!match) {
+ if (num_colors == 256) {
+ isPalette = false;
+ } else {
+ colors[num_colors++] = col;
+ }
+ }
+ }
+ }
+ }
+
+ *paletteEntries = 0;
+ *hasTransparency = !isOpaque;
+ int bpp = isOpaque ? 3 : 4;
+ int paletteSize = w * h + bpp * num_colors;
+
+ // Choose the best color type for the image.
+ // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel
+ // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct combinations
+ // is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA
+ // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is sufficiently
+ // small, otherwise use COLOR_TYPE_RGB{_ALPHA}
+ if (isGrayscale) {
+ if (isOpaque) {
+ *colorType = PNG_COLOR_TYPE_GRAY; // 1 byte/pixel
+ } else {
+ // Use a simple heuristic to determine whether using a palette will
+ // save space versus using gray + alpha for each pixel.
+ // This doesn't take into account chunk overhead, filtering, LZ
+ // compression, etc.
+ if (isPalette && (paletteSize < 2 * w * h)) {
+ *colorType = PNG_COLOR_TYPE_PALETTE; // 1 byte/pixel + 4 bytes/color
+ } else {
+ *colorType = PNG_COLOR_TYPE_GRAY_ALPHA; // 2 bytes per pixel
+ }
+ }
+ } else if (isPalette && (paletteSize < bpp * w * h)) {
+ *colorType = PNG_COLOR_TYPE_PALETTE;
+ } else {
+ *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
+ }
+
+ // Perform postprocessing of the image or palette data based on the final
+ // color type chosen
+
+ if (*colorType == PNG_COLOR_TYPE_PALETTE) {
+ // Create separate RGB and Alpha palettes and set the number of colors
+ *paletteEntries = num_colors;
+
+ // Create the RGB and alpha palettes
+ for (int idx = 0; idx < num_colors; idx++) {
+ col = colors[idx];
+ rgbPalette[idx].red = (png_byte) ((col >> 24) & 0xff);
+ rgbPalette[idx].green = (png_byte) ((col >> 16) & 0xff);
+ rgbPalette[idx].blue = (png_byte) ((col >> 8) & 0xff);
+ alphaPalette[idx] = (png_byte) (col & 0xff);
+ }
+ } else if (*colorType == PNG_COLOR_TYPE_GRAY || *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ // If the image is gray or gray + alpha, compact the pixels into outRows
+ for (j = 0; j < h; j++) {
+ png_bytep row = imageInfo.rows[j];
+ png_bytep out = outRows[j];
+ for (i = 0; i < w; i++) {
+ rr = *row++;
+ gg = *row++;
+ bb = *row++;
+ aa = *row++;
+
+ *out++ = rr;
+ if (!isOpaque) {
+ *out++ = aa;
+ }
+ }
+ }
+ }
+}
+
+
static void write_png(const char* imageName,
png_structp write_ptr, png_infop write_info,
image_info& imageInfo)
{
+ bool optimize = true;
png_uint_32 width, height;
int color_type;
int bit_depth, interlace_type, compression_type;
@@ -629,17 +770,73 @@ static void write_png(const char* imageName,
png_unknown_chunk unknowns[1];
+ png_bytepp outRows = (png_bytepp) malloc((int) imageInfo.height * png_sizeof(png_bytep));
+ if (outRows == (png_bytepp) 0) {
+ printf("Can't allocate output buffer!\n");
+ exit(1);
+ }
+ for (i = 0; i < (int) imageInfo.height; i++) {
+ outRows[i] = (png_bytep) malloc(2 * (int) imageInfo.width);
+ if (outRows[i] == (png_bytep) 0) {
+ printf("Can't allocate output buffer!\n");
+ exit(1);
+ }
+ }
+
png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);
- color_type = PNG_COLOR_MASK_COLOR;
- if (imageInfo.hasTransparency) {
- color_type |= PNG_COLOR_MASK_ALPHA;
+ NOISY(printf("Writing image %s: w = %d, h = %d, trans = %s\n", imageName,
+ (int) imageInfo.width, (int) imageInfo.height,
+ imageInfo.hasTransparency ? "true" : "false"));
+
+ png_color rgbPalette[256];
+ png_byte alphaPalette[256];
+ bool hasTransparency;
+ int paletteEntries;
+
+ if (optimize) {
+ analyze_image(imageInfo, rgbPalette, alphaPalette, &paletteEntries, &hasTransparency,
+ &color_type, outRows);
+ switch (color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ NOISY(printf("Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\n",
+ imageName, paletteEntries,
+ hasTransparency ? " (with alpha)" : ""));
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ NOISY(printf("Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\n", imageName));
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ NOISY(printf("Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\n", imageName));
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ NOISY(printf("Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\n", imageName));
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ NOISY(printf("Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\n", imageName));
+ break;
+ }
+ } else {
+ // Force RGB or RGB_ALPHA color type, copy transparency from input
+ paletteEntries = 0;
+ hasTransparency = imageInfo.hasTransparency;
+ color_type = hasTransparency ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB;
}
png_set_IHDR(write_ptr, write_info, imageInfo.width, imageInfo.height,
8, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ if (color_type == PNG_COLOR_TYPE_PALETTE) {
+ png_set_PLTE(write_ptr, write_info, rgbPalette, paletteEntries);
+ if (hasTransparency) {
+ png_set_tRNS(write_ptr, write_info, alphaPalette, paletteEntries, (png_color_16p) 0);
+ }
+ png_set_filter(write_ptr, 0, PNG_NO_FILTERS);
+ } else {
+ png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);
+ }
+
if (imageInfo.is9Patch) {
NOISY(printf("Adding 9-patch info...\n"));
strcpy((char*)unknowns[0].name, "npTc");
@@ -659,15 +856,24 @@ static void write_png(const char* imageName,
}
png_write_info(write_ptr, write_info);
-
+
if (!imageInfo.hasTransparency) {
png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);
}
- png_write_image(write_ptr, imageInfo.rows);
+ if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ png_write_image(write_ptr, imageInfo.rows);
+ } else {
+ png_write_image(write_ptr, outRows);
+ }
png_write_end(write_ptr, write_info);
+ for (i = 0; i < (int) imageInfo.height; i++) {
+ free(outRows[i]);
+ }
+ free(outRows);
+
png_get_IHDR(write_ptr, write_info, &width, &height,
&bit_depth, &color_type, &interlace_type,
&compression_type, NULL);
@@ -687,9 +893,9 @@ status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets,
return NO_ERROR;
}
- // Example of renaming a file:
- //*outNewLeafName = file->getPath().getBasePath().getFileName();
- //outNewLeafName->append(".nupng");
+ // Example of renaming a file:
+ //*outNewLeafName = file->getPath().getBasePath().getFileName();
+ //outNewLeafName->append(".nupng");
String8 printableName(file->getPrintableSource());
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index 0df4606..5d9e140 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -22,7 +22,7 @@ static const char* kExcludeExtension = ".EXCLUDE";
static const char* kNoCompressExt[] = {
".jpg", ".jpeg", ".png", ".gif",
".wav", ".mp2", ".mp3", ".ogg", ".aac",
- ".mpg", ".mpeg", ".mid", ".midi", ".smf",
+ ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".amr", ".awb", ".wma", ".wmv"
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 3641458..33f8f72 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -115,7 +115,7 @@ static const flag_entry gFormatFlags[] = {
"a floating point value, such as \"<code>1.2</code>\"."},
{ dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
"a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
- "Available units are: px (pixels), db (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
+ "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
"in (inches), mm (millimeters)." },
{ fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
"a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n"
@@ -3479,4 +3479,3 @@ bool ResourceTable::getItemValue(
}
return res;
}
-
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index 927d21e..dc61567 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -10,6 +10,8 @@
#include <sys/stat.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <map>
#ifdef HAVE_MS_C_RUNTIME
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
index 7f84ff4..e3c0af0 100644
--- a/tools/aidl/generate_java.cpp
+++ b/tools/aidl/generate_java.cpp
@@ -2,6 +2,8 @@
#include "AST.h"
#include "Type.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
// =================================================
class VariableFactory
diff --git a/tools/aidl/options.cpp b/tools/aidl/options.cpp
index a890556..57b10ae 100644
--- a/tools/aidl/options.cpp
+++ b/tools/aidl/options.cpp
@@ -1,6 +1,10 @@
#include "options.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
static int
usage()
{
diff --git a/tools/aidl/search_path.cpp b/tools/aidl/search_path.cpp
index 3c4e14b..ffb6cb2 100644
--- a/tools/aidl/search_path.cpp
+++ b/tools/aidl/search_path.cpp
@@ -1,6 +1,7 @@
#include <unistd.h>
#include "search_path.h"
#include "options.h"
+#include <string.h>
#ifdef HAVE_MS_C_RUNTIME
#include <io.h>
diff --git a/tools/aidl/search_path.h b/tools/aidl/search_path.h
index 8d85d81..2bf94b1 100644
--- a/tools/aidl/search_path.h
+++ b/tools/aidl/search_path.h
@@ -5,6 +5,7 @@
#if __cplusplus
#include <vector>
+#include <string>
using namespace std;
extern "C" {
#endif
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index b898192..f5087d9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -28,7 +28,7 @@ import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
import com.android.layoutlib.bridge.LayoutResult.LayoutViewInfo;
import com.android.ninepatch.NinePatch;
import com.android.tools.layoutlib.create.OverrideMethod;
-import com.android.tools.layoutlib.create.OverrideMethod.MethodListener;
+import com.android.tools.layoutlib.create.MethodAdapter;
import android.graphics.Bitmap;
import android.graphics.Rect;
@@ -101,13 +101,10 @@ public final class Bridge implements ILayoutBridge {
new HashMap<String, NinePatch>();
private static Map<String, Map<String, Integer>> sEnumValueMap;
-
- private final static MethodListener sNullMethodListener = new MethodListener() {
- public void onInvoke(String signature, boolean isNative, Object caller) {
- // pass
- }
- };
+ /**
+ * A default logger than prints to stdout/stderr.
+ */
private final static ILayoutLog sDefaultLogger = new ILayoutLog() {
public void error(String message) {
System.err.println(message);
@@ -127,21 +124,16 @@ public final class Bridge implements ILayoutBridge {
}
};
- /** Logger defined during a compute layout operation. */
+ /**
+ * Logger defined during a compute layout operation.
+ * <p/>
+ * This logger is generally set to {@link #sDefaultLogger} except during rendering
+ * operations when it might be set to a specific provided logger.
+ * <p/>
+ * To change this value, use a block synchronized on {@link #sDefaultLogger}.
+ */
private static ILayoutLog sLogger = sDefaultLogger;
- private final static String[] IGNORED_STATIC_METHODS = new String[] {
- "android.content.res.AssetManager#init()V",
- "android.content.res.AssetManager#deleteTheme(I)V",
- "android.content.res.AssetManager#destroy()V",
- "android.graphics._Original_Paint#native_init()I",
- "android.graphics.Bitmap#nativeRecycle(I)V",
- "android.graphics.Bitmap#nativeDestructor(I)V",
- "android.view.animation.Transformation#<clinit>()V",
- "android.view.animation.Transformation#<init>()V",
- "android.view.animation.Transformation#clear()V",
- };
-
/*
* (non-Javadoc)
* @see com.android.layoutlib.api.ILayoutBridge#getApiLevel()
@@ -163,32 +155,52 @@ public final class Bridge implements ILayoutBridge {
private static synchronized boolean sinit(String fontOsLocation,
Map<String, Map<String, Integer>> enumValueMap) {
- // set an empty method listener for some known static methods we don't care about.
- for (String method : IGNORED_STATIC_METHODS) {
- OverrideMethod.setMethodListener(method, sNullMethodListener);
- }
-
-
- // set a the default listener for the rest of the static methods. It prints out
- // missing stub methods and then throws an exception for native methods if the
- // environment variable DEBUG_LAYOUT is not defined.
- OverrideMethod.setDefaultListener(new MethodListener() {
- public void onInvoke(String signature, boolean isNative, Object caller) {
- if (isNative) {
+ // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
+ // on static (native) methods which prints the signature on the console and
+ // throws an exception.
+ // This is useful when testing the rendering in ADT to identify static native
+ // methods that are ignored -- layoutlib_create makes them returns 0/false/null
+ // which is generally OK yet might be a problem, so this is how you'd find out.
+ //
+ // Currently layoutlib_create only overrides static native method.
+ // Static non-natives are not overridden and thus do not get here.
+ final String debug = System.getenv("DEBUG_LAYOUT");
+ if (debug != null && !debug.equals("0") && !debug.equals("false")) {
+
+ OverrideMethod.setDefaultListener(new MethodAdapter() {
+ @Override
+ public void onInvokeV(String signature, boolean isNative, Object caller) {
if (sLogger != null) {
- sLogger.error("Missing Stub: " + signature +
- (isNative ? " (native)" : ""));
+ synchronized (sDefaultLogger) {
+ sLogger.error("Missing Stub: " + signature +
+ (isNative ? " (native)" : ""));
+ }
}
- if (System.getenv("DEBUG_LAYOUT") == null) {
- // TODO throwing this exception doesn't seem that useful. It breaks
+ if (debug.equalsIgnoreCase("throw")) {
+ // Throwing this exception doesn't seem that useful. It breaks
// the layout editor yet doesn't display anything meaningful to the
- // user. Having the error in the console is just as useful.
+ // user. Having the error in the console is just as useful. We'll
+ // throw it only if the environment variable is "throw" or "THROW".
throw new StaticMethodNotImplementedException(signature);
}
}
+ });
+ }
+
+ // Override View.isInEditMode to return true.
+ //
+ // This allows custom views that are drawn in the Graphical Layout Editor to adapt their
+ // rendering for preview. Most important this let custom views know that they can't expect
+ // the rest of their activities to be alive.
+ OverrideMethod.setMethodListener("android.view.View#isInEditMode()Z",
+ new MethodAdapter() {
+ @Override
+ public int onInvokeI(String signature, boolean isNative, Object caller) {
+ return 1;
+ }
}
- });
+ );
// load the fonts.
FontLoader fontLoader = FontLoader.create(fontOsLocation);
@@ -283,7 +295,9 @@ public final class Bridge implements ILayoutBridge {
logger = sDefaultLogger;
}
- sLogger = logger;
+ synchronized (sDefaultLogger) {
+ sLogger = logger;
+ }
// find the current theme and compute the style inheritance map
Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
@@ -368,7 +382,9 @@ public final class Bridge implements ILayoutBridge {
t.getClass().getSimpleName() + ": " + t.getMessage());
} finally {
// Remove the global logger
- sLogger = sDefaultLogger;
+ synchronized (sDefaultLogger) {
+ sLogger = sDefaultLogger;
+ }
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index b4e2c2b..1adcc17 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -68,7 +68,8 @@ public class AsmGenerator {
*
* @param log Output logger.
* @param osDestJar The path of the destination JAR to create.
- * @param stubMethods The list of methods to stub out
+ * @param stubMethods The list of methods to stub out. Each entry must be in the form
+ * "package.package.OuterClass$InnerClass#MethodName".
* @param renameClasses The list of classes to rename, must be an even list: the binary FQCN
* of class to replace followed by the new FQCN.
* @param deleteReturns List of classes for which the methods returning them should be deleted.
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 13443d5..76bd8d4 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -45,9 +45,11 @@ public class Main {
AsmGenerator agen = new AsmGenerator(log, osDestJar[0],
new Class<?>[] { // classes to inject in the final JAR
OverrideMethod.class,
- OverrideMethod.MethodListener.class
+ MethodListener.class,
+ MethodAdapter.class
},
new String[] { // methods to force override
+ "android.view.View#isInEditMode",
"android.content.res.Resources$Theme#obtainStyledAttributes",
},
new String[] { // classes to rename (so that we can replace them in layoutlib)
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
new file mode 100644
index 0000000..627ea17
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.android.tools.layoutlib.create;
+
+
+/**
+ * An adapter to make it easier to use {@link MethodListener}.
+ * <p/>
+ * The adapter calls the void {@link #onInvokeV(String, boolean, Object)} listener
+ * for all types (I, L, F, D and A), returning 0 or null as appropriate.
+ */
+public class MethodAdapter implements MethodListener {
+ /**
+ * A stub method is being invoked.
+ * <p/>
+ * Known limitation: caller arguments are not available.
+ *
+ * @param signature The signature of the method being invoked, composed of the
+ * binary class name followed by the method descriptor (aka argument
+ * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
+ * @param isNative True if the method was a native method.
+ * @param caller The calling object. Null for static methods, "this" for instance methods.
+ */
+ public void onInvokeV(String signature, boolean isNative, Object caller) {
+ }
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return an integer, or a boolean, or a short or a byte.
+ */
+ public int onInvokeI(String signature, boolean isNative, Object caller) {
+ onInvokeV(signature, isNative, caller);
+ return 0;
+ }
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return a long.
+ */
+ public long onInvokeL(String signature, boolean isNative, Object caller) {
+ onInvokeV(signature, isNative, caller);
+ return 0;
+ }
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return a float.
+ */
+ public float onInvokeF(String signature, boolean isNative, Object caller) {
+ onInvokeV(signature, isNative, caller);
+ return 0;
+ }
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return a double.
+ */
+ public double onInvokeD(String signature, boolean isNative, Object caller) {
+ onInvokeV(signature, isNative, caller);
+ return 0;
+ }
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return an object.
+ */
+ public Object onInvokeA(String signature, boolean isNative, Object caller) {
+ onInvokeV(signature, isNative, caller);
+ return null;
+ }
+}
+
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
new file mode 100644
index 0000000..6fc2b24
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.android.tools.layoutlib.create;
+
+
+/**
+ * Interface to allow a method invocation to be listened upon.
+ * <p/>
+ * This is used by {@link OverrideMethod} to register a listener for methods that
+ * have been stubbed by the {@link AsmGenerator}. At runtime the stub will call either a
+ * default global listener or a specific listener based on the method signature.
+ */
+public interface MethodListener {
+ /**
+ * A stub method is being invoked.
+ * <p/>
+ * Known limitation: caller arguments are not available.
+ *
+ * @param signature The signature of the method being invoked, composed of the
+ * binary class name followed by the method descriptor (aka argument
+ * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
+ * @param isNative True if the method was a native method.
+ * @param caller The calling object. Null for static methods, "this" for instance methods.
+ */
+ public void onInvokeV(String signature, boolean isNative, Object caller);
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return an integer, or a boolean, or a short or a byte.
+ */
+ public int onInvokeI(String signature, boolean isNative, Object caller);
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return a long.
+ */
+ public long onInvokeL(String signature, boolean isNative, Object caller);
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return a float.
+ */
+ public float onInvokeF(String signature, boolean isNative, Object caller);
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return a double.
+ */
+ public double onInvokeD(String signature, boolean isNative, Object caller);
+
+ /**
+ * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
+ * @see #onInvokeV(String, boolean, Object)
+ * @return an object.
+ */
+ public Object onInvokeA(String signature, boolean isNative, Object caller);
+}
+
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
index b061a15..a6aff99 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
@@ -20,27 +20,13 @@ import java.util.HashMap;
/**
* Allows stub methods from LayoutLib to be overriden at runtime.
+ * <p/>
+ * Implementation note: all types required by this class(inner/outer classes & interfaces)
+ * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java;
+ * Otherwise they won't be accessible in layoutlib.jar at runtime.
*/
public final class OverrideMethod {
- /**
- * Interface to allow a method invocation to be listend upon.
- */
- public interface MethodListener {
- /**
- * A stub method is being invoked.
- * <p/>
- * Known limitation: caller arguments are not available. Return value cannot be set.
- *
- * @param signature The signature of the method being invoked, composed of the
- * binary class name followed by the method descriptor (aka argument
- * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
- * @param isNative True if the method was a native method.
- * @param caller The calling object. Null for static methods, "this" for instance methods.
- */
- public void onInvoke(String signature, boolean isNative, Object caller);
- }
-
/** Map of method overridden. */
private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>();
/** Default listener for all method not listed in sMethods. Nothing if null. */
@@ -71,7 +57,9 @@ public final class OverrideMethod {
}
/**
- * Invoke the specific listener for the given signature or the default one if defined.
+ * Invokes the specific listener for the given signature or the default one if defined.
+ * <p/>
+ * This version invokes the method listener for the void return type.
* <p/>
* Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called
* by the stubbed methods generated by the LayoutLib_create tool.
@@ -82,12 +70,82 @@ public final class OverrideMethod {
* @param isNative True if the method was a native method.
* @param caller The calling object. Null for static methods, "this" for instance methods.
*/
- public static void invoke(String signature, boolean isNative, Object caller) {
+ public static void invokeV(String signature, boolean isNative, Object caller) {
+ MethodListener i = sMethods.get(signature);
+ if (i != null) {
+ i.onInvokeV(signature, isNative, caller);
+ } else if (sDefaultListener != null) {
+ sDefaultListener.onInvokeV(signature, isNative, caller);
+ }
+ }
+
+ /**
+ * Invokes the specific listener for the int return type.
+ * @see #invokeV(String, boolean, Object)
+ */
+ public static int invokeI(String signature, boolean isNative, Object caller) {
+ MethodListener i = sMethods.get(signature);
+ if (i != null) {
+ return i.onInvokeI(signature, isNative, caller);
+ } else if (sDefaultListener != null) {
+ return sDefaultListener.onInvokeI(signature, isNative, caller);
+ }
+ return 0;
+ }
+
+ /**
+ * Invokes the specific listener for the long return type.
+ * @see #invokeV(String, boolean, Object)
+ */
+ public static long invokeL(String signature, boolean isNative, Object caller) {
+ MethodListener i = sMethods.get(signature);
+ if (i != null) {
+ return i.onInvokeL(signature, isNative, caller);
+ } else if (sDefaultListener != null) {
+ return sDefaultListener.onInvokeL(signature, isNative, caller);
+ }
+ return 0;
+ }
+
+ /**
+ * Invokes the specific listener for the float return type.
+ * @see #invokeV(String, boolean, Object)
+ */
+ public static float invokeF(String signature, boolean isNative, Object caller) {
+ MethodListener i = sMethods.get(signature);
+ if (i != null) {
+ return i.onInvokeF(signature, isNative, caller);
+ } else if (sDefaultListener != null) {
+ return sDefaultListener.onInvokeF(signature, isNative, caller);
+ }
+ return 0;
+ }
+
+ /**
+ * Invokes the specific listener for the double return type.
+ * @see #invokeV(String, boolean, Object)
+ */
+ public static double invokeD(String signature, boolean isNative, Object caller) {
+ MethodListener i = sMethods.get(signature);
+ if (i != null) {
+ return i.onInvokeD(signature, isNative, caller);
+ } else if (sDefaultListener != null) {
+ return sDefaultListener.onInvokeD(signature, isNative, caller);
+ }
+ return 0;
+ }
+
+ /**
+ * Invokes the specific listener for the object return type.
+ * @see #invokeV(String, boolean, Object)
+ */
+ public static Object invokeA(String signature, boolean isNative, Object caller) {
MethodListener i = sMethods.get(signature);
if (i != null) {
- i.onInvoke(signature, isNative, caller);
+ return i.onInvokeA(signature, isNative, caller);
} else if (sDefaultListener != null) {
- sDefaultListener.onInvoke(signature, isNative, caller);
+ return sDefaultListener.onInvokeA(signature, isNative, caller);
}
+ return null;
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
index 9bb64bd..9a57a4a 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
@@ -74,23 +74,14 @@ class StubMethodAdapter implements MethodVisitor {
} else {
mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
}
- mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
- "com/android/tools/layoutlib/create/OverrideMethod",
- "invoke",
- "(Ljava/lang/String;ZLjava/lang/Object;)V");
- }
- private void generateReturn() {
- /* Generates one of, depending on the return type:
- * return;
- * return 0;
- * return 0L;
- * return 0.0f;
- * return 0.0;
- * return null;
- */
- switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) {
+ int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID;
+ switch(sort) {
case Type.VOID:
+ mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "com/android/tools/layoutlib/create/OverrideMethod",
+ "invokeV",
+ "(Ljava/lang/String;ZLjava/lang/Object;)V");
mParentVisitor.visitInsn(Opcodes.RETURN);
break;
case Type.BOOLEAN:
@@ -98,27 +89,86 @@ class StubMethodAdapter implements MethodVisitor {
case Type.BYTE:
case Type.SHORT:
case Type.INT:
- mParentVisitor.visitInsn(Opcodes.ICONST_0);
+ mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "com/android/tools/layoutlib/create/OverrideMethod",
+ "invokeI",
+ "(Ljava/lang/String;ZLjava/lang/Object;)I");
+ switch(sort) {
+ case Type.BOOLEAN:
+ Label l1 = new Label();
+ mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1);
+ mParentVisitor.visitInsn(Opcodes.ICONST_1);
+ mParentVisitor.visitInsn(Opcodes.IRETURN);
+ mParentVisitor.visitLabel(l1);
+ mParentVisitor.visitInsn(Opcodes.ICONST_0);
+ break;
+ case Type.CHAR:
+ mParentVisitor.visitInsn(Opcodes.I2C);
+ break;
+ case Type.BYTE:
+ mParentVisitor.visitInsn(Opcodes.I2B);
+ break;
+ case Type.SHORT:
+ mParentVisitor.visitInsn(Opcodes.I2S);
+ break;
+ }
mParentVisitor.visitInsn(Opcodes.IRETURN);
break;
case Type.LONG:
- mParentVisitor.visitInsn(Opcodes.LCONST_0);
+ mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "com/android/tools/layoutlib/create/OverrideMethod",
+ "invokeL",
+ "(Ljava/lang/String;ZLjava/lang/Object;)J");
mParentVisitor.visitInsn(Opcodes.LRETURN);
break;
case Type.FLOAT:
- mParentVisitor.visitInsn(Opcodes.FCONST_0);
+ mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "com/android/tools/layoutlib/create/OverrideMethod",
+ "invokeF",
+ "(Ljava/lang/String;ZLjava/lang/Object;)F");
mParentVisitor.visitInsn(Opcodes.FRETURN);
break;
case Type.DOUBLE:
- mParentVisitor.visitInsn(Opcodes.DCONST_0);
+ mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "com/android/tools/layoutlib/create/OverrideMethod",
+ "invokeD",
+ "(Ljava/lang/String;ZLjava/lang/Object;)D");
mParentVisitor.visitInsn(Opcodes.DRETURN);
break;
case Type.ARRAY:
case Type.OBJECT:
- mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
+ mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "com/android/tools/layoutlib/create/OverrideMethod",
+ "invokeA",
+ "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;");
+ mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
mParentVisitor.visitInsn(Opcodes.ARETURN);
break;
}
+
+ }
+
+ private void generatePop() {
+ /* Pops the stack, depending on the return type.
+ */
+ switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) {
+ case Type.VOID:
+ break;
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ case Type.FLOAT:
+ case Type.ARRAY:
+ case Type.OBJECT:
+ mParentVisitor.visitInsn(Opcodes.POP);
+ break;
+ case Type.LONG:
+ case Type.DOUBLE:
+ mParentVisitor.visitInsn(Opcodes.POP2);
+ break;
+ }
}
/* Pass down to visitor writer. In this implementation, either do nothing. */
@@ -134,7 +184,6 @@ class StubMethodAdapter implements MethodVisitor {
public void visitMaxs(int maxStack, int maxLocals) {
if (!mIsInitMethod && !mMessageGenerated) {
generateInvoke();
- generateReturn();
mMessageGenerated = true;
}
mParentVisitor.visitMaxs(maxStack, maxLocals);
@@ -148,7 +197,6 @@ class StubMethodAdapter implements MethodVisitor {
public void visitEnd() {
if (!mIsInitMethod && !mMessageGenerated) {
generateInvoke();
- generateReturn();
mMessageGenerated = true;
mParentVisitor.visitMaxs(1, 1);
}
@@ -198,10 +246,13 @@ class StubMethodAdapter implements MethodVisitor {
case Opcodes.FRETURN:
case Opcodes.IRETURN:
case Opcodes.LRETURN:
+ // Pop the last word from the stack since invoke will generate its own return.
+ generatePop();
generateInvoke();
mMessageGenerated = true;
+ default:
+ mParentVisitor.visitInsn(opcode);
}
- mParentVisitor.visitInsn(opcode);
}
}
diff --git a/tools/localize/Perforce.cpp b/tools/localize/Perforce.cpp
index 3184dfc..3425668 100644
--- a/tools/localize/Perforce.cpp
+++ b/tools/localize/Perforce.cpp
@@ -1,5 +1,7 @@
#include "Perforce.h"
#include "log.h"
+#include <string.h>
+#include <stdlib.h>
#include <sstream>
#include <sys/types.h>
#include <unistd.h>
diff --git a/tools/localize/XLIFFFile.cpp b/tools/localize/XLIFFFile.cpp
index 5da05a2..51f81de 100644
--- a/tools/localize/XLIFFFile.cpp
+++ b/tools/localize/XLIFFFile.cpp
@@ -1,5 +1,6 @@
#include "XLIFFFile.h"
+#include <algorithm>
#include <sys/time.h>
#include <time.h>
diff --git a/tools/localize/XMLHandler.cpp b/tools/localize/XMLHandler.cpp
index 64af7af..3fab211 100644
--- a/tools/localize/XMLHandler.cpp
+++ b/tools/localize/XMLHandler.cpp
@@ -1,5 +1,6 @@
#include "XMLHandler.h"
+#include <algorithm>
#include <expat.h>
#include <stdio.h>
#include <string.h>
diff --git a/tools/localize/file_utils.cpp b/tools/localize/file_utils.cpp
index 9431709..bb82a9c 100644
--- a/tools/localize/file_utils.cpp
+++ b/tools/localize/file_utils.cpp
@@ -1,3 +1,6 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
#include "file_utils.h"
#include "Perforce.h"
#include <sys/fcntl.h>
diff --git a/tools/localize/localize.cpp b/tools/localize/localize.cpp
index d03c811..c0d84cc 100644
--- a/tools/localize/localize.cpp
+++ b/tools/localize/localize.cpp
@@ -10,6 +10,7 @@
#include <host/pseudolocalize.h>
+#include <stdlib.h>
#include <stdarg.h>
#include <sstream>
#include <stdio.h>