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;
18 
19 import static com.android.launcher3.util.PackageManagerHelper.findSystemApk;
20 
21 import android.content.pm.PackageManager;
22 import android.content.res.Resources;
23 import android.util.DisplayMetrics;
24 import android.util.Log;
25 import android.util.Pair;
26 
27 import java.io.File;
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     public static final String RES_FOLDER = "partner_folder";
43     public static final String RES_WALLPAPERS = "partner_wallpapers";
44     public static final String RES_DEFAULT_LAYOUT = "partner_default_layout";
45 
46     public static final String RES_DEFAULT_WALLPAPER_HIDDEN = "default_wallpapper_hidden";
47     public static final String RES_SYSTEM_WALLPAPER_DIR = "system_wallpaper_directory";
48 
49     public static final String RES_REQUIRE_FIRST_RUN_FLOW = "requires_first_run_flow";
50 
51     /** These resources are used to override the device profile  */
52     public static final String RES_GRID_NUM_ROWS = "grid_num_rows";
53     public static final String RES_GRID_NUM_COLUMNS = "grid_num_columns";
54     public static final String RES_GRID_ICON_SIZE_DP = "grid_icon_size_dp";
55 
56     /**
57      * Find and return partner details, or {@code null} if none exists.
58      */
get(PackageManager pm)59     public static synchronized Partner get(PackageManager pm) {
60         Pair<String, Resources> apkInfo = findSystemApk(ACTION_PARTNER_CUSTOMIZATION, pm);
61         return apkInfo != null ? new Partner(apkInfo.first, apkInfo.second) : null;
62     }
63 
64     private final String mPackageName;
65     private final Resources mResources;
66 
Partner(String packageName, Resources res)67     private Partner(String packageName, Resources res) {
68         mPackageName = packageName;
69         mResources = res;
70     }
71 
getPackageName()72     public String getPackageName() {
73         return mPackageName;
74     }
75 
getResources()76     public Resources getResources() {
77         return mResources;
78     }
79 
hasDefaultLayout()80     public boolean hasDefaultLayout() {
81         int defaultLayout = getResources().getIdentifier(Partner.RES_DEFAULT_LAYOUT,
82                 "xml", getPackageName());
83         return defaultLayout != 0;
84     }
85 
hasFolder()86     public boolean hasFolder() {
87         int folder = getResources().getIdentifier(Partner.RES_FOLDER,
88                 "xml", getPackageName());
89         return folder != 0;
90     }
91 
hideDefaultWallpaper()92     public boolean hideDefaultWallpaper() {
93         int resId = getResources().getIdentifier(RES_DEFAULT_WALLPAPER_HIDDEN, "bool",
94                 getPackageName());
95         return resId != 0 && getResources().getBoolean(resId);
96     }
97 
getWallpaperDirectory()98     public File getWallpaperDirectory() {
99         int resId = getResources().getIdentifier(RES_SYSTEM_WALLPAPER_DIR, "string",
100                 getPackageName());
101         return (resId != 0) ? new File(getResources().getString(resId)) : null;
102     }
103 
requiresFirstRunFlow()104     public boolean requiresFirstRunFlow() {
105         int resId = getResources().getIdentifier(RES_REQUIRE_FIRST_RUN_FLOW, "bool",
106                 getPackageName());
107         return resId != 0 && getResources().getBoolean(resId);
108     }
109 
applyInvariantDeviceProfileOverrides(InvariantDeviceProfile inv, DisplayMetrics dm)110     public void applyInvariantDeviceProfileOverrides(InvariantDeviceProfile inv, DisplayMetrics dm) {
111         int numRows = -1;
112         int numColumns = -1;
113         float iconSize = -1;
114 
115         try {
116             int resId = getResources().getIdentifier(RES_GRID_NUM_ROWS,
117                     "integer", getPackageName());
118             if (resId > 0) {
119                 numRows = getResources().getInteger(resId);
120             }
121 
122             resId = getResources().getIdentifier(RES_GRID_NUM_COLUMNS,
123                     "integer", getPackageName());
124             if (resId > 0) {
125                 numColumns = getResources().getInteger(resId);
126             }
127 
128             resId = getResources().getIdentifier(RES_GRID_ICON_SIZE_DP,
129                     "dimen", getPackageName());
130             if (resId > 0) {
131                 int px = getResources().getDimensionPixelSize(resId);
132                 iconSize = Utilities.dpiFromPx(px, dm);
133             }
134         } catch (Resources.NotFoundException ex) {
135             Log.e(TAG, "Invalid Partner grid resource!", ex);
136             return;
137         }
138 
139         if (numRows > 0 && numColumns > 0) {
140             inv.numRows = numRows;
141             inv.numColumns = numColumns;
142         }
143 
144         if (iconSize > 0) {
145             inv.iconSize = iconSize;
146         }
147     }
148 }
149