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