mobile/android/base/mozglue/GeckoLoader.java.in

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.

     1 #filter substitution
     2 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 package org.mozilla.gecko.mozglue;
     9 import android.content.Context;
    10 import android.content.Intent;
    11 import android.os.Build;
    12 import android.os.Environment;
    13 import android.util.Log;
    15 import java.io.File;
    16 import java.text.DecimalFormat;
    17 import java.text.DecimalFormatSymbols;
    18 import java.text.NumberFormat;
    19 import java.util.Locale;
    21 public final class GeckoLoader {
    22     private static final String LOGTAG = "GeckoLoader";
    24     // This matches AppConstants, but we're built earlier.
    25     private static final String ANDROID_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@";
    27     private static volatile Intent sIntent;
    28     private static File sCacheFile;
    29     private static File sGREDir;
    31     private static final Object sLibLoadingLock = new Object();
    32     // Must hold sLibLoadingLock while accessing the following boolean variables.
    33     private static boolean sSQLiteLibsLoaded;
    34     private static boolean sNSSLibsLoaded;
    35     private static boolean sMozGlueLoaded;
    36     private static boolean sLibsSetup;
    38     private GeckoLoader() {
    39         // prevent instantiation
    40     }
    42     public static File getCacheDir(Context context) {
    43         if (sCacheFile == null) {
    44             sCacheFile = context.getCacheDir();
    45         }
    46         return sCacheFile;
    47     }
    49     public static File getGREDir(Context context) {
    50         if (sGREDir == null) {
    51             sGREDir = new File(context.getApplicationInfo().dataDir);
    52         }
    53         return sGREDir;
    54     }
    56     private static void setupPluginEnvironment(Context context, String[] pluginDirs) {
    57         // setup plugin path directories
    58         try {
    59             // Check to see if plugins were blocked.
    60             if (pluginDirs == null) {
    61                 putenv("MOZ_PLUGINS_BLOCKED=1");
    62                 putenv("MOZ_PLUGIN_PATH=");
    63                 return;
    64             }
    66             StringBuilder pluginSearchPath = new StringBuilder();
    67             for (int i = 0; i < pluginDirs.length; i++) {
    68                 pluginSearchPath.append(pluginDirs[i]);
    69                 pluginSearchPath.append(":");
    70             }
    71             putenv("MOZ_PLUGIN_PATH="+pluginSearchPath);
    73             File pluginDataDir = context.getDir("plugins", 0);
    74             putenv("ANDROID_PLUGIN_DATADIR=" + pluginDataDir.getPath());
    76             File pluginPrivateDataDir = context.getDir("plugins_private", 0);
    77             putenv("ANDROID_PLUGIN_DATADIR_PRIVATE=" + pluginPrivateDataDir.getPath());
    79         } catch (Exception ex) {
    80             Log.w(LOGTAG, "Caught exception getting plugin dirs.", ex);
    81         }
    82     }
    84     private static void setupDownloadEnvironment(Context context) {
    85         try {
    86             File downloadDir = null;
    87             File updatesDir  = null;
    88             if (Build.VERSION.SDK_INT >= 8) {
    89                 downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    90                 updatesDir  = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
    91             }
    92             if (downloadDir == null) {
    93                 downloadDir = new File(Environment.getExternalStorageDirectory().getPath(), "download");
    94             }
    95             if (updatesDir == null) {
    96                 updatesDir = downloadDir;
    97             }
    98             putenv("DOWNLOADS_DIRECTORY=" + downloadDir.getPath());
    99             putenv("UPDATES_DIRECTORY="   + updatesDir.getPath());
   100         }
   101         catch (Exception e) {
   102             Log.w(LOGTAG, "No download directory found.", e);
   103         }
   104     }
   106     private static void delTree(File file) {
   107         if (file.isDirectory()) {
   108             File children[] = file.listFiles();
   109             for (File child : children) {
   110                 delTree(child);
   111             }
   112         }
   113         file.delete();
   114     }
   116     private static File getTmpDir(Context context) {
   117         File tmpDir = context.getDir("tmpdir", Context.MODE_PRIVATE);
   118         // check if the old tmp dir is there
   119         File oldDir = new File(tmpDir.getParentFile(), "app_tmp");
   120         if (oldDir.exists()) {
   121             delTree(oldDir);
   122         }
   123         return tmpDir;
   124     }
   126     public static void setLastIntent(Intent intent) {
   127         sIntent = intent;
   128     }
   130     public static void setupGeckoEnvironment(Context context, String[] pluginDirs, String profilePath) {
   131         // if we have an intent (we're being launched by an activity)
   132         // read in any environmental variables from it here
   133         final Intent intent = sIntent;
   134         if (intent != null) {
   135             String env = intent.getStringExtra("env0");
   136             Log.d(LOGTAG, "Gecko environment env0: " + env);
   137             for (int c = 1; env != null; c++) {
   138                 putenv(env);
   139                 env = intent.getStringExtra("env" + c);
   140                 Log.d(LOGTAG, "env" + c + ": " + env);
   141             }
   142         }
   144         setupPluginEnvironment(context, pluginDirs);
   145         setupDownloadEnvironment(context);
   147         // profile home path
   148         putenv("HOME=" + profilePath);
   150         // setup the tmp path
   151         File f = getTmpDir(context);
   152         if (!f.exists()) {
   153             f.mkdirs();
   154         }
   155         putenv("TMPDIR=" + f.getPath());
   157         // setup the downloads path
   158         f = Environment.getDownloadCacheDirectory();
   159         putenv("EXTERNAL_STORAGE=" + f.getPath());
   161         // setup the app-specific cache path
   162         f = context.getCacheDir();
   163         putenv("CACHE_DIRECTORY=" + f.getPath());
   165         /* We really want to use this code, but it requires bumping up the SDK to 17 so for now
   166            we will use reflection. See https://bugzilla.mozilla.org/show_bug.cgi?id=811763#c11
   168         if (Build.VERSION.SDK_INT >= 17) {
   169             android.os.UserManager um = (android.os.UserManager)context.getSystemService(Context.USER_SERVICE);
   170             if (um != null) {
   171                 putenv("MOZ_ANDROID_USER_SERIAL_NUMBER=" + um.getSerialNumberForUser(android.os.Process.myUserHandle()));
   172             } else {
   173                 Log.d(LOGTAG, "Unable to obtain user manager service on a device with SDK version " + Build.VERSION.SDK_INT);
   174             }
   175         }
   176         */
   177         try {
   178             Object userManager = context.getSystemService("user");
   179             if (userManager != null) {
   180                 // if userManager is non-null that means we're running on 4.2+ and so the rest of this
   181                 // should just work
   182                 Object userHandle = android.os.Process.class.getMethod("myUserHandle", (Class[])null).invoke(null);
   183                 Object userSerial = userManager.getClass().getMethod("getSerialNumberForUser", userHandle.getClass()).invoke(userManager, userHandle);
   184                 putenv("MOZ_ANDROID_USER_SERIAL_NUMBER=" + userSerial.toString());
   185             }
   186         } catch (Exception e) {
   187             // Guard against any unexpected failures
   188             Log.d(LOGTAG, "Unable to set the user serial number", e);
   189         }
   191         setupLocaleEnvironment();
   193         // We don't need this any more.
   194         sIntent = null;
   195     }
   197     private static void loadLibsSetup(Context context) {
   198         synchronized (sLibLoadingLock) {
   199             if (sLibsSetup) {
   200                 return;
   201             }
   202             sLibsSetup = true;
   203         }
   205         // The package data lib directory isn't placed in ld.so's
   206         // search path, so we have to manually load libraries that
   207         // libxul will depend on.  Not ideal.
   209         File cacheFile = getCacheDir(context);
   210         putenv("GRE_HOME=" + getGREDir(context).getPath());
   212         // setup the libs cache
   213         String linkerCache = System.getenv("MOZ_LINKER_CACHE");
   214         if (linkerCache == null) {
   215             linkerCache = cacheFile.getPath();
   216             putenv("MOZ_LINKER_CACHE=" + linkerCache);
   217         }
   219         // Disable on-demand decompression of the linker on devices where it
   220         // is known to cause crashes.
   221         if ("HTC".equals(android.os.Build.MANUFACTURER) &&
   222             "HTC Vision".equals(android.os.Build.MODEL)) {
   223             putenv("MOZ_LINKER_ONDEMAND=0");
   224         }
   226 #ifdef MOZ_LINKER_EXTRACT
   227         putenv("MOZ_LINKER_EXTRACT=1");
   228         // Ensure that the cache dir is world-writable
   229         File cacheDir = new File(linkerCache);
   230         if (cacheDir.isDirectory()) {
   231             cacheDir.setWritable(true, false);
   232             cacheDir.setExecutable(true, false);
   233             cacheDir.setReadable(true, false);
   234         }
   235 #endif
   236     }
   238     @RobocopTarget
   239     public static void loadSQLiteLibs(Context context, String apkName) {
   240         synchronized (sLibLoadingLock) {
   241             if (sSQLiteLibsLoaded) {
   242                 return;
   243             }
   244             sSQLiteLibsLoaded = true;
   245         }
   247         loadMozGlue();
   248         // the extract libs parameter is being removed in bug 732069
   249         loadLibsSetup(context);
   250         loadSQLiteLibsNative(apkName, false);
   251     }
   253     public static void loadNSSLibs(Context context, String apkName) {
   254         synchronized (sLibLoadingLock) {
   255             if (sNSSLibsLoaded) {
   256                 return;
   257             }
   258             sNSSLibsLoaded = true;
   259         }
   261         loadMozGlue();
   262         loadLibsSetup(context);
   263         loadNSSLibsNative(apkName, false);
   264     }
   266     public static void doLoadLibrary(final String lib) {
   267         try {
   268             System.loadLibrary(lib);
   269         } catch (UnsatisfiedLinkError e) {
   270             Log.wtf(LOGTAG, "Couldn't load " + lib + ". Trying /data/app-lib path.");
   271             try {
   272                 System.load("/data/app-lib/" + ANDROID_PACKAGE_NAME + "/lib" + lib + ".so");
   273             } catch (Throwable ee) {
   274                 try {
   275                     Log.wtf(LOGTAG, "Couldn't load " + lib + ": " + ee + ". Trying /data/data path.");
   276                     System.load("/data/data/" + ANDROID_PACKAGE_NAME + "/lib/lib" + lib + ".so");
   277                 } catch (Throwable eee) {
   278                     Log.wtf(LOGTAG, "Failed every attempt to load " + lib + ". Giving up.");
   279                     throw new RuntimeException("Unable to load " + lib, eee);
   280                 }
   281             }
   282         }
   283     }
   285     public static void loadMozGlue() {
   286         synchronized (sLibLoadingLock) {
   287             if (sMozGlueLoaded) {
   288                 return;
   289             }
   290             sMozGlueLoaded = true;
   291         }
   293         doLoadLibrary("mozglue");
   294     }
   296     public static void loadGeckoLibs(Context context, String apkName) {
   297         loadLibsSetup(context);
   298         loadGeckoLibsNative(apkName);
   299     }
   301     private static void setupLocaleEnvironment() {
   302         putenv("LANG=" + Locale.getDefault().toString());
   303         NumberFormat nf = NumberFormat.getInstance();
   304         if (nf instanceof DecimalFormat) {
   305             DecimalFormat df = (DecimalFormat)nf;
   306             DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
   308             putenv("LOCALE_DECIMAL_POINT=" + dfs.getDecimalSeparator());
   309             putenv("LOCALE_THOUSANDS_SEP=" + dfs.getGroupingSeparator());
   310             putenv("LOCALE_GROUPING=" + (char)df.getGroupingSize());
   311         }
   312     }
   314     // These methods are implemented in mozglue/android/nsGeckoUtils.cpp
   315     private static native void putenv(String map);
   317     // These methods are implemented in mozglue/android/APKOpen.cpp
   318     public static native void nativeRun(String args);
   319     private static native void loadGeckoLibsNative(String apkName);
   320     private static native void loadSQLiteLibsNative(String apkName, boolean shouldExtract);
   321     private static native void loadNSSLibsNative(String apkName, boolean shouldExtract);
   322 }

mercurial