2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
19 import android.appwidget.AppWidgetManager;
20 import android.appwidget.AppWidgetProviderInfo;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.os.Parcelable;
25 import android.util.Log;
27 import java.text.Collator;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.List;
33 public class AppWidgetLoader<Item extends AppWidgetLoader.LabelledItem> {
34 private static final String TAG = "AppWidgetAdapter";
35 private static final boolean LOGD = AppWidgetPickActivity.LOGD;
37 private Context mContext;
38 private AppWidgetManager mAppWidgetManager;
39 ItemConstructor<Item> mItemConstructor;
41 interface LabelledItem {
42 CharSequence getLabel();
45 public AppWidgetLoader(Context context, AppWidgetManager appWidgetManager,
46 ItemConstructor<Item> itemConstructor) {
48 mAppWidgetManager = appWidgetManager;
49 mItemConstructor = itemConstructor;
53 * Create list entries for any custom widgets requested through
54 * {@link AppWidgetManager#EXTRA_CUSTOM_INFO}.
56 void putCustomAppWidgets(List<Item> items, Intent intent) {
57 // get and validate the extras they gave us
58 ArrayList<AppWidgetProviderInfo> customInfo = null;
59 ArrayList<Bundle> customExtras = null;
61 customInfo = intent.getParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO);
62 if (customInfo == null || customInfo.size() == 0) {
63 Log.i(TAG, "EXTRA_CUSTOM_INFO not present.");
64 break try_custom_items;
67 int customInfoSize = customInfo.size();
68 for (int i=0; i<customInfoSize; i++) {
69 Parcelable p = customInfo.get(i);
70 if (p == null || !(p instanceof AppWidgetProviderInfo)) {
72 Log.e(TAG, "error using EXTRA_CUSTOM_INFO index=" + i);
73 break try_custom_items;
77 customExtras = intent.getParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS);
78 if (customExtras == null) {
80 Log.e(TAG, "EXTRA_CUSTOM_INFO without EXTRA_CUSTOM_EXTRAS");
81 break try_custom_items;
84 int customExtrasSize = customExtras.size();
85 if (customInfoSize != customExtrasSize) {
88 Log.e(TAG, "list size mismatch: EXTRA_CUSTOM_INFO: " + customInfoSize
89 + " EXTRA_CUSTOM_EXTRAS: " + customExtrasSize);
90 break try_custom_items;
94 for (int i=0; i<customExtrasSize; i++) {
95 Parcelable p = customExtras.get(i);
96 if (p == null || !(p instanceof Bundle)) {
99 Log.e(TAG, "error using EXTRA_CUSTOM_EXTRAS index=" + i);
100 break try_custom_items;
105 if (LOGD) Log.d(TAG, "Using " + customInfo.size() + " custom items");
106 putAppWidgetItems(customInfo, customExtras, items, 0, true);
111 * Create list entries for the given {@link AppWidgetProviderInfo} widgets,
112 * inserting extras if provided.
114 void putAppWidgetItems(List<AppWidgetProviderInfo> appWidgets,
115 List<Bundle> customExtras, List<Item> items, int categoryFilter,
116 boolean ignoreFilter) {
117 if (appWidgets == null) return;
118 final int size = appWidgets.size();
119 for (int i = 0; i < size; i++) {
120 AppWidgetProviderInfo info = appWidgets.get(i);
122 // We remove any widgets whose category isn't included in the filter
123 if (!ignoreFilter && (info.widgetCategory & categoryFilter) == 0) {
127 Item item = mItemConstructor.createItem(mContext, info,
128 customExtras != null ? customExtras.get(i) : null);
134 public interface ItemConstructor<Item> {
135 Item createItem(Context context, AppWidgetProviderInfo info, Bundle extras);
140 * Build and return list of items to be shown in dialog. This will mix both
141 * installed {@link AppWidgetProviderInfo} and those provided through
142 * {@link AppWidgetManager#EXTRA_CUSTOM_INFO}, sorting them alphabetically.
144 protected List<Item> getItems(Intent intent) {
145 boolean sortCustomAppWidgets =
146 intent.getBooleanExtra(AppWidgetManager.EXTRA_CUSTOM_SORT, true);
148 List<Item> items = new ArrayList<Item>();
150 // Default category is home screen
151 int categoryFilter = intent.getIntExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
152 AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
154 putInstalledAppWidgets(items, categoryFilter);
156 // Sort all items together by label
157 if (sortCustomAppWidgets) {
158 putCustomAppWidgets(items, intent);
160 Collections.sort(items, new Comparator<Item>() {
161 Collator mCollator = Collator.getInstance();
163 public int compare(Item lhs, Item rhs) {
164 return mCollator.compare(lhs.getLabel(), rhs.getLabel());
167 if (!sortCustomAppWidgets) {
168 List<Item> customItems = new ArrayList<Item>();
169 putCustomAppWidgets(customItems, intent);
170 items.addAll(customItems);
176 * Create list entries for installed {@link AppWidgetProviderInfo} widgets.
178 void putInstalledAppWidgets(List<Item> items, int categoryFilter) {
179 List<AppWidgetProviderInfo> installed =
180 mAppWidgetManager.getInstalledProviders(categoryFilter);
181 putAppWidgetItems(installed, null, items, categoryFilter, false);