1 /*
2  * Copyright (c) 2016, 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 package com.android.car.stream.media;
17 
18 import android.content.ComponentName;
19 import android.content.Context;
20 import android.content.pm.ApplicationInfo;
21 import android.content.pm.PackageManager;
22 import android.content.pm.ServiceInfo;
23 import android.content.res.Resources;
24 import android.content.res.TypedArray;
25 import android.util.Log;
26 
27 /**
28  * An immutable class which hold the the information about the currently connected media app, if
29  * it supports {@link android.service.media.MediaBrowserService}.
30  */
31 public class MediaAppInfo {
32     private static final String TAG = "MediaAppInfo";
33     private static final String KEY_SMALL_ICON =
34             "com.google.android.gms.car.notification.SmallIcon";
35 
36     /** Third-party defined application theme to use **/
37     private static final String THEME_META_DATA_NAME
38             = "com.google.android.gms.car.application.theme";
39 
40     private final ComponentName mComponentName;
41     private final Resources mPackageResources;
42     private final String mAppName;
43     private final String mPackageName;
44     private final int mSmallIcon;
45 
46     private int mPrimaryColor;
47     private int mPrimaryColorDark;
48     private int mAccentColor;
49 
MediaAppInfo(Context context, String packageName)50     public MediaAppInfo(Context context, String packageName) {
51         Resources resources = null;
52         try {
53             resources = context.getPackageManager().getResourcesForApplication(packageName);
54         } catch (PackageManager.NameNotFoundException e) {
55             Log.e(TAG, "Unable to get resources for " + packageName);
56         }
57         mPackageResources = resources;
58 
59         mComponentName = MediaUtils.getMediaBrowserService(packageName, context);
60         String appName = null;
61         int smallIconResId = 0;
62         try {
63             PackageManager packageManager = context.getPackageManager();
64             ServiceInfo serviceInfo = null;
65             ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName,
66                     PackageManager.GET_META_DATA);
67 
68             int labelResId;
69 
70             if (mComponentName != null) {
71                 serviceInfo =
72                         packageManager.getServiceInfo(mComponentName, PackageManager.GET_META_DATA);
73                 smallIconResId = serviceInfo.metaData == null ? 0 : serviceInfo.metaData.getInt
74                         (KEY_SMALL_ICON, 0);
75                 labelResId = serviceInfo.labelRes;
76             } else {
77                 Log.w(TAG, "Service label is null for " + packageName +
78                         ". Falling back to app name.");
79                 labelResId = appInfo.labelRes;
80             }
81 
82             int appTheme = 0;
83             if (serviceInfo != null && serviceInfo.metaData != null) {
84                 appTheme = serviceInfo.metaData.getInt(THEME_META_DATA_NAME);
85             }
86             if (appTheme == 0 && appInfo.metaData != null) {
87                 appTheme = appInfo.metaData.getInt(THEME_META_DATA_NAME);
88             }
89             if (appTheme == 0) {
90                 appTheme = appInfo.theme;
91             }
92 
93             fetchAppColors(packageName, appTheme, context);
94             appName = (labelResId == 0 || mPackageResources == null) ? null
95                     : mPackageResources.getString(labelResId);
96         } catch (PackageManager.NameNotFoundException e) {
97             Log.e(TAG, "Got a component that doesn't exist (" + packageName + ")");
98         }
99         mSmallIcon = smallIconResId;
100         mAppName = appName;
101 
102         mPackageName = packageName;
103     }
104 
getComponentName()105     public ComponentName getComponentName() {
106         return mComponentName;
107     }
108 
getAppName()109     public String getAppName() {
110         return mAppName;
111     }
112 
getSmallIcon()113     public int getSmallIcon() {
114         return mSmallIcon;
115     }
116 
getPackageName()117     public String getPackageName() {
118         return mPackageName;
119     }
120 
getPackageResources()121     public Resources getPackageResources() {
122         return mPackageResources;
123     }
124 
getMediaClientPrimaryColor()125     public int getMediaClientPrimaryColor() {
126         return mPrimaryColor;
127     }
128 
getMediaClientPrimaryColorDark()129     public int getMediaClientPrimaryColorDark() {
130         return mPrimaryColorDark;
131     }
132 
getMediaClientAccentColor()133     public int getMediaClientAccentColor() {
134         return mAccentColor;
135     }
136 
fetchAppColors(String packageName, int appTheme, Context context)137     private void fetchAppColors(String packageName, int appTheme, Context context) {
138         TypedArray ta = null;
139         try {
140             Context packageContext = context.createPackageContext(packageName, 0);
141             packageContext.setTheme(appTheme);
142             Resources.Theme theme = packageContext.getTheme();
143             ta = theme.obtainStyledAttributes(new int[]{
144                     android.R.attr.colorPrimary,
145                     android.R.attr.colorAccent,
146                     android.R.attr.colorPrimaryDark
147             });
148             int defaultColor =
149                     context.getColor(android.R.color.holo_green_light);
150             mPrimaryColor = ta.getColor(0, defaultColor);
151             mAccentColor = ta.getColor(1, defaultColor);
152             mPrimaryColorDark = ta.getColor(2, defaultColor);
153         } catch (PackageManager.NameNotFoundException e) {
154             Log.e(TAG, "Unable to update media client package attributes.", e);
155         } finally {
156             if (ta != null) {
157                 ta.recycle();
158             }
159         }
160     }
161 }