mobile/android/base/webapp/Allocator.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.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; 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.webapp;
     8 import java.util.ArrayList;
    10 import org.mozilla.gecko.GeckoAppShell;
    12 import android.content.Context;
    13 import android.content.SharedPreferences;
    14 import android.content.SharedPreferences.Editor;
    15 import android.util.Log;
    17 public class Allocator {
    19     private final String LOGTAG = "GeckoWebappAllocator";
    21     private static final String PREFIX_ORIGIN = "webapp-origin-";
    22     private static final String PREFIX_PACKAGE_NAME = "webapp-package-name-";
    24     // These prefixes are for prefs used by the old shortcut-based runtime.
    25     // We define them here so maybeMigrateOldPrefs can migrate them to their
    26     // new equivalents if this app was originally installed as a shortcut.
    27     // Maybe we can remove this code in the future!
    28     private static final String PREFIX_OLD_APP = "app";
    29     private static final String PREFIX_OLD_ICON = "icon";
    31     // The number of Webapp# and WEBAPP# activities/apps/intents
    32     private final static int MAX_WEB_APPS = 100;
    34     protected static Allocator sInstance = null;
    35     public static Allocator getInstance() {
    36         return getInstance(GeckoAppShell.getContext());
    37     }
    39     public static synchronized Allocator getInstance(Context cx) {
    40         if (sInstance == null) {
    41             sInstance = new Allocator(cx);
    42         }
    44         return sInstance;
    45     }
    47     SharedPreferences mPrefs;
    49     protected Allocator(Context context) {
    50         mPrefs = context.getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
    51     }
    53     private static String appKey(int index) {
    54         return PREFIX_PACKAGE_NAME + index;
    55     }
    57     public static String iconKey(int index) {
    58         return "web-app-color-" + index;
    59     }
    61     public static String originKey(int i) {
    62         return PREFIX_ORIGIN + i;
    63     }
    65     private static String oldAppKey(int index) {
    66         return PREFIX_OLD_APP + index;
    67     }
    69     private static String oldIconKey(int index) {
    70         return PREFIX_OLD_ICON + index;
    71     }
    73     private static void save(Editor editor) {
    74         // Use SharedPreferences.Editor.apply() where available and commit()
    75         // where it isn't.  We could also use a background thread with commit(),
    76         // but our callers might expect the changes we make to be available
    77         // immediately, so we instead take the commit() performance hit
    78         // on the small percentage of extant devices that don't support apply().
    79         if (android.os.Build.VERSION.SDK_INT > 8) {
    80             editor.apply();
    81         } else {
    82             editor.commit();
    83         }
    84     }
    86     public ArrayList<String> getInstalledPackageNames() {
    87         ArrayList<String> installedPackages = new ArrayList<String>();
    89         for (int i = 0; i < MAX_WEB_APPS; ++i) {
    90             if (mPrefs.contains(appKey(i))) {
    91                 installedPackages.add(mPrefs.getString(appKey(i), ""));
    92             }
    93         }
    94         return installedPackages;
    95     }
    97     public synchronized int findOrAllocatePackage(final String packageName) {
    98         int index = getIndexForApp(packageName);
    99         if (index != -1)
   100             return index;
   102         for (int i = 0; i < MAX_WEB_APPS; ++i) {
   103             if (!mPrefs.contains(appKey(i))) {
   104                 // found unused index i
   105                 putPackageName(i, packageName);
   106                 return i;
   107             }
   108         }
   110         // no more apps!
   111         return -1;
   112     }
   114     public synchronized void putPackageName(final int index, final String packageName) {
   115         save(mPrefs.edit().putString(appKey(index), packageName));
   116     }
   118     public void updateColor(int index, int color) {
   119         save(mPrefs.edit().putInt(iconKey(index), color));
   120     }
   122     public synchronized int getIndexForApp(String packageName) {
   123         return findSlotForPrefix(PREFIX_PACKAGE_NAME, packageName);
   124     }
   126     public synchronized int getIndexForOrigin(String origin) {
   127         return findSlotForPrefix(PREFIX_ORIGIN, origin);
   128     }
   130     protected int findSlotForPrefix(String prefix, String value) {
   131         for (int i = 0; i < MAX_WEB_APPS; ++i) {
   132             if (mPrefs.getString(prefix + i, "").equals(value)) {
   133                 return i;
   134             }
   135         }
   136         return -1;
   137     }
   139     public synchronized String getAppForIndex(int index) {
   140         return mPrefs.getString(appKey(index), null);
   141     }
   143     public synchronized int releaseIndexForApp(String app) {
   144         int index = getIndexForApp(app);
   145         if (index == -1)
   146             return -1;
   148         releaseIndex(index);
   149         return index;
   150     }
   152     public synchronized void releaseIndex(final int index) {
   153         save(mPrefs.edit().remove(appKey(index)).remove(iconKey(index)).remove(originKey(index)));
   154     }
   156     public void putOrigin(int index, String origin) {
   157         save(mPrefs.edit().putString(originKey(index), origin));
   158     }
   160     public String getOrigin(int index) {
   161         return mPrefs.getString(originKey(index), null);
   162     }
   164     public int getColor(int index) {
   165         return mPrefs.getInt(iconKey(index), -1);
   166     }
   168     /**
   169      * Migrate old prefs to their new equivalents if this app was originally
   170      * installed by the shortcut-based implementation.
   171      */
   172     public void maybeMigrateOldPrefs(int index) {
   173         if (!mPrefs.contains(oldAppKey(index))) {
   174             return;
   175         }
   177         Log.i(LOGTAG, "migrating old prefs");
   179         // The old appKey pref stored the origin, while the new appKey pref
   180         // stores the packageName, so we migrate oldAppKey to the origin pref.
   181         putOrigin(index, mPrefs.getString(oldAppKey(index), null));
   183         // The old iconKey pref actually stored the splash screen background
   184         // color, so we migrate oldIconKey to the color pref.
   185         updateColor(index, mPrefs.getInt(oldIconKey(index), -1));
   187         // Remove the old prefs so we don't migrate them the next time around.
   188         save(mPrefs.edit().remove(oldAppKey(index)).remove(oldIconKey(index)));
   189     }
   190 }

mercurial