blob: 8eebe39d986ae388a3491a2e7386def3f8221e07 [file] [log] [blame]
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -07001/*
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.launcher;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.pm.ActivityInfo;
23import android.content.pm.PackageManager;
24import android.content.pm.ResolveInfo;
25import android.view.LayoutInflater;
26import android.view.View;
27import android.view.ViewGroup;
28import android.widget.TextView;
29import android.widget.BaseExpandableListAdapter;
30import android.graphics.drawable.Drawable;
The Android Open Source Projectd097a182008-12-17 18:05:58 -080031import android.provider.LiveFolders;
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -070032
33import java.util.ArrayList;
34import java.util.Collections;
35import java.util.List;
36
37/**
38 * Shows a list of all the items that can be added to the workspace.
39 */
40public final class AddAdapter extends BaseExpandableListAdapter {
41 private static final int GROUP_APPLICATIONS = 0;
42 private static final int GROUP_SHORTCUTS = 1;
43 private static final int GROUP_WIDGETS = 2;
The Android Open Source Projectd097a182008-12-17 18:05:58 -080044 private static final int GROUP_LIVE_FOLDERS = 3;
45 private static final int GROUP_WALLPAPERS = 4;
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -070046
47 private final Intent mCreateShortcutIntent;
The Android Open Source Projectd097a182008-12-17 18:05:58 -080048 private final Intent mCreateLiveFolderIntent;
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -070049 private Intent mSetWallpaperIntent;
50 private final LayoutInflater mInflater;
51 private Launcher mLauncher;
52 private Group[] mGroups;
53
54 /**
55 * Abstract class representing one thing that can be added
56 */
57 public abstract class AddAction implements Runnable {
The Android Open Source Projectd097a182008-12-17 18:05:58 -080058 protected final Context mContext;
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -070059
60 AddAction(Context context) {
61 mContext = context;
62 }
63
64 Drawable getIcon(int resource) {
65 return mContext.getResources().getDrawable(resource);
66 }
67
68 public abstract void bindView(View v);
69 }
70
71 /**
72 * Class representing an action that will create set the wallpaper.
73 */
74 public class SetWallpaperAction extends CreateShortcutAction {
75 SetWallpaperAction(Context context, ResolveInfo info) {
76 super(context, info);
77 }
78
79 public void run() {
80 Intent intent = new Intent(mSetWallpaperIntent);
81 ActivityInfo activityInfo = mInfo.activityInfo;
82 intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
83 activityInfo.name));
84 mLauncher.startActivity(intent);
85 }
86 }
87
88 /**
89 * Class representing an action that will create a specific type
90 * of shortcut
91 */
92 public class CreateShortcutAction extends AddAction {
93
94 ResolveInfo mInfo;
95 private CharSequence mLabel;
96 private Drawable mIcon;
97
98 CreateShortcutAction(Context context, ResolveInfo info) {
99 super(context);
100 mInfo = info;
101 }
102
103 @Override
104 public void bindView(View view) {
105 ResolveInfo info = mInfo;
106 TextView text = (TextView) view;
107
108 PackageManager pm = mLauncher.getPackageManager();
109
110 if (mLabel == null) {
111 mLabel = info.loadLabel(pm);
112 if (mLabel == null) {
113 mLabel = info.activityInfo.name;
114 }
115 }
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800116
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700117 if (mIcon == null) {
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800118 mIcon = Utilities.createIconThumbnail(info.loadIcon(pm), mContext);
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700119 }
120
121 text.setText(mLabel);
122 text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
123 }
124
125 public void run() {
126 Intent intent = new Intent(mCreateShortcutIntent);
127 ActivityInfo activityInfo = mInfo.activityInfo;
128 intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
129 activityInfo.name));
130 mLauncher.addShortcut(intent);
131 }
132 }
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800133
134 /**
135 * Class representing an action that will create a specific type
136 * of live folder
137 */
138 public class CreateLiveFolderAction extends CreateShortcutAction {
139 CreateLiveFolderAction(Context context, ResolveInfo info) {
140 super(context, info);
141 }
142
143 @Override
144 public void run() {
145 Intent intent = new Intent(mCreateLiveFolderIntent);
146 ActivityInfo activityInfo = mInfo.activityInfo;
147 intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
148 activityInfo.name));
149 mLauncher.addLiveFolder(intent);
150 }
151 }
152
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700153 /**
154 * Class representing an action that will add a folder
155 */
156 public class CreateFolderAction extends AddAction {
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800157 private Drawable mIcon;
158
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700159 CreateFolderAction(Context context) {
160 super(context);
161 }
162
163 @Override
164 public void bindView(View view) {
165 TextView text = (TextView) view;
166 text.setText(R.string.add_folder);
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800167 if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_folder);
168 text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700169 }
170
171 public void run() {
172 mLauncher.addFolder();
173 }
174 }
175
176 /**
177 * Class representing an action that will add a folder
178 */
179 public class CreateClockAction extends AddAction {
180
181 CreateClockAction(Context context) {
182 super(context);
183 }
184
185 @Override
186 public void bindView(View view) {
187 TextView text = (TextView) view;
188 text.setText(R.string.add_clock);
189 Drawable icon = getIcon(R.drawable.ic_launcher_alarmclock);
190 text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
191 }
192
193 public void run() {
194 mLauncher.addClock();
195 }
196 }
197
198 /**
199 * Class representing an action that will add a PhotoFrame
200 */
201 public class CreatePhotoFrameAction extends AddAction {
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800202 private Drawable mIcon;
203
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700204 CreatePhotoFrameAction(Context context) {
205 super(context);
206 }
207
208 @Override
209 public void bindView(View view) {
210 TextView text = (TextView) view;
211 text.setText(R.string.add_photo_frame);
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800212 if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_gallery);
213 text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700214 }
215
216 public void run() {
217 mLauncher.getPhotoForPhotoFrame();
218 }
219 }
220
221
222 /**
223 * Class representing an action that will add a Search widget
224 */
225 public class CreateSearchAction extends AddAction {
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800226 private Drawable mIcon;
227
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700228 CreateSearchAction(Context context) {
229 super(context);
230 }
231
232 @Override
233 public void bindView(View view) {
234 TextView text = (TextView) view;
235 text.setText(R.string.add_search);
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800236 if (mIcon == null) mIcon = getIcon(R.drawable.ic_search_gadget);
237 text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700238 }
239
240 public void run() {
241 mLauncher.addSearch();
242 }
243 }
244
245 private class Group {
246 private String mName;
247 private ArrayList<AddAction> mList;
248
249 Group(String name) {
250 mName = name;
251 mList = new ArrayList<AddAction>();
252 }
253
254 void add(AddAction action) {
255 mList.add(action);
256 }
257
258 int size() {
259 return mList.size();
260 }
261
262 String getName() {
263 return mName;
264 }
265
266 void run(int position) {
267 mList.get(position).run();
268 }
269
270 void bindView(int childPosition, View view) {
271 mList.get(childPosition).bindView(view);
272 }
273
274 public Object get(int childPosition) {
275 return mList.get(childPosition);
276 }
277 }
278
279 private class ApplicationsGroup extends Group {
280 private final Launcher mLauncher;
281 private final ArrayList<ApplicationInfo> mApplications;
282
283 ApplicationsGroup(Launcher launcher, String name) {
284 super(name);
285 mLauncher = launcher;
286 mApplications = Launcher.getModel().getApplications();
287 }
288
289 @Override
290 int size() {
291 return mApplications == null ? 0 : mApplications.size();
292 }
293
294 @Override
295 void add(AddAction action) {
296 }
297
298 @Override
299 void run(int position) {
300 final ApplicationInfo info = mApplications.get(position);
301 mLauncher.addApplicationShortcut(info);
302 }
303
304 @Override
305 void bindView(int childPosition, View view) {
306 TextView text = (TextView) view.findViewById(R.id.title);
307
308 final ApplicationInfo info = mApplications.get(childPosition);
309 text.setText(info.title);
310 if (!info.filtered) {
311 info.icon = Utilities.createIconThumbnail(info.icon, mLauncher);
312 info.filtered = true;
313 }
314 text.setCompoundDrawablesWithIntrinsicBounds(info.icon, null, null, null);
315 }
316
317 @Override
318 public Object get(int childPosition) {
319 return mApplications.get(childPosition);
320 }
321 }
322
323 public AddAdapter(Launcher launcher, boolean forFolder) {
324 mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
325 mCreateShortcutIntent.setComponent(null);
326
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800327 mCreateLiveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
328 mCreateLiveFolderIntent.setComponent(null);
329
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700330 mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
331 mSetWallpaperIntent.setComponent(null);
332
333 mLauncher = launcher;
334 mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
335
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800336 mGroups = new Group[forFolder ? 2 : 5];
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700337 final Group[] groups = mGroups;
338 groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher,
339 mLauncher.getString(R.string.group_applications));
340 groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts));
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800341 groups[GROUP_LIVE_FOLDERS] = new Group(mLauncher.getString(R.string.group_live_folders));
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700342
343 if (!forFolder) {
344 groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers));
345 groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher));
346 groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets));
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800347
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700348 final Group widgets = groups[GROUP_WIDGETS];
349 widgets.add(new CreateClockAction(launcher));
350 widgets.add(new CreatePhotoFrameAction(launcher));
351 widgets.add(new CreateSearchAction(launcher));
352 }
353
354 PackageManager packageManager = launcher.getPackageManager();
355
356 List<ResolveInfo> list = findTargetsForIntent(mCreateShortcutIntent, packageManager);
357 if (list != null && list.size() > 0) {
358 int count = list.size();
359 final Group shortcuts = groups[GROUP_SHORTCUTS];
360 for (int i = 0; i < count; i++) {
361 ResolveInfo resolveInfo = list.get(i);
362 shortcuts.add(new CreateShortcutAction(launcher, resolveInfo));
363 }
364 }
365
The Android Open Source Projectd097a182008-12-17 18:05:58 -0800366 list = findTargetsForIntent(mCreateLiveFolderIntent, packageManager);
367 if (list != null && list.size() > 0) {
368 int count = list.size();
369 final Group shortcuts = groups[GROUP_LIVE_FOLDERS];
370 for (int i = 0; i < count; i++) {
371 ResolveInfo resolveInfo = list.get(i);
372 shortcuts.add(new CreateLiveFolderAction(launcher, resolveInfo));
373 }
374 }
375
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -0700376 list = findTargetsForIntent(mSetWallpaperIntent, packageManager);
377 if (list != null && list.size() > 0) {
378 int count = list.size();
379 final Group shortcuts = groups[GROUP_WALLPAPERS];
380 for (int i = 0; i < count; i++) {
381 ResolveInfo resolveInfo = list.get(i);
382 shortcuts.add(new SetWallpaperAction(launcher, resolveInfo));
383 }
384 }
385 }
386
387 private List<ResolveInfo> findTargetsForIntent(Intent intent, PackageManager packageManager) {
388 List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
389 PackageManager.MATCH_DEFAULT_ONLY);
390 if (list != null) {
391 int count = list.size();
392 if (count > 1) {
393 // Only display the first matches that are either of equal
394 // priority or have asked to be default options.
395 ResolveInfo firstInfo = list.get(0);
396 for (int i=1; i<count; i++) {
397 ResolveInfo resolveInfo = list.get(i);
398 if (firstInfo.priority != resolveInfo.priority ||
399 firstInfo.isDefault != resolveInfo.isDefault) {
400 while (i < count) {
401 list.remove(i);
402 count--;
403 }
404 }
405 }
406 Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager));
407 }
408 }
409 return list;
410 }
411
412 public int getGroupCount() {
413 return mGroups.length;
414 }
415
416 public int getChildrenCount(int groupPosition) {
417 return mGroups[groupPosition].size();
418 }
419
420 public Object getGroup(int groupPosition) {
421 return mGroups[groupPosition].getName();
422 }
423
424 public Object getChild(int groupPosition, int childPosition) {
425 return mGroups[groupPosition].get(childPosition);
426 }
427
428 public long getGroupId(int groupPosition) {
429 return groupPosition;
430 }
431
432 public long getChildId(int groupPosition, int childPosition) {
433 return (groupPosition << 16) | childPosition;
434 }
435
436 public boolean hasStableIds() {
437 return true;
438 }
439
440 public View getGroupView(int groupPosition, boolean isExpanded,
441 View convertView, ViewGroup parent) {
442 View view;
443 if (convertView == null) {
444 view = mInflater.inflate(R.layout.create_shortcut_group_item, parent, false);
445 } else {
446 view = convertView;
447 }
448 ((TextView) view).setText(mGroups[groupPosition].getName());
449 return view;
450 }
451
452 public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
453 View convertView, ViewGroup parent) {
454 View view;
455 if (convertView == null) {
456 view = mInflater.inflate(R.layout.create_shortcut_list_item, parent, false);
457 } else {
458 view = convertView;
459 }
460 mGroups[groupPosition].bindView(childPosition, view);
461 return view;
462 }
463
464 public boolean isChildSelectable(int groupPosition, int childPosition) {
465 return true;
466 }
467
468 void performAction(int groupPosition, int childPosition) {
469 mGroups[groupPosition].run(childPosition);
470 }
471}