1 /*
2  * Copyright (C) 2016 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.enterprise;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.content.pm.UserInfo;
26 import android.content.res.Resources;
27 import android.net.ConnectivityManager;
28 import android.os.UserHandle;
29 import android.os.UserManager;
30 import android.provider.Settings;
31 import android.text.SpannableStringBuilder;
32 import android.text.style.ClickableSpan;
33 import android.view.View;
34 
35 import com.android.settings.R;
36 import com.android.settings.vpn2.VpnUtils;
37 
38 import java.util.Date;
39 import java.util.List;
40 
41 public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFeatureProvider {
42 
43     private final Context mContext;
44     private final DevicePolicyManager mDpm;
45     private final PackageManager mPm;
46     private final UserManager mUm;
47     private final ConnectivityManager mCm;
48     private final Resources mResources;
49 
50     private static final int MY_USER_ID = UserHandle.myUserId();
51 
EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm, PackageManager pm, UserManager um, ConnectivityManager cm, Resources resources)52     public EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm,
53             PackageManager pm, UserManager um, ConnectivityManager cm,
54             Resources resources) {
55         mContext = context.getApplicationContext();
56         mDpm = dpm;
57         mPm = pm;
58         mUm = um;
59         mCm = cm;
60         mResources = resources;
61     }
62 
63     @Override
hasDeviceOwner()64     public boolean hasDeviceOwner() {
65         return getDeviceOwnerComponent() != null;
66     }
67 
68     @Override
isInCompMode()69     public boolean isInCompMode() {
70         return hasDeviceOwner() && getManagedProfileUserId() != UserHandle.USER_NULL;
71     }
72 
73     @Override
getDeviceOwnerOrganizationName()74     public String getDeviceOwnerOrganizationName() {
75         final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName();
76         if (organizationName == null) {
77             return null;
78         } else {
79             return organizationName.toString();
80         }
81     }
82 
83     @Override
getDeviceOwnerDisclosure()84     public CharSequence getDeviceOwnerDisclosure() {
85         if (!hasDeviceOwner()) {
86             return null;
87         }
88 
89         final SpannableStringBuilder disclosure = new SpannableStringBuilder();
90         final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName();
91         if (organizationName != null) {
92             disclosure.append(mResources.getString(R.string.do_disclosure_with_name,
93                     organizationName));
94         } else {
95             disclosure.append(mResources.getString(R.string.do_disclosure_generic));
96         }
97         disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
98         disclosure.append(mResources.getString(R.string.learn_more),
99                 new EnterprisePrivacySpan(mContext), 0);
100         return disclosure;
101     }
102 
103     @Override
getLastSecurityLogRetrievalTime()104     public Date getLastSecurityLogRetrievalTime() {
105         final long timestamp = mDpm.getLastSecurityLogRetrievalTime();
106         return timestamp < 0 ? null : new Date(timestamp);
107     }
108 
109     @Override
getLastBugReportRequestTime()110     public Date getLastBugReportRequestTime() {
111         final long timestamp = mDpm.getLastBugReportRequestTime();
112         return timestamp < 0 ? null : new Date(timestamp);
113     }
114 
115     @Override
getLastNetworkLogRetrievalTime()116     public Date getLastNetworkLogRetrievalTime() {
117         final long timestamp = mDpm.getLastNetworkLogRetrievalTime();
118         return timestamp < 0 ? null : new Date(timestamp);
119     }
120 
121     @Override
isSecurityLoggingEnabled()122     public boolean isSecurityLoggingEnabled() {
123         return mDpm.isSecurityLoggingEnabled(null);
124     }
125 
126     @Override
isNetworkLoggingEnabled()127     public boolean isNetworkLoggingEnabled() {
128         return mDpm.isNetworkLoggingEnabled(null);
129     }
130 
131     @Override
isAlwaysOnVpnSetInCurrentUser()132     public boolean isAlwaysOnVpnSetInCurrentUser() {
133         return VpnUtils.isAlwaysOnVpnSet(mCm, MY_USER_ID);
134     }
135 
136     @Override
isAlwaysOnVpnSetInManagedProfile()137     public boolean isAlwaysOnVpnSetInManagedProfile() {
138         final int managedProfileUserId = getManagedProfileUserId();
139         return managedProfileUserId != UserHandle.USER_NULL &&
140                 VpnUtils.isAlwaysOnVpnSet(mCm, managedProfileUserId);
141     }
142 
143     @Override
isGlobalHttpProxySet()144     public boolean isGlobalHttpProxySet() {
145         return mCm.getGlobalProxy() != null;
146     }
147 
148     @Override
getMaximumFailedPasswordsBeforeWipeInCurrentUser()149     public int getMaximumFailedPasswordsBeforeWipeInCurrentUser() {
150         ComponentName owner = mDpm.getDeviceOwnerComponentOnCallingUser();
151         if (owner == null) {
152             owner = mDpm.getProfileOwnerAsUser(MY_USER_ID);
153         }
154         if (owner == null) {
155             return 0;
156         }
157         return mDpm.getMaximumFailedPasswordsForWipe(owner, MY_USER_ID);
158     }
159 
160     @Override
getMaximumFailedPasswordsBeforeWipeInManagedProfile()161     public int getMaximumFailedPasswordsBeforeWipeInManagedProfile() {
162         final int userId = getManagedProfileUserId();
163         if (userId == UserHandle.USER_NULL) {
164             return 0;
165         }
166         final ComponentName profileOwner = mDpm.getProfileOwnerAsUser(userId);
167         if (profileOwner == null) {
168             return 0;
169         }
170         return mDpm.getMaximumFailedPasswordsForWipe(profileOwner, userId);
171     }
172 
173     @Override
getImeLabelIfOwnerSet()174     public String getImeLabelIfOwnerSet() {
175         if (!mDpm.isCurrentInputMethodSetByOwner()) {
176             return null;
177         }
178         final String packageName = Settings.Secure.getStringForUser(mContext.getContentResolver(),
179                 Settings.Secure.DEFAULT_INPUT_METHOD, MY_USER_ID);
180         if (packageName == null) {
181             return null;
182         }
183         try {
184             return mPm.getApplicationInfoAsUser(packageName, 0 /* flags */, MY_USER_ID)
185                     .loadLabel(mPm).toString();
186         } catch (PackageManager.NameNotFoundException e) {
187             return null;
188         }
189     }
190 
191     @Override
getNumberOfOwnerInstalledCaCertsForCurrentUser()192     public int getNumberOfOwnerInstalledCaCertsForCurrentUser() {
193         final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(MY_USER_ID));
194         if (certs == null) {
195             return 0;
196         }
197         return certs.size();
198     }
199 
200     @Override
getNumberOfOwnerInstalledCaCertsForManagedProfile()201     public int getNumberOfOwnerInstalledCaCertsForManagedProfile() {
202         final int userId = getManagedProfileUserId();
203         if (userId == UserHandle.USER_NULL) {
204             return 0;
205         }
206         final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(userId));
207         if (certs == null) {
208             return 0;
209         }
210         return certs.size();
211     }
212 
213     @Override
getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile()214     public int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile() {
215         int activeAdmins = 0;
216         for (final UserInfo userInfo : mUm.getProfiles(MY_USER_ID)) {
217             final List<ComponentName> activeAdminsForUser
218                     = mDpm.getActiveAdminsAsUser(userInfo.id);
219             if (activeAdminsForUser != null) {
220                 activeAdmins += activeAdminsForUser.size();
221             }
222         }
223         return activeAdmins;
224     }
225 
226     @Override
hasWorkPolicyInfo()227     public boolean hasWorkPolicyInfo() {
228         return (getWorkPolicyInfoIntentDO() != null) || (getWorkPolicyInfoIntentPO() != null);
229     }
230 
231     @Override
showWorkPolicyInfo()232     public boolean showWorkPolicyInfo() {
233         Intent intent = getWorkPolicyInfoIntentDO();
234         if (intent != null) {
235             mContext.startActivity(intent);
236             return true;
237         }
238 
239         intent = getWorkPolicyInfoIntentPO();
240         final UserInfo userInfo = getManagedProfileUserInfo();
241         if (intent != null && userInfo != null) {
242             mContext.startActivityAsUser(intent, userInfo.getUserHandle());
243             return true;
244         }
245 
246         return false;
247     }
248 
getDeviceOwnerComponent()249     private ComponentName getDeviceOwnerComponent() {
250         if (!mPm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
251             return null;
252         }
253         return mDpm.getDeviceOwnerComponentOnAnyUser();
254     }
255 
getManagedProfileUserInfo()256     private UserInfo getManagedProfileUserInfo() {
257         for (final UserInfo userInfo : mUm.getProfiles(MY_USER_ID)) {
258             if (userInfo.isManagedProfile()) {
259                 return userInfo;
260             }
261         }
262         return null;
263     }
264 
getManagedProfileUserId()265     private int getManagedProfileUserId() {
266         final UserInfo userInfo = getManagedProfileUserInfo();
267         if (userInfo != null) {
268             return userInfo.id;
269         }
270         return UserHandle.USER_NULL;
271     }
272 
getWorkPolicyInfoIntentDO()273     private Intent getWorkPolicyInfoIntentDO() {
274         final ComponentName ownerComponent = getDeviceOwnerComponent();
275         if (ownerComponent == null) {
276             return null;
277         }
278 
279         // Only search for the required action in the Device Owner's package
280         final Intent intent =
281                 new Intent(mResources.getString(R.string.config_work_policy_info_intent_action))
282                         .setPackage(ownerComponent.getPackageName())
283                         .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
284         final List<ResolveInfo> activities = mPm.queryIntentActivities(intent, 0);
285         if (activities.size() != 0) {
286             return intent;
287         }
288 
289         return null;
290     }
291 
getWorkPolicyInfoIntentPO()292     private Intent getWorkPolicyInfoIntentPO() {
293         final int userId = getManagedProfileUserId();
294         if (userId == UserHandle.USER_NULL) {
295             return null;
296         }
297 
298         final ComponentName ownerComponent = mDpm.getProfileOwnerAsUser(userId);
299         if (ownerComponent == null) {
300             return null;
301         }
302 
303         // Only search for the required action in the Profile Owner's package
304         final Intent intent =
305                 new Intent(mResources.getString(R.string.config_work_policy_info_intent_action))
306                         .setPackage(ownerComponent.getPackageName())
307                         .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
308         final List<ResolveInfo> activities = mPm.queryIntentActivitiesAsUser(intent, 0, userId);
309         if (activities.size() != 0) {
310             return intent;
311         }
312 
313         return null;
314     }
315 
316     protected static class EnterprisePrivacySpan extends ClickableSpan {
317         private final Context mContext;
318 
EnterprisePrivacySpan(Context context)319         public EnterprisePrivacySpan(Context context) {
320             mContext = context;
321         }
322 
323         @Override
onClick(View widget)324         public void onClick(View widget) {
325             mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS)
326                     .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
327         }
328 
329         @Override
equals(Object object)330         public boolean equals(Object object) {
331             return object instanceof EnterprisePrivacySpan
332                     && ((EnterprisePrivacySpan) object).mContext == mContext;
333         }
334     }
335 }
336