mobile/android/base/util/HardwareUtils.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial