blob: f7b5a61bb4630e6639fae150d01065455f1788b5 [file] [log] [blame]
The Android Open Source Project8a156092009-03-02 22:54:43 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings;
18
19import android.app.Activity;
20import android.content.ContentResolver;
21import android.content.ContentUris;
22import android.content.ContentValues;
23import android.content.Intent;
24import android.content.ComponentName;
25import android.database.Cursor;
26import android.database.SQLException;
27import android.gadget.GadgetManager;
28import android.graphics.Bitmap;
29import android.graphics.BitmapFactory;
30import android.net.Uri;
31import android.os.Bundle;
32import android.provider.BaseColumns;
33import android.util.Log;
34
35import java.util.ArrayList;
36
37public class LauncherGadgetBinder extends Activity {
38 private static final String TAG = "LauncherGadgetBinder";
39 private static final boolean LOGD = true;
40
41 static final String AUTHORITY = "com.android.launcher.settings";
42 static final String TABLE_FAVORITES = "favorites";
43
44 static final String EXTRA_BIND_SOURCES = "com.android.launcher.settings.bindsources";
45 static final String EXTRA_BIND_TARGETS = "com.android.launcher.settings.bindtargets";
46
47 static final String EXTRA_GADGET_BITMAPS = "com.android.camera.gadgetbitmaps";
48
49 /**
50 * {@link ContentProvider} constants pulled over from Launcher
51 */
52 static final class LauncherProvider implements BaseColumns {
53 static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_FAVORITES);
54
55 static final String ITEM_TYPE = "itemType";
56 static final String GADGET_ID = "gadgetId";
57 static final String ICON = "icon";
58
59 static final int ITEM_TYPE_GADGET = 4;
60 static final int ITEM_TYPE_WIDGET_CLOCK = 1000;
61 static final int ITEM_TYPE_WIDGET_SEARCH = 1001;
62 static final int ITEM_TYPE_WIDGET_PHOTO_FRAME = 1002;
63 }
64
65 static final String[] BIND_PROJECTION = new String[] {
66 LauncherProvider._ID,
67 LauncherProvider.ITEM_TYPE,
68 LauncherProvider.GADGET_ID,
69 LauncherProvider.ICON,
70 };
71
72 static final int INDEX_ID = 0;
73 static final int INDEX_ITEM_TYPE = 1;
74 static final int INDEX_GADGET_ID = 2;
75 static final int INDEX_ICON = 3;
76
77 static final ComponentName BIND_PHOTO_GADGET = new ComponentName("com.android.camera",
78 "com.android.camera.PhotoGadgetBind");
79
80 @Override
81 protected void onCreate(Bundle icicle) {
82 super.onCreate(icicle);
83 finish();
84
85 // This helper reaches into the Launcher database and binds any unlinked
86 // gadgets. If will remove any items that can't be bound successfully.
87 // We protect this binder at the manifest level by asserting the caller
88 // has the Launcher WRITE_SETTINGS permission.
89
90 final Intent intent = getIntent();
91 final Bundle extras = intent.getExtras();
92
93 int[] bindSources = null;
94 ArrayList<ComponentName> bindTargets = null;
95 Exception exception = null;
96
97 try {
98 bindSources = extras.getIntArray(EXTRA_BIND_SOURCES);
99 bindTargets = intent.getParcelableArrayListExtra(EXTRA_BIND_TARGETS);
100 } catch (ClassCastException ex) {
101 exception = ex;
102 }
103
104 if (exception != null || bindSources == null || bindTargets == null ||
105 bindSources.length != bindTargets.size()) {
106 Log.w(TAG, "Problem reading incoming bind request, or invalid request", exception);
107 return;
108 }
109
110 final String selectWhere = buildOrWhereString(LauncherProvider.ITEM_TYPE, bindSources);
111
112 final ContentResolver resolver = getContentResolver();
113 final GadgetManager gadgetManager = GadgetManager.getInstance(this);
114
115 boolean foundPhotoGadgets = false;
116 final ArrayList<Integer> photoGadgetIds = new ArrayList<Integer>();
117 final ArrayList<Bitmap> photoBitmaps = new ArrayList<Bitmap>();
118
119 Cursor c = null;
120
121 try {
122 c = resolver.query(LauncherProvider.CONTENT_URI,
123 BIND_PROJECTION, selectWhere, null, null);
124
125 if (LOGD) Log.d(TAG, "found bind cursor count="+c.getCount());
126
127 final ContentValues values = new ContentValues();
128 while (c != null && c.moveToNext()) {
129 long favoriteId = c.getLong(INDEX_ID);
130 int itemType = c.getInt(INDEX_ITEM_TYPE);
131 int gadgetId = c.getInt(INDEX_GADGET_ID);
132 byte[] iconData = c.getBlob(INDEX_ICON);
133
134 // Find the binding target for this type
135 ComponentName targetGadget = null;
136 for (int i = 0; i < bindSources.length; i++) {
137 if (bindSources[i] == itemType) {
138 targetGadget = bindTargets.get(i);
139 break;
140 }
141 }
142
143 if (LOGD) Log.d(TAG, "found matching targetGadget="+targetGadget.toString()+" for favoriteId="+favoriteId);
144
145 boolean bindSuccess = false;
146 try {
147 gadgetManager.bindGadgetId(gadgetId, targetGadget);
148 bindSuccess = true;
149 } catch (RuntimeException ex) {
150 Log.w(TAG, "Problem binding gadget", ex);
151 }
152
153 // Handle special case of photo gadget by loading bitmap and
154 // preparing for later binding
155 if (bindSuccess && iconData != null &&
156 itemType == LauncherProvider.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
157 Bitmap bitmap = BitmapFactory.decodeByteArray(iconData, 0, iconData.length);
158
159 photoGadgetIds.add(gadgetId);
160 photoBitmaps.add(bitmap);
161 foundPhotoGadgets = true;
162 }
163
164 if (LOGD) Log.d(TAG, "after finished, success="+bindSuccess);
165
166 // Depending on success, update launcher or remove item
167 Uri favoritesUri = ContentUris.withAppendedId(LauncherProvider.CONTENT_URI, favoriteId);
168 if (bindSuccess) {
169 values.clear();
170 values.put(LauncherProvider.ITEM_TYPE, LauncherProvider.ITEM_TYPE_GADGET);
171 values.putNull(LauncherProvider.ICON);
172 resolver.update(favoritesUri, values, null, null);
173 } else {
174 resolver.delete(favoritesUri, null, null);
175 }
176
177 }
178 } catch (SQLException ex) {
179 Log.w(TAG, "Problem while binding gadgetIds for Launcher", ex);
180 } finally {
181 if (c != null) {
182 c.close();
183 }
184 }
185
186 if (foundPhotoGadgets) {
187 // Convert gadgetIds into int[]
188 final int N = photoGadgetIds.size();
189 final int[] photoGadgetIdsArray = new int[N];
190 for (int i = 0; i < N; i++) {
191 photoGadgetIdsArray[i] = photoGadgetIds.get(i);
192 }
193
194 // Launch intent over to handle bitmap binding, but we don't need to
195 // wait around for the result.
196 final Intent bindIntent = new Intent();
197 bindIntent.setComponent(BIND_PHOTO_GADGET);
198
199 final Bundle bindExtras = new Bundle();
200 bindExtras.putIntArray(GadgetManager.EXTRA_GADGET_IDS, photoGadgetIdsArray);
201 bindExtras.putParcelableArrayList(EXTRA_GADGET_BITMAPS, photoBitmaps);
202 bindIntent.putExtras(bindExtras);
203
204 startActivity(bindIntent);
205 }
206
207 if (LOGD) Log.d(TAG, "completely finished with binding for Launcher");
208 }
209
210 /**
211 * Build a query string that will match any row where the column matches
212 * anything in the values list.
213 */
214 static String buildOrWhereString(String column, int[] values) {
215 StringBuilder selectWhere = new StringBuilder();
216 for (int i = values.length - 1; i >= 0; i--) {
217 selectWhere.append(column).append("=").append(values[i]);
218 if (i > 0) {
219 selectWhere.append(" OR ");
220 }
221 }
222 return selectWhere.toString();
223 }
224
225}