From cdd980f48087cf2fbe9a81c2f9f464719927d98c Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Mon, 24 Nov 2014 15:37:30 -0800 Subject: [PATCH] Bug 1102488 - Part 1: Factor out constants JAR. r=rnewman The constants JAR contains AppConstants and SysInfo. SysInfo depended on HardwareUtils for one function, which can (should?) be in SysInfo anyway, so I moved it. Both SysInfo and AppConstants should be available to Robocop tests, but they are compiled too early to access RobocopTarget. Since nothing in GeckoView should know about GeckoView, I moved the annotation to the Fennec-level proguard.cfg. --HG-- extra : rebase_source : cdba5f056a41ec28f190dd7ebf82213a358cb3a8 extra : source : d2c14599cbab6c476465a6ba142c7c2501895cb3 --- mobile/android/base/AppConstants.java.in | 9 +- mobile/android/base/Makefile.in | 5 +- mobile/android/base/SysInfo.java.in | 129 +++++++++++++++++--- mobile/android/base/geckoview.ddf | 1 + mobile/android/base/moz.build | 22 +++- mobile/android/base/util/HardwareUtils.java | 97 +-------------- mobile/android/config/proguard.cfg | 8 ++ 7 files changed, 149 insertions(+), 122 deletions(-) diff --git a/mobile/android/base/AppConstants.java.in b/mobile/android/base/AppConstants.java.in index a438564aaeaf..5e8b9660bb63 100644 --- a/mobile/android/base/AppConstants.java.in +++ b/mobile/android/base/AppConstants.java.in @@ -6,10 +6,11 @@ package org.mozilla.gecko; -import org.mozilla.gecko.mozglue.RobocopTarget; - import android.os.Build; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * A collection of constants that pertain to the build and runtime state of the * application. Typically these are sourced from build-time definitions (see @@ -19,7 +20,9 @@ import android.os.Build; * See also SysInfo.java, which includes some of the values available from * nsSystemInfo inside Gecko. */ -@RobocopTarget +// Normally, we'd annotate with @RobocopTarget. Since AppConstants is compiled +// before RobocopTarget, we instead add o.m.g.AppConstants directly to the +// Proguard configuration. public class AppConstants { public static final String ANDROID_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@"; public static final String MANGLED_ANDROID_PACKAGE_NAME = "@MANGLED_ANDROID_PACKAGE_NAME@"; diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 6d398041e3f1..5b767a66c787 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -79,6 +79,7 @@ endif JAVA_CLASSPATH := $(subst $(NULL) ,:,$(strip $(JAVA_CLASSPATH))) ALL_JARS = \ + constants.jar \ gecko-R.jar \ gecko-browser.jar \ gecko-mozglue.jar \ @@ -151,7 +152,7 @@ classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar # outputs are fresher than the target, preventing a subsequent # invocation from thinking Proguard's outputs are stale. This is safe # because Make removes the target file if any recipe command fails. -.proguard.deps: .geckoview.deps $(ALL_JARS) +.proguard.deps: .geckoview.deps $(ALL_JARS) $(topsrcdir)/mobile/android/config/proguard.cfg $(REPORT_BUILD) @$(TOUCH) $@ java \ @@ -194,7 +195,7 @@ GeneratedJNIWrappers.cpp: $(ALL_JARS) # These _PP_JAVAFILES are specified in moz.build and defined in # backend.mk, which is included by config.mk. Therefore this needs to # be defined after config.mk is included. -PP_JAVAFILES := $(filter-out generated/org/mozilla/gecko/R.java,$(gecko-mozglue_PP_JAVAFILES) $(gecko-browser_PP_JAVAFILES)) +PP_JAVAFILES := $(filter-out generated/org/mozilla/gecko/R.java,$(gecko-mozglue_PP_JAVAFILES) $(gecko-browser_PP_JAVAFILES) $(constants_PP_JAVAFILES)) manifest := \ AndroidManifest.xml.in \ diff --git a/mobile/android/base/SysInfo.java.in b/mobile/android/base/SysInfo.java.in index f5c07302ebc8..83e9d15ea689 100644 --- a/mobile/android/base/SysInfo.java.in +++ b/mobile/android/base/SysInfo.java.in @@ -6,13 +6,17 @@ package org.mozilla.gecko; -import org.mozilla.gecko.util.HardwareUtils; - import android.os.StrictMode; import android.util.Log; import java.io.File; import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.regex.Pattern; @@ -21,27 +25,35 @@ import java.util.regex.Pattern; * nsSystemInfo. See also the constants in AppConstants, which reflect * much of nsIXULAppInfo. */ +// Normally, we'd annotate with @RobocopTarget. Since SysInfo is compiled +// before RobocopTarget, we instead add o.m.g.SysInfo directly to the Proguard +// configuration. public final class SysInfo { private static final String LOG_TAG = "GeckoSysInfo"; + // Number of bytes of /proc/meminfo to read in one go. + private static final int MEMINFO_BUFFER_SIZE_BYTES = 256; + // We don't mind an instant of possible duplicate work, we only wish to // avoid inconsistency, so we don't bother with synchronization for // these. private static volatile int cpuCount = -1; - /** - * Get the number of cores on the device. - * - * We can't use a nice tidy API call, because they're all wrong: - * - * - * - * This method is based on that code. - * - * @return the number of CPU cores, or 1 if the number could not be - * determined. - */ + private static volatile int totalRAM = -1; + + /** + * Get the number of cores on the device. + * + * We can't use a nice tidy API call, because they're all wrong: + * + * + * + * This method is based on that code. + * + * @return the number of CPU cores, or 1 if the number could not be + * determined. + */ public static int getCPUCount() { if (cpuCount > 0) { return cpuCount; @@ -73,10 +85,93 @@ public final class SysInfo { } /** - * Wraps HardwareUtils so callers don't need to know about it. + * Helper functions used to extract key/value data from /proc/meminfo + * Pulled from: + * http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/MemInfoReader.java + */ + private static boolean matchMemText(byte[] buffer, int index, int bufferLength, byte[] text) { + final int N = text.length; + if ((index + N) >= bufferLength) { + return false; + } + for (int i = 0; i < N; i++) { + if (buffer[index + i] != text[i]) { + return false; + } + } + return true; + } + + /** + * Parses a line like: + * + * MemTotal: 1605324 kB + * + * into 1605324. + * + * @return the first uninterrupted sequence of digits following the + * specified index, parsed as an integer value in KB. + */ + private static int extractMemValue(byte[] buffer, int offset, int length) { + if (offset >= length) { + return 0; + } + + while (offset < length && buffer[offset] != '\n') { + if (buffer[offset] >= '0' && buffer[offset] <= '9') { + int start = offset++; + while (offset < length && + buffer[offset] >= '0' && + buffer[offset] <= '9') { + ++offset; + } + return Integer.parseInt(new String(buffer, start, offset - start), 10); + } + ++offset; + } + return 0; + } + + /** + * Fetch the total memory of the device in MB by parsing /proc/meminfo. + * + * Of course, Android doesn't have a neat and tidy way to find total + * RAM, so we do it by parsing /proc/meminfo. + * + * @return 0 if a problem occurred, or memory size in MB. */ public static int getMemSize() { - return HardwareUtils.getMemSize(); + if (totalRAM >= 0) { + return totalRAM; + } + + // This is the string "MemTotal" that we're searching for in the buffer. + final byte[] MEMTOTAL = {'M', 'e', 'm', 'T', 'o', 't', 'a', 'l'}; + try { + final byte[] buffer = new byte[MEMINFO_BUFFER_SIZE_BYTES]; + final FileInputStream is = new FileInputStream("/proc/meminfo"); + try { + final int length = is.read(buffer); + + for (int i = 0; i < length; i++) { + if (matchMemText(buffer, i, length, MEMTOTAL)) { + i += 8; + totalRAM = extractMemValue(buffer, i, length) / 1024; + Log.d(LOG_TAG, "System memory: " + totalRAM + "MB."); + return totalRAM; + } + } + } finally { + is.close(); + } + + Log.w(LOG_TAG, "Did not find MemTotal line in /proc/meminfo."); + return totalRAM = 0; + } catch (FileNotFoundException f) { + return totalRAM = 0; + } catch (IOException e) { + return totalRAM = 0; + } } /** diff --git a/mobile/android/base/geckoview.ddf b/mobile/android/base/geckoview.ddf index 1c3bb98a5989..9df47e3c9c52 100644 --- a/mobile/android/base/geckoview.ddf +++ b/mobile/android/base/geckoview.ddf @@ -40,6 +40,7 @@ show allResults org.mozilla.gecko.PrefsHelper \ org.mozilla.gecko.SmsManager \ org.mozilla.gecko.SurfaceBits \ + org.mozilla.gecko.SysInfo \ org.mozilla.gecko.TouchEventInterceptor \ org.mozilla.gecko.ZoomConstraints diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index ef964a658896..2e33c566227d 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -11,6 +11,13 @@ include('android-services.mozbuild') thirdparty_source_dir = TOPSRCDIR + '/mobile/android/thirdparty/' +constants_jar = add_java_jar('constants') +constants_jar.sources = [] +constants_jar.generated_sources = [ + 'org/mozilla/gecko/AppConstants.java', + 'org/mozilla/gecko/SysInfo.java', +] + resjar = add_java_jar('gecko-R') resjar.sources = [] resjar.generated_sources += [ @@ -39,9 +46,11 @@ mgjar.sources += [ 'mozglue/WebRTCJNITarget.java', ] mgjar.generated_sources += [ - 'org/mozilla/gecko/AppConstants.java', 'org/mozilla/gecko/mozglue/GeckoLoader.java', ] +mgjar.extra_jars += [ + 'constants.jar', +] mgjar.javac_flags += ['-Xlint:all'] gujar = add_java_jar('gecko-util') @@ -77,7 +86,8 @@ gujar.sources += [ 'util/WebActivityMapper.java', ] gujar.extra_jars = [ - 'gecko-mozglue.jar' + 'constants.jar', + 'gecko-mozglue.jar', ] gujar.javac_flags += ['-Xlint:all,-deprecation'] @@ -499,8 +509,9 @@ gbjar.sources += [ thirdparty_source_dir + f for f in [ 'com/googlecode/eyesfree/braille/selfbraille/WriteData.java', ] ] android_package_dir = CONFIG['ANDROID_PACKAGE_NAME'].replace('.', '/') -gbjar.generated_sources += [ - 'org/mozilla/gecko/SysInfo.java', +gbjar.generated_sources = [] # Keep it this way. +gbjar.extra_jars += [ + 'constants.jar' ] if CONFIG['MOZ_CRASHREPORTER']: gbjar.sources += [ 'CrashReporter.java' ] @@ -540,7 +551,7 @@ if CONFIG['MOZ_ANDROID_NEW_TABLET_UI'] and max_sdk_version >= 11: gbjar.sources += sync_java_files gbjar.generated_sources += sync_generated_java_files -gbjar.extra_jars = [ +gbjar.extra_jars += [ 'gecko-R.jar', 'gecko-mozglue.jar', 'gecko-thirdparty.jar', @@ -686,6 +697,7 @@ if CONFIG['MOZ_ANDROID_SEARCH_ACTIVITY']: search_activity.sources += [search_source_dir + '/' + f for f in search_activity_sources] search_activity.javac_flags += ['-Xlint:all'] search_activity.extra_jars = [ + 'constants.jar', 'gecko-R.jar', 'gecko-browser.jar', 'gecko-mozglue.jar', diff --git a/mobile/android/base/util/HardwareUtils.java b/mobile/android/base/util/HardwareUtils.java index 149f4b2d7b65..c9a2598cac65 100644 --- a/mobile/android/base/util/HardwareUtils.java +++ b/mobile/android/base/util/HardwareUtils.java @@ -5,9 +5,7 @@ package org.mozilla.gecko.util; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; +import org.mozilla.gecko.SysInfo; import android.content.Context; import android.content.pm.PackageManager; @@ -27,14 +25,10 @@ public final class HardwareUtils { // reading list capabilities in HomePager. private static final int LOW_MEMORY_THRESHOLD_MB = 384; - // Number of bytes of /proc/meminfo to read in one go. - private static final int MEMINFO_BUFFER_SIZE_BYTES = 256; - private static final boolean IS_AMAZON_DEVICE = Build.MANUFACTURER.equalsIgnoreCase("Amazon"); public static final boolean IS_KINDLE_DEVICE = IS_AMAZON_DEVICE && (Build.MODEL.equals("Kindle Fire") || Build.MODEL.startsWith("KF")); - private static volatile int sTotalRAM = -1; private static volatile boolean sInited; @@ -99,95 +93,8 @@ public final class HardwareUtils { return sHasMenuButton; } - /** - * Helper functions used to extract key/value data from /proc/meminfo - * Pulled from: - * http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/MemInfoReader.java - */ - - private static boolean matchMemText(byte[] buffer, int index, int bufferLength, byte[] text) { - final int N = text.length; - if ((index + N) >= bufferLength) { - return false; - } - for (int i = 0; i < N; i++) { - if (buffer[index + i] != text[i]) { - return false; - } - } - return true; - } - - /** - * Parses a line like: - * - * MemTotal: 1605324 kB - * - * into 1605324. - * - * @return the first uninterrupted sequence of digits following the - * specified index, parsed as an integer value in KB. - */ - private static int extractMemValue(byte[] buffer, int offset, int length) { - if (offset >= length) { - return 0; - } - - while (offset < length && buffer[offset] != '\n') { - if (buffer[offset] >= '0' && buffer[offset] <= '9') { - int start = offset++; - while (offset < length && - buffer[offset] >= '0' && - buffer[offset] <= '9') { - ++offset; - } - return Integer.parseInt(new String(buffer, start, offset - start), 10); - } - ++offset; - } - return 0; - } - - /** - * Fetch the total memory of the device in MB by parsing /proc/meminfo. - * - * Of course, Android doesn't have a neat and tidy way to find total - * RAM, so we do it by parsing /proc/meminfo. - * - * @return 0 if a problem occurred, or memory size in MB. - */ public static int getMemSize() { - if (sTotalRAM >= 0) { - return sTotalRAM; - } - - // This is the string "MemTotal" that we're searching for in the buffer. - final byte[] MEMTOTAL = {'M', 'e', 'm', 'T', 'o', 't', 'a', 'l'}; - try { - final byte[] buffer = new byte[MEMINFO_BUFFER_SIZE_BYTES]; - final FileInputStream is = new FileInputStream("/proc/meminfo"); - try { - final int length = is.read(buffer); - - for (int i = 0; i < length; i++) { - if (matchMemText(buffer, i, length, MEMTOTAL)) { - i += 8; - sTotalRAM = extractMemValue(buffer, i, length) / 1024; - Log.d(LOGTAG, "System memory: " + sTotalRAM + "MB."); - return sTotalRAM; - } - } - } finally { - is.close(); - } - - Log.w(LOGTAG, "Did not find MemTotal line in /proc/meminfo."); - return sTotalRAM = 0; - } catch (FileNotFoundException f) { - return sTotalRAM = 0; - } catch (IOException e) { - return sTotalRAM = 0; - } + return SysInfo.getMemSize(); } public static boolean isLowMemoryPlatform() { diff --git a/mobile/android/config/proguard.cfg b/mobile/android/config/proguard.cfg index 73736e979b17..d84996dea45f 100644 --- a/mobile/android/config/proguard.cfg +++ b/mobile/android/config/proguard.cfg @@ -194,6 +194,14 @@ -keep class **.R$* +# Keep classes, and all their contents, compiled before mozglue.RobocopTarget. +-keep class org.mozilla.gecko.AppConstants { + *; +} +-keep class org.mozilla.gecko.SysInfo { + *; +} + # Disable obfuscation because it makes exception stack traces more difficult to read. -dontobfuscate