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.android.launcher3.util;
18 
19 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
20 
21 import android.content.Intent;
22 import android.content.pm.PackageManager;
23 import android.content.pm.PackageManager.NameNotFoundException;
24 import android.content.pm.ResolveInfo;
25 import android.content.res.Resources;
26 import android.util.Log;
27 import android.util.Pair;
28 
29 /**
30  * Utilities to discover and interact with partner customizations. There can
31  * only be one set of customizations on a device, and it must be bundled with
32  * the system.
33  */
34 public class Partner {
35 
36     static final String TAG = "Launcher.Partner";
37 
38     /** Marker action used to discover partner */
39     private static final String
40             ACTION_PARTNER_CUSTOMIZATION = "com.android.launcher3.action.PARTNER_CUSTOMIZATION";
41 
42     /**
43      * Find and return partner details, or {@code null} if none exists.
44      */
get(PackageManager pm)45     public static Partner get(PackageManager pm) {
46         return get(pm, ACTION_PARTNER_CUSTOMIZATION);
47     }
48 
49     /**
50      * Find and return partner details, or {@code null} if none exists.
51      */
get(PackageManager pm, String action)52     public static Partner get(PackageManager pm, String action) {
53         Pair<String, Resources> apkInfo = findSystemApk(action, pm);
54         return apkInfo != null ? new Partner(apkInfo.first, apkInfo.second) : null;
55     }
56 
57     private final String mPackageName;
58     private final Resources mResources;
59 
Partner(String packageName, Resources res)60     private Partner(String packageName, Resources res) {
61         mPackageName = packageName;
62         mResources = res;
63     }
64 
getPackageName()65     public String getPackageName() {
66         return mPackageName;
67     }
68 
getResources()69     public Resources getResources() {
70         return mResources;
71     }
72 
73     /**
74      * Returns the xml resource Id for the provided name, or 0 is the resource is not found
75      */
getXmlResId(String layoutName)76     public int getXmlResId(String layoutName) {
77         return getResources().getIdentifier(layoutName, "xml", getPackageName());
78     }
79 
80     /**
81      * Returns the integer resource value for the provided resource name,
82      * or default value if the resource name is not present
83      */
getIntValue(String resName, int defaultValue)84     public int getIntValue(String resName, int defaultValue) {
85         int resId = getResources().getIdentifier(resName, "integer", getPackageName());
86         return resId > 0 ? getResources().getInteger(resId) : defaultValue;
87     }
88 
89     /**
90      * Returns the dimension value for the provided resource name,
91      * or default value if the resource name is not present
92      */
getDimenValue(String resName, int defaultValue)93     public float getDimenValue(String resName, int defaultValue) {
94         int resId = getResources().getIdentifier(resName, "dimen", getPackageName());
95         return resId > 0 ? getResources().getDimension(resId) : defaultValue;
96     }
97 
98     /**
99      * Finds a system apk which had a broadcast receiver listening to a particular action.
100      * @param action intent action used to find the apk
101      * @return a pair of apk package name and the resources.
102      */
findSystemApk(String action, PackageManager pm)103     private static Pair<String, Resources> findSystemApk(String action, PackageManager pm) {
104         final Intent intent = new Intent(action);
105         for (ResolveInfo info : pm.queryBroadcastReceivers(intent, MATCH_SYSTEM_ONLY)) {
106             final String packageName = info.activityInfo.packageName;
107             try {
108                 final Resources res = pm.getResourcesForApplication(packageName);
109                 return Pair.create(packageName, res);
110             } catch (NameNotFoundException e) {
111                 Log.w(TAG, "Failed to find resources for " + packageName);
112             }
113         }
114         return null;
115     }
116 }
117