mobile/android/base/webapp/Allocator.java

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:4f635ccb72cc
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/. */
5
6 package org.mozilla.gecko.webapp;
7
8 import java.util.ArrayList;
9
10 import org.mozilla.gecko.GeckoAppShell;
11
12 import android.content.Context;
13 import android.content.SharedPreferences;
14 import android.content.SharedPreferences.Editor;
15 import android.util.Log;
16
17 public class Allocator {
18
19 private final String LOGTAG = "GeckoWebappAllocator";
20
21 private static final String PREFIX_ORIGIN = "webapp-origin-";
22 private static final String PREFIX_PACKAGE_NAME = "webapp-package-name-";
23
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";
30
31 // The number of Webapp# and WEBAPP# activities/apps/intents
32 private final static int MAX_WEB_APPS = 100;
33
34 protected static Allocator sInstance = null;
35 public static Allocator getInstance() {
36 return getInstance(GeckoAppShell.getContext());
37 }
38
39 public static synchronized Allocator getInstance(Context cx) {
40 if (sInstance == null) {
41 sInstance = new Allocator(cx);
42 }
43
44 return sInstance;
45 }
46
47 SharedPreferences mPrefs;
48
49 protected Allocator(Context context) {
50 mPrefs = context.getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
51 }
52
53 private static String appKey(int index) {
54 return PREFIX_PACKAGE_NAME + index;
55 }
56
57 public static String iconKey(int index) {
58 return "web-app-color-" + index;
59 }
60
61 public static String originKey(int i) {
62 return PREFIX_ORIGIN + i;
63 }
64
65 private static String oldAppKey(int index) {
66 return PREFIX_OLD_APP + index;
67 }
68
69 private static String oldIconKey(int index) {
70 return PREFIX_OLD_ICON + index;
71 }
72
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 }
85
86 public ArrayList<String> getInstalledPackageNames() {
87 ArrayList<String> installedPackages = new ArrayList<String>();
88
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 }
96
97 public synchronized int findOrAllocatePackage(final String packageName) {
98 int index = getIndexForApp(packageName);
99 if (index != -1)
100 return index;
101
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 }
109
110 // no more apps!
111 return -1;
112 }
113
114 public synchronized void putPackageName(final int index, final String packageName) {
115 save(mPrefs.edit().putString(appKey(index), packageName));
116 }
117
118 public void updateColor(int index, int color) {
119 save(mPrefs.edit().putInt(iconKey(index), color));
120 }
121
122 public synchronized int getIndexForApp(String packageName) {
123 return findSlotForPrefix(PREFIX_PACKAGE_NAME, packageName);
124 }
125
126 public synchronized int getIndexForOrigin(String origin) {
127 return findSlotForPrefix(PREFIX_ORIGIN, origin);
128 }
129
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 }
138
139 public synchronized String getAppForIndex(int index) {
140 return mPrefs.getString(appKey(index), null);
141 }
142
143 public synchronized int releaseIndexForApp(String app) {
144 int index = getIndexForApp(app);
145 if (index == -1)
146 return -1;
147
148 releaseIndex(index);
149 return index;
150 }
151
152 public synchronized void releaseIndex(final int index) {
153 save(mPrefs.edit().remove(appKey(index)).remove(iconKey(index)).remove(originKey(index)));
154 }
155
156 public void putOrigin(int index, String origin) {
157 save(mPrefs.edit().putString(originKey(index), origin));
158 }
159
160 public String getOrigin(int index) {
161 return mPrefs.getString(originKey(index), null);
162 }
163
164 public int getColor(int index) {
165 return mPrefs.getInt(iconKey(index), -1);
166 }
167
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 }
176
177 Log.i(LOGTAG, "migrating old prefs");
178
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));
182
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));
186
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