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.settings;
18 
19 import android.content.ComponentName;
20 import android.content.pm.PackageManager;
21 import android.content.pm.ResolveInfo;
22 import android.content.res.Resources;
23 import android.content.res.TypedArray;
24 import android.content.res.XmlResourceParser;
25 import android.service.trust.TrustAgentService;
26 import android.util.AttributeSet;
27 import android.util.Log;
28 import android.util.Slog;
29 import android.util.Xml;
30 
31 import org.xmlpull.v1.XmlPullParser;
32 import org.xmlpull.v1.XmlPullParserException;
33 
34 import java.io.IOException;
35 
36 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
37 
38 public class TrustAgentUtils {
39     static final String TAG = "TrustAgentUtils";
40 
41     private static final String TRUST_AGENT_META_DATA = TrustAgentService.TRUST_AGENT_META_DATA;
42     private static final String PERMISSION_PROVIDE_AGENT = android.Manifest.permission.PROVIDE_TRUST_AGENT;
43 
44     /**
45      * @return true, if the service in resolveInfo has the permission to provide a trust agent.
46      */
checkProvidePermission(ResolveInfo resolveInfo, PackageManager pm)47     public static boolean checkProvidePermission(ResolveInfo resolveInfo, PackageManager pm) {
48         String packageName = resolveInfo.serviceInfo.packageName;
49         if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
50                 != PackageManager.PERMISSION_GRANTED) {
51             Log.w(TAG, "Skipping agent because package " + packageName
52                     + " does not have permission " + PERMISSION_PROVIDE_AGENT + ".");
53             return false;
54         }
55         return true;
56     }
57 
58     public static class TrustAgentComponentInfo {
59         ComponentName componentName;
60         String title;
61         String summary;
62         EnforcedAdmin admin = null;
63     }
64 
getComponentName(ResolveInfo resolveInfo)65     public static ComponentName getComponentName(ResolveInfo resolveInfo) {
66         if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
67         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
68     }
69 
getSettingsComponent( PackageManager pm, ResolveInfo resolveInfo)70     public static TrustAgentComponentInfo getSettingsComponent(
71             PackageManager pm, ResolveInfo resolveInfo) {
72         if (resolveInfo == null || resolveInfo.serviceInfo == null
73                 || resolveInfo.serviceInfo.metaData == null) return null;
74         String cn = null;
75         TrustAgentComponentInfo trustAgentComponentInfo = new TrustAgentComponentInfo();
76         XmlResourceParser parser = null;
77         Exception caughtException = null;
78         try {
79             parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, TRUST_AGENT_META_DATA);
80             if (parser == null) {
81                 Slog.w(TAG, "Can't find " + TRUST_AGENT_META_DATA + " meta-data");
82                 return null;
83             }
84             Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
85             AttributeSet attrs = Xml.asAttributeSet(parser);
86             int type;
87             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
88                     && type != XmlPullParser.START_TAG) {
89             }
90             String nodeName = parser.getName();
91             if (!"trust-agent".equals(nodeName)) {
92                 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
93                 return null;
94             }
95             TypedArray sa =
96                     res.obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
97             trustAgentComponentInfo.summary =
98                     sa.getString(com.android.internal.R.styleable.TrustAgent_summary);
99             trustAgentComponentInfo.title =
100                     sa.getString(com.android.internal.R.styleable.TrustAgent_title);
101             cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
102             sa.recycle();
103         } catch (PackageManager.NameNotFoundException e) {
104             caughtException = e;
105         } catch (IOException e) {
106             caughtException = e;
107         } catch (XmlPullParserException e) {
108             caughtException = e;
109         } finally {
110             if (parser != null) parser.close();
111         }
112         if (caughtException != null) {
113             Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
114             return null;
115         }
116         if (cn != null && cn.indexOf('/') < 0) {
117             cn = resolveInfo.serviceInfo.packageName + "/" + cn;
118         }
119         trustAgentComponentInfo.componentName = (cn == null) ? null : ComponentName.unflattenFromString(cn);
120         return trustAgentComponentInfo;
121     }
122 }
123