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.

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

mercurial