blob: 985ef8bf0c5284aec38856012c679fb77645fcc7 [file] [log] [blame]
Michael Jurka0b2bd8d2012-10-30 15:32:27 -07001/*
2 * Copyright (C) 2012 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.appwidget.AppWidgetManager;
20import android.appwidget.AppWidgetProviderInfo;
21import android.content.Context;
22import android.content.Intent;
23import android.os.Bundle;
24import android.os.Parcelable;
25import android.util.Log;
26
27import java.text.Collator;
28import java.util.ArrayList;
29import java.util.Collections;
30import java.util.Comparator;
31import java.util.List;
32
33public class AppWidgetLoader<Item extends AppWidgetLoader.LabelledItem> {
34 private static final String TAG = "AppWidgetAdapter";
35 private static final boolean LOGD = AppWidgetPickActivity.LOGD;
36
37 private Context mContext;
38 private AppWidgetManager mAppWidgetManager;
39 ItemConstructor<Item> mItemConstructor;
40
41 interface LabelledItem {
42 CharSequence getLabel();
43 }
44
45 public AppWidgetLoader(Context context, AppWidgetManager appWidgetManager,
46 ItemConstructor<Item> itemConstructor) {
47 mContext = context;
48 mAppWidgetManager = appWidgetManager;
49 mItemConstructor = itemConstructor;
50 }
51
52 /**
53 * Create list entries for any custom widgets requested through
54 * {@link AppWidgetManager#EXTRA_CUSTOM_INFO}.
55 */
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;
60 try_custom_items: {
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;
65 }
66
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)) {
71 customInfo = null;
72 Log.e(TAG, "error using EXTRA_CUSTOM_INFO index=" + i);
73 break try_custom_items;
74 }
75 }
76
77 customExtras = intent.getParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS);
78 if (customExtras == null) {
79 customInfo = null;
80 Log.e(TAG, "EXTRA_CUSTOM_INFO without EXTRA_CUSTOM_EXTRAS");
81 break try_custom_items;
82 }
83
84 int customExtrasSize = customExtras.size();
85 if (customInfoSize != customExtrasSize) {
86 customInfo = null;
87 customExtras = null;
88 Log.e(TAG, "list size mismatch: EXTRA_CUSTOM_INFO: " + customInfoSize
89 + " EXTRA_CUSTOM_EXTRAS: " + customExtrasSize);
90 break try_custom_items;
91 }
92
93
94 for (int i=0; i<customExtrasSize; i++) {
95 Parcelable p = customExtras.get(i);
96 if (p == null || !(p instanceof Bundle)) {
97 customInfo = null;
98 customExtras = null;
99 Log.e(TAG, "error using EXTRA_CUSTOM_EXTRAS index=" + i);
100 break try_custom_items;
101 }
102 }
103 }
104
105 if (LOGD) Log.d(TAG, "Using " + customInfo.size() + " custom items");
106 putAppWidgetItems(customInfo, customExtras, items, 0, true);
107 }
108
109
110 /**
111 * Create list entries for the given {@link AppWidgetProviderInfo} widgets,
112 * inserting extras if provided.
113 */
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);
121
122 // We remove any widgets whose category isn't included in the filter
123 if (!ignoreFilter && (info.widgetCategory & categoryFilter) == 0) {
124 continue;
125 }
126
127 Item item = mItemConstructor.createItem(mContext, info,
128 customExtras != null ? customExtras.get(i) : null);
129
130 items.add(item);
131 }
132 }
133
134 public interface ItemConstructor<Item> {
135 Item createItem(Context context, AppWidgetProviderInfo info, Bundle extras);
136 }
137
138
139 /**
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.
143 */
144 protected List<Item> getItems(Intent intent) {
145 boolean sortCustomAppWidgets =
146 intent.getBooleanExtra(AppWidgetManager.EXTRA_CUSTOM_SORT, true);
147
148 List<Item> items = new ArrayList<Item>();
149
150 // Default category is home screen
151 int categoryFilter = intent.getIntExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
152 AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
153
154 putInstalledAppWidgets(items, categoryFilter);
155
156 // Sort all items together by label
157 if (sortCustomAppWidgets) {
158 putCustomAppWidgets(items, intent);
159 }
160 Collections.sort(items, new Comparator<Item>() {
161 Collator mCollator = Collator.getInstance();
162
163 public int compare(Item lhs, Item rhs) {
164 return mCollator.compare(lhs.getLabel(), rhs.getLabel());
165 }
166 });
167 if (!sortCustomAppWidgets) {
168 List<Item> customItems = new ArrayList<Item>();
169 putCustomAppWidgets(customItems, intent);
170 items.addAll(customItems);
171 }
172 return items;
173 }
174
175 /**
176 * Create list entries for installed {@link AppWidgetProviderInfo} widgets.
177 */
178 void putInstalledAppWidgets(List<Item> items, int categoryFilter) {
Adam Cohen441588d2012-11-28 16:37:44 -0800179 List<AppWidgetProviderInfo> installed =
180 mAppWidgetManager.getInstalledProviders(categoryFilter);
Michael Jurka0b2bd8d2012-10-30 15:32:27 -0700181 putAppWidgetItems(installed, null, items, categoryFilter, false);
182 }
183}