mobile/android/base/util/HardwareUtils.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 package org.mozilla.gecko.util;
michael@0 7
michael@0 8 import android.content.Context;
michael@0 9 import android.content.pm.PackageManager;
michael@0 10 import android.content.res.Configuration;
michael@0 11 import android.os.Build;
michael@0 12 import android.util.Log;
michael@0 13 import android.view.ViewConfiguration;
michael@0 14
michael@0 15 import java.io.FileInputStream;
michael@0 16 import java.io.FileNotFoundException;
michael@0 17 import java.io.IOException;
michael@0 18 import java.util.regex.Matcher;
michael@0 19 import java.util.regex.Pattern;
michael@0 20
michael@0 21 public final class HardwareUtils {
michael@0 22 private static final String LOGTAG = "GeckoHardwareUtils";
michael@0 23
michael@0 24 // Minimum memory threshold for a device to be considered
michael@0 25 // a low memory platform (see isLowMemoryPlatform). This value
michael@0 26 // has be in sync with Gecko's equivalent threshold (defined in
michael@0 27 // xpcom/base/nsMemoryImpl.cpp) and should only be used in cases
michael@0 28 // where we can't depend on Gecko to be up and running e.g. show/hide
michael@0 29 // reading list capabilities in HomePager.
michael@0 30 private static final int LOW_MEMORY_THRESHOLD_MB = 384;
michael@0 31
michael@0 32 // Number of bytes of /proc/meminfo to read in one go.
michael@0 33 private static final int MEMINFO_BUFFER_SIZE_BYTES = 256;
michael@0 34
michael@0 35 private static volatile int sTotalRAM = -1;
michael@0 36
michael@0 37 private static Context sContext;
michael@0 38
michael@0 39 private static Boolean sIsLargeTablet;
michael@0 40 private static Boolean sIsSmallTablet;
michael@0 41 private static Boolean sIsTelevision;
michael@0 42 private static Boolean sHasMenuButton;
michael@0 43
michael@0 44 private HardwareUtils() {
michael@0 45 }
michael@0 46
michael@0 47 public static void init(Context context) {
michael@0 48 if (sContext != null) {
michael@0 49 Log.w(LOGTAG, "HardwareUtils.init called twice!");
michael@0 50 }
michael@0 51 sContext = context;
michael@0 52 }
michael@0 53
michael@0 54 public static boolean isTablet() {
michael@0 55 return isLargeTablet() || isSmallTablet();
michael@0 56 }
michael@0 57
michael@0 58 public static boolean isLargeTablet() {
michael@0 59 if (sIsLargeTablet == null) {
michael@0 60 int screenLayout = sContext.getResources().getConfiguration().screenLayout;
michael@0 61 sIsLargeTablet = (Build.VERSION.SDK_INT >= 11 &&
michael@0 62 ((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE));
michael@0 63 }
michael@0 64 return sIsLargeTablet;
michael@0 65 }
michael@0 66
michael@0 67 public static boolean isSmallTablet() {
michael@0 68 if (sIsSmallTablet == null) {
michael@0 69 int screenLayout = sContext.getResources().getConfiguration().screenLayout;
michael@0 70 sIsSmallTablet = (Build.VERSION.SDK_INT >= 11 &&
michael@0 71 ((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE));
michael@0 72 }
michael@0 73 return sIsSmallTablet;
michael@0 74 }
michael@0 75
michael@0 76 public static boolean isTelevision() {
michael@0 77 if (sIsTelevision == null) {
michael@0 78 sIsTelevision = sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION);
michael@0 79 }
michael@0 80 return sIsTelevision;
michael@0 81 }
michael@0 82
michael@0 83 public static boolean hasMenuButton() {
michael@0 84 if (sHasMenuButton == null) {
michael@0 85 sHasMenuButton = Boolean.TRUE;
michael@0 86 if (Build.VERSION.SDK_INT >= 11) {
michael@0 87 sHasMenuButton = Boolean.FALSE;
michael@0 88 }
michael@0 89 if (Build.VERSION.SDK_INT >= 14) {
michael@0 90 sHasMenuButton = ViewConfiguration.get(sContext).hasPermanentMenuKey();
michael@0 91 }
michael@0 92 }
michael@0 93 return sHasMenuButton;
michael@0 94 }
michael@0 95
michael@0 96 /**
michael@0 97 * Helper functions used to extract key/value data from /proc/meminfo
michael@0 98 * Pulled from:
michael@0 99 * http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/MemInfoReader.java
michael@0 100 */
michael@0 101
michael@0 102 private static boolean matchMemText(byte[] buffer, int index, int bufferLength, byte[] text) {
michael@0 103 final int N = text.length;
michael@0 104 if ((index + N) >= bufferLength) {
michael@0 105 return false;
michael@0 106 }
michael@0 107 for (int i = 0; i < N; i++) {
michael@0 108 if (buffer[index + i] != text[i]) {
michael@0 109 return false;
michael@0 110 }
michael@0 111 }
michael@0 112 return true;
michael@0 113 }
michael@0 114
michael@0 115 /**
michael@0 116 * Parses a line like:
michael@0 117 *
michael@0 118 * MemTotal: 1605324 kB
michael@0 119 *
michael@0 120 * into 1605324.
michael@0 121 *
michael@0 122 * @return the first uninterrupted sequence of digits following the
michael@0 123 * specified index, parsed as an integer value in KB.
michael@0 124 */
michael@0 125 private static int extractMemValue(byte[] buffer, int offset, int length) {
michael@0 126 if (offset >= length) {
michael@0 127 return 0;
michael@0 128 }
michael@0 129
michael@0 130 while (offset < length && buffer[offset] != '\n') {
michael@0 131 if (buffer[offset] >= '0' && buffer[offset] <= '9') {
michael@0 132 int start = offset++;
michael@0 133 while (offset < length &&
michael@0 134 buffer[offset] >= '0' &&
michael@0 135 buffer[offset] <= '9') {
michael@0 136 ++offset;
michael@0 137 }
michael@0 138 return Integer.parseInt(new String(buffer, start, offset - start), 10);
michael@0 139 }
michael@0 140 ++offset;
michael@0 141 }
michael@0 142 return 0;
michael@0 143 }
michael@0 144
michael@0 145 /**
michael@0 146 * Fetch the total memory of the device in MB by parsing /proc/meminfo.
michael@0 147 *
michael@0 148 * Of course, Android doesn't have a neat and tidy way to find total
michael@0 149 * RAM, so we do it by parsing /proc/meminfo.
michael@0 150 *
michael@0 151 * @return 0 if a problem occurred, or memory size in MB.
michael@0 152 */
michael@0 153 public static int getMemSize() {
michael@0 154 if (sTotalRAM >= 0) {
michael@0 155 return sTotalRAM;
michael@0 156 }
michael@0 157
michael@0 158 // This is the string "MemTotal" that we're searching for in the buffer.
michael@0 159 final byte[] MEMTOTAL = {'M', 'e', 'm', 'T', 'o', 't', 'a', 'l'};
michael@0 160 try {
michael@0 161 final byte[] buffer = new byte[MEMINFO_BUFFER_SIZE_BYTES];
michael@0 162 final FileInputStream is = new FileInputStream("/proc/meminfo");
michael@0 163 try {
michael@0 164 final int length = is.read(buffer);
michael@0 165
michael@0 166 for (int i = 0; i < length; i++) {
michael@0 167 if (matchMemText(buffer, i, length, MEMTOTAL)) {
michael@0 168 i += 8;
michael@0 169 sTotalRAM = extractMemValue(buffer, i, length) / 1024;
michael@0 170 Log.d(LOGTAG, "System memory: " + sTotalRAM + "MB.");
michael@0 171 return sTotalRAM;
michael@0 172 }
michael@0 173 }
michael@0 174 } finally {
michael@0 175 is.close();
michael@0 176 }
michael@0 177
michael@0 178 Log.w(LOGTAG, "Did not find MemTotal line in /proc/meminfo.");
michael@0 179 return sTotalRAM = 0;
michael@0 180 } catch (FileNotFoundException f) {
michael@0 181 return sTotalRAM = 0;
michael@0 182 } catch (IOException e) {
michael@0 183 return sTotalRAM = 0;
michael@0 184 }
michael@0 185 }
michael@0 186
michael@0 187 public static boolean isLowMemoryPlatform() {
michael@0 188 final int memSize = getMemSize();
michael@0 189
michael@0 190 // Fallback to false if we fail to read meminfo
michael@0 191 // for some reason.
michael@0 192 if (memSize == 0) {
michael@0 193 Log.w(LOGTAG, "Could not compute system memory. Falling back to isLowMemoryPlatform = false.");
michael@0 194 return false;
michael@0 195 }
michael@0 196
michael@0 197 return memSize < LOW_MEMORY_THRESHOLD_MB;
michael@0 198 }
michael@0 199 }

mercurial