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 : source : d2c14599cbab6c476465a6ba142c7c2501895cb3
This commit is contained in:
Nick Alexander 2014-11-24 15:37:30 -08:00
parent ee0c6abe57
commit 5d43e7f247
7 changed files with 149 additions and 122 deletions

View File

@ -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@";

View File

@ -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 \

View File

@ -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:
*
* <http://stackoverflow.com/questions/7962155/how-can-you-detect-a-dual-core-
* cpu-on-an-android-device-from-code>
*
* 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:
*
* <http://stackoverflow.com/questions/7962155/how-can-you-detect-a-dual-core-
* cpu-on-an-android-device-from-code>
*
* 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;
}
}
/**

View File

@ -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

View File

@ -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',

View File

@ -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() {

View File

@ -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