Bug 937945 - Don't store Context in GeckoProfile. r=rnewman
authorBrian Nicholson <bnicholson@mozilla.com>
Fri, 15 Nov 2013 22:53:53 -0800
changeset 155004 000ac7f90a40a17e3932f9e2f3d6cc8f8f7fee21
parent 155003 2423cb6ee914f79ea6f665d8beb43bc3bd9a18e2
child 155005 43549d3c33331d197ee534a9bf3eb894ddc6ca2e
push id25658
push userMs2ger@gmail.com
push dateSun, 17 Nov 2013 13:28:01 +0000
treeherdermozilla-central@99084b22e38d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs937945
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 937945 - Don't store Context in GeckoProfile. r=rnewman
mobile/android/base/GeckoProfile.java
mobile/android/base/GeckoThread.java
--- a/mobile/android/base/GeckoProfile.java
+++ b/mobile/android/base/GeckoProfile.java
@@ -2,17 +2,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import org.mozilla.gecko.util.INIParser;
 import org.mozilla.gecko.util.INISection;
-import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileReader;
@@ -26,20 +25,18 @@ import java.util.Hashtable;
 public final class GeckoProfile {
     private static final String LOGTAG = "GeckoProfile";
     // Used to "lock" the guest profile, so that we'll always restart in it
     private static final String LOCK_FILE_NAME = ".active_lock";
 
     private static HashMap<String, GeckoProfile> sProfileCache = new HashMap<String, GeckoProfile>();
     private static String sDefaultProfileName = null;
 
-    private final Context mContext;
     private final String mName;
-    private File mMozDir;
-    private File mDir;
+    private File mProfileDir;
     public static boolean sIsUsingCustomProfile = false;
 
     // Constants to cache whether or not a profile is "locked".
     private enum LockState {
         LOCKED,
         UNLOCKED,
         UNDEFINED
     };
@@ -48,21 +45,22 @@ public final class GeckoProfile {
     private LockState mLocked = LockState.UNDEFINED;
 
     // Caches the guest profile dir
     private static File mGuestDir = null;
 
     private boolean mInGuestMode = false;
     private static GeckoProfile mGuestProfile = null;
 
-    static private INIParser getProfilesINI(Context context) {
-      File filesDir = context.getFilesDir();
-      File mozillaDir = new File(filesDir, "mozilla");
-      File profilesIni = new File(mozillaDir, "profiles.ini");
-      return new INIParser(profilesIni);
+    private static final String MOZILLA_DIR_NAME = "mozilla";
+    private static File sMozillaDir;
+
+    private static INIParser getProfilesINI(File mozillaDir) {
+        File profilesIni = new File(mozillaDir, "profiles.ini");
+        return new INIParser(profilesIni);
     }
 
     public static GeckoProfile get(Context context) {
         boolean isGeckoApp = false;
         try {
             isGeckoApp = context instanceof GeckoApp;
         } catch (NoClassDefFoundError ex) {}
         
@@ -117,36 +115,35 @@ public final class GeckoProfile {
             if (profileName == null)
                 profileName = "default";
         }
 
         // actually try to look up the profile
         synchronized (sProfileCache) {
             GeckoProfile profile = sProfileCache.get(profileName);
             if (profile == null) {
-                profile = new GeckoProfile(context, profileName, profileDir);
+                profile = new GeckoProfile(context, profileName);
+                profile.setDir(profileDir);
                 sProfileCache.put(profileName, profile);
             } else {
                 profile.setDir(profileDir);
             }
             return profile;
         }
     }
 
-    public static File ensureMozillaDirectory(Context context) throws IOException {
-        synchronized (context) {
-            File filesDir = context.getFilesDir();
-            File mozDir = new File(filesDir, "mozilla");
-            if (! mozDir.exists()) {
-                if (! mozDir.mkdirs()) {
-                    throw new IOException("Unable to create mozilla directory at " + mozDir.getAbsolutePath());
-                }
-            }
-            return mozDir;
+    private static File getMozillaDirectory(Context context) {
+        return new File(context.getFilesDir(), MOZILLA_DIR_NAME);
+    }
+
+    private synchronized File ensureMozillaDirectory() throws IOException {
+        if (sMozillaDir.exists() || sMozillaDir.mkdirs()) {
+            return sMozillaDir;
         }
+        throw new IOException("Unable to create mozilla directory at " + sMozillaDir.getAbsolutePath());
     }
 
     public static boolean removeProfile(Context context, String profileName) {
         return new GeckoProfile(context, profileName).remove();
     }
 
     public static GeckoProfile createGuestProfile(Context context) {
         try {
@@ -236,18 +233,18 @@ public final class GeckoProfile {
 
     // Warning, Changing the lock file state from outside apis will cause this to become out of sync
     public boolean locked() {
         if (mLocked != LockState.UNDEFINED) {
             return mLocked == LockState.LOCKED;
         }
 
         // Don't use getDir() as it will create a dir if none exists
-        if (mDir != null && mDir.exists()) {
-            File lockFile = new File(mDir, LOCK_FILE_NAME);
+        if (mProfileDir != null && mProfileDir.exists()) {
+            File lockFile = new File(mProfileDir, LOCK_FILE_NAME);
             boolean res = lockFile.exists();
             mLocked = res ? LockState.LOCKED : LockState.UNLOCKED;
         } else {
             mLocked = LockState.UNLOCKED;
         }
 
         return mLocked == LockState.LOCKED;
     }
@@ -267,101 +264,93 @@ public final class GeckoProfile {
             Log.e(LOGTAG, "Error locking profile", ex);
         }
         mLocked = LockState.UNLOCKED;
         return false;
     }
 
     public boolean unlock() {
         // Don't use getDir() as it will create a dir
-        if (mDir == null || !mDir.exists()) {
+        if (mProfileDir == null || !mProfileDir.exists()) {
             return true;
         }
 
         try {
-            File lockFile = new File(mDir, LOCK_FILE_NAME);
+            File lockFile = new File(mProfileDir, LOCK_FILE_NAME);
             boolean result = delete(lockFile);
             if (result) {
                 mLocked = LockState.UNLOCKED;
             } else {
                 mLocked = LockState.LOCKED;
             }
             return result;
         } catch(IOException ex) {
             Log.e(LOGTAG, "Error unlocking profile", ex);
         }
         mLocked = LockState.LOCKED;
         return false;
     }
 
     private GeckoProfile(Context context, String profileName) {
-        mContext = context;
         mName = profileName;
-    }
-
-    private GeckoProfile(Context context, String profileName, File profileDir) {
-        mContext = context;
-        mName = profileName;
-        setDir(profileDir);
+        if (sMozillaDir == null) {
+            sMozillaDir = getMozillaDirectory(context);
+        }
     }
 
     public boolean inGuestMode() {
         return mInGuestMode;
     }
 
     private void setDir(File dir) {
         if (dir != null && dir.exists() && dir.isDirectory()) {
-            mDir = dir;
+            mProfileDir = dir;
         } else {
             Log.w(LOGTAG, "requested profile directory missing: " + dir);
         }
     }
 
     public String getName() {
         return mName;
     }
 
     public synchronized File getDir() {
         forceCreate();
-        return mDir;
+        return mProfileDir;
     }
 
     public synchronized GeckoProfile forceCreate() {
-        if (mDir != null) {
+        if (mProfileDir != null) {
             return this;
         }
 
         try {
             // Check if a profile with this name already exists.
-            File mozillaDir = ensureMozillaDirectory(mContext);
-            mDir = findProfileDir(mozillaDir);
-            if (mDir == null) {
+            File mozillaDir = ensureMozillaDirectory();
+            mProfileDir = findProfileDir(mozillaDir);
+            if (mProfileDir == null) {
                 // otherwise create it
-                mDir = createProfileDir(mozillaDir);
+                mProfileDir = createProfileDir(mozillaDir);
             } else {
-                Log.d(LOGTAG, "Found profile dir: " + mDir.getAbsolutePath());
+                Log.d(LOGTAG, "Found profile dir: " + mProfileDir.getAbsolutePath());
             }
         } catch (IOException ioe) {
             Log.e(LOGTAG, "Error getting profile dir", ioe);
         }
         return this;
     }
 
     public File getFile(String aFile) {
         File f = getDir();
         if (f == null)
             return null;
 
         return new File(f, aFile);
     }
 
-    public File getFilesDir() {
-        return mContext.getFilesDir();
-    }
-
     /**
      * Moves the session file to the backup session file.
      *
      * sessionstore.js should hold the current session, and sessionstore.bak
      * should hold the previous session (where it is used to read the "tabs
      * from last time"). Normally, sessionstore.js is moved to sessionstore.bak
      * on a clean quit, but this doesn't happen if Fennec crashed. Thus, this
      * method should be called after a crash so sessionstore.bak correctly
@@ -426,23 +415,23 @@ public final class GeckoProfile {
     }
 
     private boolean remove() {
         try {
             File dir = getDir();
             if (dir.exists())
                 delete(dir);
 
-            File mozillaDir = ensureMozillaDirectory(mContext);
-            mDir = findProfileDir(mozillaDir);
-            if (mDir == null) {
+            File mozillaDir = ensureMozillaDirectory();
+            mProfileDir = findProfileDir(mozillaDir);
+            if (mProfileDir == null) {
                 return false;
             }
 
-            INIParser parser = getProfilesINI(mContext);
+            INIParser parser = getProfilesINI(mozillaDir);
 
             Hashtable<String, INISection> sections = parser.getSections();
             for (Enumeration<INISection> e = sections.elements(); e.hasMoreElements();) {
                 INISection section = e.nextElement();
                 String name = section.getStringProperty("Name");
 
                 if (name == null || !name.equals(mName))
                     continue;
@@ -487,32 +476,32 @@ public final class GeckoProfile {
         // Have we read the default profile from the INI already?
         // Changing the default profile requires a restart, so we don't
         // need to worry about runtime changes.
         if (sDefaultProfileName != null) {
             return sDefaultProfileName;
         }
 
         // Open profiles.ini to find the correct path
-        INIParser parser = getProfilesINI(context);
+        INIParser parser = getProfilesINI(getMozillaDirectory(context));
 
         for (Enumeration<INISection> e = parser.getSections().elements(); e.hasMoreElements();) {
             INISection section = e.nextElement();
             if (section.getIntProperty("Default") == 1) {
                 sDefaultProfileName = section.getStringProperty("Name");
                 return sDefaultProfileName;
             }
         }
 
         return null;
     }
 
     private File findProfileDir(File mozillaDir) {
         // Open profiles.ini to find the correct path
-        INIParser parser = getProfilesINI(mContext);
+        INIParser parser = getProfilesINI(mozillaDir);
 
         for (Enumeration<INISection> e = parser.getSections().elements(); e.hasMoreElements();) {
             INISection section = e.nextElement();
             String name = section.getStringProperty("Name");
             if (name != null && name.equals(mName)) {
                 if (section.getIntProperty("IsRelative") == 1) {
                     return new File(mozillaDir, section.getStringProperty("Path"));
                 }
@@ -530,17 +519,17 @@ public final class GeckoProfile {
             salt.append(allowedChars.charAt((int)(Math.random() * allowedChars.length())));
         }
         salt.append('.');
         salt.append(name);
         return salt.toString();
     }
 
     private File createProfileDir(File mozillaDir) throws IOException {
-        INIParser parser = getProfilesINI(mContext);
+        INIParser parser = getProfilesINI(mozillaDir);
 
         // Salt the name of our requested profile
         String saltedName = saltProfileName(mName);
         File profileDir = new File(mozillaDir, saltedName);
         while (profileDir.exists()) {
             saltedName = saltProfileName(mName);
             profileDir = new File(mozillaDir, saltedName);
         }
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -104,17 +104,17 @@ public class GeckoThread extends Thread 
         } catch (Exception e) {
             Log.w(LOGTAG, "Caught exception getting plugin dirs.", e);
         }
         
         if (app instanceof Activity) {
             Activity activity = (Activity)app;
             resourcePath = activity.getApplication().getPackageResourcePath();
             res = activity.getBaseContext().getResources();
-            GeckoLoader.setupGeckoEnvironment(activity, pluginDirs, GeckoProfile.get(app).getFilesDir().getPath());
+            GeckoLoader.setupGeckoEnvironment(activity, pluginDirs, app.getFilesDir().getPath());
         }
         GeckoLoader.loadSQLiteLibs(app, resourcePath);
         GeckoLoader.loadNSSLibs(app, resourcePath);
         GeckoLoader.loadGeckoLibs(app, resourcePath);
         GeckoJavaSampler.setLibsLoaded();
 
         Locale.setDefault(locale);