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.systemui.statusbar.policy;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.content.pm.ResolveInfo;
23 import android.os.UserHandle;
24 import android.util.Log;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 
28 import com.android.internal.widget.LockPatternUtils;
29 import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
30 
31 import java.util.List;
32 
33 /**
34  * Utility class to inflate previews for phone and camera affordance.
35  */
36 public class PreviewInflater {
37 
38     private static final String TAG = "PreviewInflater";
39 
40     private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
41 
42     private Context mContext;
43     private LockPatternUtils mLockPatternUtils;
44 
PreviewInflater(Context context, LockPatternUtils lockPatternUtils)45     public PreviewInflater(Context context, LockPatternUtils lockPatternUtils) {
46         mContext = context;
47         mLockPatternUtils = lockPatternUtils;
48     }
49 
inflatePreview(Intent intent)50     public View inflatePreview(Intent intent) {
51         WidgetInfo info = getWidgetInfo(intent);
52         if (info == null) {
53             return null;
54         }
55         View v = inflateWidgetView(info);
56         if (v == null) {
57             return null;
58         }
59         KeyguardPreviewContainer container = new KeyguardPreviewContainer(mContext, null);
60         container.addView(v);
61         return container;
62     }
63 
inflateWidgetView(WidgetInfo widgetInfo)64     private View inflateWidgetView(WidgetInfo widgetInfo) {
65         View widgetView = null;
66         try {
67             Context appContext = mContext.createPackageContext(
68                     widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
69             LayoutInflater appInflater = (LayoutInflater)
70                     appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
71             appInflater = appInflater.cloneInContext(appContext);
72             widgetView = appInflater.inflate(widgetInfo.layoutId, null, false);
73         } catch (PackageManager.NameNotFoundException|RuntimeException e) {
74             Log.w(TAG, "Error creating widget view", e);
75         }
76         return widgetView;
77     }
78 
getWidgetInfo(Intent intent)79     private WidgetInfo getWidgetInfo(Intent intent) {
80         WidgetInfo info = new WidgetInfo();
81         PackageManager packageManager = mContext.getPackageManager();
82         final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
83                 intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
84         if (appList.size() == 0) {
85             return null;
86         }
87         ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
88                 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
89                 mLockPatternUtils.getCurrentUser());
90         if (wouldLaunchResolverActivity(resolved, appList)) {
91             return null;
92         }
93         if (resolved == null || resolved.activityInfo == null) {
94             return null;
95         }
96         if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
97             return null;
98         }
99         int layoutId = resolved.activityInfo.metaData.getInt(META_DATA_KEYGUARD_LAYOUT);
100         if (layoutId == 0) {
101             return null;
102         }
103         info.contextPackage = resolved.activityInfo.packageName;
104         info.layoutId = layoutId;
105         return info;
106     }
107 
wouldLaunchResolverActivity(Context ctx, Intent intent, int currentUserId)108     public static boolean wouldLaunchResolverActivity(Context ctx, Intent intent,
109             int currentUserId) {
110         PackageManager packageManager = ctx.getPackageManager();
111         final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
112                 intent, PackageManager.MATCH_DEFAULT_ONLY, currentUserId);
113         if (appList.size() == 0) {
114             return false;
115         }
116         ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
117                 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, currentUserId);
118         return wouldLaunchResolverActivity(resolved, appList);
119     }
120 
wouldLaunchResolverActivity( ResolveInfo resolved, List<ResolveInfo> appList)121     private static boolean wouldLaunchResolverActivity(
122             ResolveInfo resolved, List<ResolveInfo> appList) {
123         // If the list contains the above resolved activity, then it can't be
124         // ResolverActivity itself.
125         for (int i = 0; i < appList.size(); i++) {
126             ResolveInfo tmp = appList.get(i);
127             if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
128                     && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
129                 return false;
130             }
131         }
132         return true;
133     }
134 
135     private static class WidgetInfo {
136         String contextPackage;
137         int layoutId;
138     }
139 }
140