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