2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com
.android
.setupwizardlib
.util
;
19 import android
.content
.Context
;
20 import android
.content
.Intent
;
21 import android
.content
.pm
.ApplicationInfo
;
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
.graphics
.drawable
.Drawable
;
27 import android
.util
.Log
;
29 import com
.android
.setupwizardlib
.annotations
.VisibleForTesting
;
32 * Utilities to discover and interact with partner customizations. There can only be one set of
33 * customizations on a device, and it must be bundled with the system.
35 * Derived from com.android.launcher3/Partner.java
37 public class Partner
{
38 private static final String TAG
= "(SUW) Partner";
40 /** Marker action used to discover partner */
41 private static final String
42 ACTION_PARTNER_CUSTOMIZATION
= "com.android.setupwizard.action.PARTNER_CUSTOMIZATION";
44 private static boolean sSearched
= false;
45 private static Partner sPartner
;
48 * Convenience to get a drawable from partner overlay, or if not available, the drawable from
49 * the original context.
51 * @see #getResourceEntry(android.content.Context, int)
53 public static Drawable
getDrawable(Context context
, int id
) {
54 final ResourceEntry entry
= getResourceEntry(context
, id
);
55 return entry
.resources
.getDrawable(entry
.id
);
59 * Convenience to get a string from partner overlay, or if not available, the string from the
62 * @see #getResourceEntry(android.content.Context, int)
64 public static String
getString(Context context
, int id
) {
65 final ResourceEntry entry
= getResourceEntry(context
, id
);
66 return entry
.resources
.getString(entry
.id
);
70 * Find an entry of resource in the overlay package provided by partners. It will first look for
71 * the resource in the overlay package, and if not available, will return the one in the
74 * @return a ResourceEntry in the partner overlay's resources, if one is defined. Otherwise the
75 * resources from the original context is returned. Clients can then get the resource by
76 * {@code entry.resources.getString(entry.id)}, or other methods available in
77 * {@link android.content.res.Resources}.
79 public static ResourceEntry
getResourceEntry(Context context
, int id
) {
80 final Partner partner
= Partner
.get(context
);
81 if (partner
!= null) {
82 final Resources ourResources
= context
.getResources();
83 final String name
= ourResources
.getResourceEntryName(id
);
84 final String type
= ourResources
.getResourceTypeName(id
);
85 final int partnerId
= partner
.getIdentifier(name
, type
);
87 return new ResourceEntry(partner
.mResources
, partnerId
, true);
90 return new ResourceEntry(context
.getResources(), id
, false);
93 public static class ResourceEntry
{
94 public Resources resources
;
96 public boolean isOverlay
;
98 ResourceEntry(Resources resources
, int id
, boolean isOverlay
) {
99 this.resources
= resources
;
101 this.isOverlay
= isOverlay
;
106 * Find and return partner details, or {@code null} if none exists. A partner package is marked
107 * by a broadcast receiver declared in the manifest that handles the
108 * com.android.setupwizard.action.PARTNER_CUSTOMIZATION intent action. The overlay package must
109 * also be a system package.
111 public static synchronized Partner
get(Context context
) {
113 PackageManager pm
= context
.getPackageManager();
114 final Intent intent
= new Intent(ACTION_PARTNER_CUSTOMIZATION
);
115 for (ResolveInfo info
: pm
.queryBroadcastReceivers(intent
, 0)) {
116 if (info
.activityInfo
== null) {
119 final ApplicationInfo appInfo
= info
.activityInfo
.applicationInfo
;
120 if ((appInfo
.flags
& ApplicationInfo
.FLAG_SYSTEM
) != 0) {
122 final Resources res
= pm
.getResourcesForApplication(appInfo
);
123 sPartner
= new Partner(appInfo
.packageName
, res
);
125 } catch (NameNotFoundException e
) {
126 Log
.w(TAG
, "Failed to find resources for " + appInfo
.packageName
);
136 public static synchronized void resetForTesting() {
141 private final String mPackageName
;
142 private final Resources mResources
;
144 private Partner(String packageName
, Resources res
) {
145 mPackageName
= packageName
;
149 public String
getPackageName() {
153 public Resources
getResources() {
157 public int getIdentifier(String name
, String defType
) {
158 return mResources
.getIdentifier(name
, defType
, mPackageName
);