1 /* 2 * Copyright (C) 2019 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.car.developeroptions.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.UserInfo; 25 import android.content.res.Resources; 26 import android.net.ConnectivityManager; 27 import android.os.UserHandle; 28 import android.os.UserManager; 29 import android.provider.Settings; 30 import android.text.SpannableStringBuilder; 31 import android.text.style.ClickableSpan; 32 import android.view.View; 33 34 import com.android.car.developeroptions.R; 35 import com.android.car.developeroptions.vpn2.VpnUtils; 36 37 import java.util.Date; 38 import java.util.List; 39 40 public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFeatureProvider { 41 42 private final Context mContext; 43 private final DevicePolicyManager mDpm; 44 private final PackageManager mPm; 45 private final UserManager mUm; 46 private final ConnectivityManager mCm; 47 private final Resources mResources; 48 49 private static final int MY_USER_ID = UserHandle.myUserId(); 50 EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm, PackageManager pm, UserManager um, ConnectivityManager cm, Resources resources)51 public EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm, 52 PackageManager pm, UserManager um, ConnectivityManager cm, 53 Resources resources) { 54 mContext = context.getApplicationContext(); 55 mDpm = dpm; 56 mPm = pm; 57 mUm = um; 58 mCm = cm; 59 mResources = resources; 60 } 61 62 @Override hasDeviceOwner()63 public boolean hasDeviceOwner() { 64 if (!mPm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) { 65 return false; 66 } 67 return mDpm.getDeviceOwnerComponentOnAnyUser() != null; 68 } 69 getManagedProfileUserId()70 private int getManagedProfileUserId() { 71 for (final UserInfo userInfo : mUm.getProfiles(MY_USER_ID)) { 72 if (userInfo.isManagedProfile()) { 73 return userInfo.id; 74 } 75 } 76 return UserHandle.USER_NULL; 77 } 78 79 @Override isInCompMode()80 public boolean isInCompMode() { 81 return hasDeviceOwner() && getManagedProfileUserId() != UserHandle.USER_NULL; 82 } 83 84 @Override getDeviceOwnerOrganizationName()85 public String getDeviceOwnerOrganizationName() { 86 final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName(); 87 if (organizationName == null) { 88 return null; 89 } else { 90 return organizationName.toString(); 91 } 92 } 93 94 @Override getDeviceOwnerDisclosure()95 public CharSequence getDeviceOwnerDisclosure() { 96 if (!hasDeviceOwner()) { 97 return null; 98 } 99 100 final SpannableStringBuilder disclosure = new SpannableStringBuilder(); 101 final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName(); 102 if (organizationName != null) { 103 disclosure.append(mResources.getString(R.string.do_disclosure_with_name, 104 organizationName)); 105 } else { 106 disclosure.append(mResources.getString(R.string.do_disclosure_generic)); 107 } 108 disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator)); 109 disclosure.append(mResources.getString(R.string.learn_more), 110 new EnterprisePrivacySpan(mContext), 0); 111 return disclosure; 112 } 113 114 @Override getLastSecurityLogRetrievalTime()115 public Date getLastSecurityLogRetrievalTime() { 116 final long timestamp = mDpm.getLastSecurityLogRetrievalTime(); 117 return timestamp < 0 ? null : new Date(timestamp); 118 } 119 120 @Override getLastBugReportRequestTime()121 public Date getLastBugReportRequestTime() { 122 final long timestamp = mDpm.getLastBugReportRequestTime(); 123 return timestamp < 0 ? null : new Date(timestamp); 124 } 125 126 @Override getLastNetworkLogRetrievalTime()127 public Date getLastNetworkLogRetrievalTime() { 128 final long timestamp = mDpm.getLastNetworkLogRetrievalTime(); 129 return timestamp < 0 ? null : new Date(timestamp); 130 } 131 132 @Override isSecurityLoggingEnabled()133 public boolean isSecurityLoggingEnabled() { 134 return mDpm.isSecurityLoggingEnabled(null); 135 } 136 137 @Override isNetworkLoggingEnabled()138 public boolean isNetworkLoggingEnabled() { 139 return mDpm.isNetworkLoggingEnabled(null); 140 } 141 142 @Override isAlwaysOnVpnSetInCurrentUser()143 public boolean isAlwaysOnVpnSetInCurrentUser() { 144 return VpnUtils.isAlwaysOnVpnSet(mCm, MY_USER_ID); 145 } 146 147 @Override isAlwaysOnVpnSetInManagedProfile()148 public boolean isAlwaysOnVpnSetInManagedProfile() { 149 final int managedProfileUserId = getManagedProfileUserId(); 150 return managedProfileUserId != UserHandle.USER_NULL && 151 VpnUtils.isAlwaysOnVpnSet(mCm, managedProfileUserId); 152 } 153 154 @Override isGlobalHttpProxySet()155 public boolean isGlobalHttpProxySet() { 156 return mCm.getGlobalProxy() != null; 157 } 158 159 @Override getMaximumFailedPasswordsBeforeWipeInCurrentUser()160 public int getMaximumFailedPasswordsBeforeWipeInCurrentUser() { 161 ComponentName owner = mDpm.getDeviceOwnerComponentOnCallingUser(); 162 if (owner == null) { 163 owner = mDpm.getProfileOwnerAsUser(MY_USER_ID); 164 } 165 if (owner == null) { 166 return 0; 167 } 168 return mDpm.getMaximumFailedPasswordsForWipe(owner, MY_USER_ID); 169 } 170 171 @Override getMaximumFailedPasswordsBeforeWipeInManagedProfile()172 public int getMaximumFailedPasswordsBeforeWipeInManagedProfile() { 173 final int userId = getManagedProfileUserId(); 174 if (userId == UserHandle.USER_NULL) { 175 return 0; 176 } 177 final ComponentName profileOwner = mDpm.getProfileOwnerAsUser(userId); 178 if (profileOwner == null) { 179 return 0; 180 } 181 return mDpm.getMaximumFailedPasswordsForWipe(profileOwner, userId); 182 } 183 184 @Override getImeLabelIfOwnerSet()185 public String getImeLabelIfOwnerSet() { 186 if (!mDpm.isCurrentInputMethodSetByOwner()) { 187 return null; 188 } 189 final String packageName = Settings.Secure.getStringForUser(mContext.getContentResolver(), 190 Settings.Secure.DEFAULT_INPUT_METHOD, MY_USER_ID); 191 if (packageName == null) { 192 return null; 193 } 194 try { 195 return mPm.getApplicationInfoAsUser(packageName, 0 /* flags */, MY_USER_ID) 196 .loadLabel(mPm).toString(); 197 } catch (PackageManager.NameNotFoundException e) { 198 return null; 199 } 200 } 201 202 @Override getNumberOfOwnerInstalledCaCertsForCurrentUser()203 public int getNumberOfOwnerInstalledCaCertsForCurrentUser() { 204 final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(MY_USER_ID)); 205 if (certs == null) { 206 return 0; 207 } 208 return certs.size(); 209 } 210 211 @Override getNumberOfOwnerInstalledCaCertsForManagedProfile()212 public int getNumberOfOwnerInstalledCaCertsForManagedProfile() { 213 final int userId = getManagedProfileUserId(); 214 if (userId == UserHandle.USER_NULL) { 215 return 0; 216 } 217 final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(userId)); 218 if (certs == null) { 219 return 0; 220 } 221 return certs.size(); 222 } 223 224 @Override getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile()225 public int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile() { 226 int activeAdmins = 0; 227 for (final UserInfo userInfo : mUm.getProfiles(MY_USER_ID)) { 228 final List<ComponentName> activeAdminsForUser 229 = mDpm.getActiveAdminsAsUser(userInfo.id); 230 if (activeAdminsForUser != null) { 231 activeAdmins += activeAdminsForUser.size(); 232 } 233 } 234 return activeAdmins; 235 } 236 237 protected static class EnterprisePrivacySpan extends ClickableSpan { 238 private final Context mContext; 239 EnterprisePrivacySpan(Context context)240 public EnterprisePrivacySpan(Context context) { 241 mContext = context; 242 } 243 244 @Override onClick(View widget)245 public void onClick(View widget) { 246 mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS) 247 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 248 } 249 250 @Override equals(Object object)251 public boolean equals(Object object) { 252 return object instanceof EnterprisePrivacySpan 253 && ((EnterprisePrivacySpan) object).mContext == mContext; 254 } 255 } 256 } 257