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
17package com.google.android.leanbacklauncher.partnercustomizer;
18
19import android.app.Notification;
20import android.app.NotificationManager;
21import android.app.PendingIntent;
22import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.pm.PackageManager;
26import android.graphics.BitmapFactory;
27import android.net.Uri;
28import android.os.Bundle;
29import 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 */
39public 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
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
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
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
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
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