1 /*
2  * Copyright (C) 2014 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.google.android.leanbacklauncher.partnercustomizer;
18 
19 import android.app.Notification;
20 import android.app.NotificationManager;
21 import android.app.PendingIntent;
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.graphics.BitmapFactory;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.os.Handler;
30 
31 /**
32  * This class posts notifications that are used to populate the Partner Row of the Leanback Launcher
33  * It also allows the system/launcher to find the correct partner customization
34  * package.
35  *
36  * Packages using this broadcast receiver must also be a system app to be used for
37  * partner customization.
38  */
39 public class PartnerReceiver extends BroadcastReceiver {
40     private static final String ACTION_PARTNER_CUSTOMIZATION =
41             "com.google.android.leanbacklauncher.action.PARTNER_CUSTOMIZATION";
42 
43     private static final String EXTRA_ROW_WRAPPING_CUTOFF =
44             "com.google.android.leanbacklauncher.extra.ROW_WRAPPING_CUTOFF";
45 
46     private static final String PARTNER_GROUP = "partner_row_entry";
47     private static final String BLACKLIST_PACKAGE = "com.google.android.leanbacklauncher.replacespackage";
48 
49     private static final String TED_PKG_NAME = "com.ted.android.tv";
50     private static final String PLAY_MOVIES_PKG_NAME = "com.google.android.videos";
51 
52     private Context mContext;
53     private NotificationManager mNotifMan;
54     private PackageManager mPkgMan;
55 
56     // Cutoff value for when the Launcher displays the Partner row as a single
57     // row, or a two row grid. Can be used for correctly positioning the partner
58     // app entries.
59     private int mRowCutoff = 0;
60 
61     @Override
onReceive(Context context, Intent intent)62     public void onReceive(Context context, Intent intent) {
63         if (mContext == null) {
64             mContext = context;
65             mNotifMan = (NotificationManager)
66                     mContext.getSystemService(Context.NOTIFICATION_SERVICE);
67             mPkgMan = mContext.getPackageManager();
68         }
69 
70         String action = intent.getAction();
71         if (Intent.ACTION_PACKAGE_ADDED.equals(action)||
72                 Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
73             postNotification(getPackageName(intent));
74         } else if (ACTION_PARTNER_CUSTOMIZATION.equals(action)) {
75             mRowCutoff = intent.getIntExtra(EXTRA_ROW_WRAPPING_CUTOFF, 0);
76             postNotification(TED_PKG_NAME);
77             postNotification(PLAY_MOVIES_PKG_NAME);
78         }
79     }
80 
postNotification(String pkgName)81     private void postNotification(String pkgName) {
82         int sort;
83         int resId;
84         int backupResId;
85         int titleId;
86         int backupTitleId;
87 
88         switch (pkgName) {
89             case TED_PKG_NAME:
90                 sort = 1;
91                 resId = R.drawable.ic_ted_banner;
92                 backupResId = R.drawable.ic_try_ted_banner;
93                 titleId = R.string.ted;
94                 backupTitleId = R.string.try_ted;
95                 break;
96             case PLAY_MOVIES_PKG_NAME:
97                 sort = 2;
98                 resId = R.drawable.ic_play_movies_banner;
99                 backupResId = R.drawable.ic_try_play_movies_banner;
100                 titleId = R.string.play_movies;
101                 backupTitleId = R.string.try_play_movies;
102                 break;
103             default:
104                 return;
105         }
106 
107         postNotification(sort, resId, backupResId, titleId, backupTitleId, pkgName);
108     }
109 
postNotification(int sort, int resId, int backupResId, int titleId, int backupTitleId, String pkgName)110     private void postNotification(int sort, int resId, int backupResId,
111             int titleId, int backupTitleId, String pkgName) {
112         int id = resId;
113         Intent intent = mPkgMan.getLeanbackLaunchIntentForPackage(pkgName);
114 
115         if (intent == null) {
116             titleId = backupTitleId;
117             resId = backupResId;
118             intent = getBackupIntent(pkgName);
119         }
120 
121         Notification.Builder bob = new Notification.Builder(mContext);
122         Bundle extras = new Bundle();
123         extras.putString(BLACKLIST_PACKAGE, pkgName);
124 
125         bob.setContentTitle(mContext.getString(titleId))
126                 .setSmallIcon(R.drawable.ic_launcher)
127                 .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), resId))
128                 .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0))
129                 .setCategory(Notification.CATEGORY_RECOMMENDATION)
130                 .setGroup(PARTNER_GROUP)
131                 .setSortKey(sort+"")
132                 .setColor(mContext.getResources().getColor(R.color.partner_color))
133                 .setExtras(extras);
134 
135         mNotifMan.notify(id, bob.build());
136     }
137 
getBackupIntent(String pkgName)138     private Intent getBackupIntent(String pkgName) {
139         Intent intent = new Intent(Intent.ACTION_VIEW);
140         intent.setData(Uri.parse("market://details?id=" + pkgName));
141 
142         return intent;
143     }
144 
getPackageName(Intent intent)145     private String getPackageName(Intent intent) {
146         Uri uri = intent.getData();
147         String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
148         return pkg;
149     }
150 
151 }
152