1 /*
2  * Copyright (C) 2015 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 
17 package com.android.messaging.widget;
18 
19 import android.app.PendingIntent;
20 import android.appwidget.AppWidgetManager;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.widget.RemoteViews;
25 
26 import com.android.messaging.R;
27 import com.android.messaging.ui.UIIntents;
28 import com.android.messaging.util.LogUtil;
29 import com.android.messaging.util.OsUtil;
30 import com.android.messaging.util.SafeAsyncTask;
31 import com.android.messaging.util.UiUtils;
32 
33 public class BugleWidgetProvider extends BaseWidgetProvider {
34     public static final String ACTION_NOTIFY_CONVERSATIONS_CHANGED =
35             "com.android.Bugle.intent.action.ACTION_NOTIFY_CONVERSATIONS_CHANGED";
36 
37     public static final int WIDGET_NEW_CONVERSATION_REQUEST_CODE = 986;
38 
39     /**
40      * Update the widget appWidgetId
41      */
42     @Override
updateWidget(final Context context, final int appWidgetId)43     protected void updateWidget(final Context context, final int appWidgetId) {
44         if (OsUtil.hasRequiredPermissions()) {
45             SafeAsyncTask.executeOnThreadPool(new Runnable() {
46                 @Override
47                 public void run() {
48                     rebuildWidget(context, appWidgetId);
49                 }
50             });
51         } else {
52             AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId,
53                     UiUtils.getWidgetMissingPermissionView(context));
54         }
55     }
56 
57     @Override
getAction()58     protected String getAction() {
59         return ACTION_NOTIFY_CONVERSATIONS_CHANGED;
60     }
61 
62     @Override
getListId()63     protected int getListId() {
64         return R.id.conversation_list;
65     }
66 
rebuildWidget(final Context context, final int appWidgetId)67     public static void rebuildWidget(final Context context, final int appWidgetId) {
68         if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
69             LogUtil.v(TAG, "BugleWidgetProvider.rebuildWidget appWidgetId: " + appWidgetId);
70         }
71         final RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
72                 R.layout.widget_conversation_list);
73         PendingIntent clickIntent;
74 
75         // Launch an intent to avoid ANRs
76         final Intent intent = new Intent(context, WidgetConversationListService.class);
77         intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
78         intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
79         remoteViews.setRemoteAdapter(appWidgetId, R.id.conversation_list, intent);
80 
81         remoteViews.setTextViewText(R.id.widget_label, context.getString(R.string.app_name));
82 
83         // Open Bugle's app conversation list when click on header
84         clickIntent = UIIntents.get().getWidgetPendingIntentForConversationListActivity(context);
85         remoteViews.setOnClickPendingIntent(R.id.widget_header, clickIntent);
86 
87         // On click intent for Compose
88         clickIntent = UIIntents.get().getWidgetPendingIntentForConversationActivity(context,
89                 null /*conversationId*/, WIDGET_NEW_CONVERSATION_REQUEST_CODE);
90         remoteViews.setOnClickPendingIntent(R.id.widget_compose, clickIntent);
91 
92         // On click intent for Conversation
93         // Note: the template intent has to be a "naked" intent without any extras. It turns out
94         // that if the template intent does have extras, those particular extras won't get
95         // replaced by the fill-in intent on each list item.
96         clickIntent = UIIntents.get().getWidgetPendingIntentForConversationActivity(context,
97                 null /*conversationId*/, WIDGET_CONVERSATION_REQUEST_CODE);
98         remoteViews.setPendingIntentTemplate(R.id.conversation_list, clickIntent);
99 
100         AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, remoteViews);
101     }
102 
103     /*
104      * notifyDatasetChanged call when the conversation list changes so the Bugle widget will
105      * update and reflect the changes
106      */
notifyConversationListChanged(final Context context)107     public static void notifyConversationListChanged(final Context context) {
108         if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
109             LogUtil.v(TAG, "notifyConversationListChanged");
110         }
111         final Intent intent = new Intent(ACTION_NOTIFY_CONVERSATIONS_CHANGED);
112         context.sendBroadcast(intent);
113     }
114 }
115