blob: 12b7b908813947afd8b32c63df906f7517b3af47 [file] [log] [blame]
Robin Lee2bd92d52015-04-09 17:13:08 +01001/*
2 * Copyright (C) 2015 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
17package com.android.settings.vpn2;
18
Pavel Grafov16d588c2021-03-18 22:46:08 +000019import android.app.admin.DevicePolicyManager;
Robin Lee2bd92d52015-04-09 17:13:08 +010020import android.content.Context;
Robin Lee2bd92d52015-04-09 17:13:08 +010021import android.content.pm.PackageInfo;
22import android.content.pm.PackageManager;
23import android.graphics.drawable.Drawable;
Robin Lee2bd92d52015-04-09 17:13:08 +010024import android.os.UserHandle;
Robin Lee2bd92d52015-04-09 17:13:08 +010025
Fan Zhang23f8d592018-08-28 15:11:40 -070026import androidx.preference.Preference;
27
Robin Lee2bd92d52015-04-09 17:13:08 +010028import com.android.internal.net.LegacyVpnInfo;
29import com.android.internal.net.VpnConfig;
Pavel Grafov16d588c2021-03-18 22:46:08 +000030import com.android.settingslib.RestrictedLockUtils;
31import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
Bonian Chen61c45062023-01-09 08:10:11 +000032import com.android.settings.R;
Robin Lee2bd92d52015-04-09 17:13:08 +010033
34/**
Aurimas Liutikase0069d32018-04-17 11:22:43 -070035 * {@link androidx.preference.Preference} containing information about a VPN
Robin Lee2bd92d52015-04-09 17:13:08 +010036 * application. Tracks the package name and connection state.
37 */
38public class AppPreference extends ManageablePreference {
39 public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED;
Robin Leee06d7572016-04-19 12:29:02 +010040 public static final int STATE_DISCONNECTED = STATE_NONE;
Robin Lee2bd92d52015-04-09 17:13:08 +010041
Robin Leeb166ea22016-04-21 12:56:21 +010042 private final String mPackageName;
43 private final String mName;
Robin Lee2bd92d52015-04-09 17:13:08 +010044
Robin Leeb166ea22016-04-21 12:56:21 +010045 public AppPreference(Context context, int userId, String packageName) {
Bonian Chen61c45062023-01-09 08:10:11 +000046 super(context, null /* attrs */, R.style.VpnAppManagementPreferenceStyle, 0);
Victor Chang14c2ac42016-03-15 18:48:08 +000047 super.setUserId(userId);
Robin Leeb166ea22016-04-21 12:56:21 +010048
49 mPackageName = packageName;
Pavel Grafov16d588c2021-03-18 22:46:08 +000050 disableIfConfiguredByAdmin();
Robin Leeb166ea22016-04-21 12:56:21 +010051
52 // Fetch icon and VPN label
53 String label = packageName;
54 Drawable icon = null;
55 try {
56 // Make all calls to the package manager as the appropriate user.
57 Context userContext = getUserContext();
58 PackageManager pm = userContext.getPackageManager();
59 // The nested catch block is for the case that the app doesn't exist, so we can fall
60 // back to the default activity icon.
61 try {
62 PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */);
63 if (pkgInfo != null) {
64 icon = pkgInfo.applicationInfo.loadIcon(pm);
65 label = VpnConfig.getVpnLabel(userContext, mPackageName).toString();
66 }
67 } catch (PackageManager.NameNotFoundException pkgNotFound) {
68 // Use default app label and icon as fallback
69 }
70 if (icon == null) {
71 icon = pm.getDefaultActivityIcon();
72 }
73 } catch (PackageManager.NameNotFoundException userNotFound) {
74 // No user, no useful information to obtain. Quietly fail.
75 }
76 mName = label;
77
78 setTitle(mName);
79 setIcon(icon);
Robin Lee2bd92d52015-04-09 17:13:08 +010080 }
81
Pavel Grafov16d588c2021-03-18 22:46:08 +000082 /**
83 * Disable this preference if VPN is set as always on by a profile or device owner.
84 * NB: it should be called after super.setUserId() otherwise admin information can be lost.
85 */
86 private void disableIfConfiguredByAdmin() {
87 if (isDisabledByAdmin()) {
88 // Already disabled due to user restriction.
89 return;
90 }
91 final DevicePolicyManager dpm = getContext()
92 .createContextAsUser(UserHandle.of(getUserId()), /* flags= */ 0)
93 .getSystemService(DevicePolicyManager.class);
94 if (mPackageName.equals(dpm.getAlwaysOnVpnPackage())) {
95 final EnforcedAdmin admin = RestrictedLockUtils.getProfileOrDeviceOwner(
96 getContext(), UserHandle.of(mUserId));
97 setDisabledByAdmin(admin);
98 }
99 }
100
Robin Lee2bd92d52015-04-09 17:13:08 +0100101 public PackageInfo getPackageInfo() {
Robin Lee2bd92d52015-04-09 17:13:08 +0100102 try {
Robin Leeab6a65c2015-05-01 17:42:30 +0100103 PackageManager pm = getUserContext().getPackageManager();
104 return pm.getPackageInfo(mPackageName, 0 /* flags */);
105 } catch (PackageManager.NameNotFoundException nnfe) {
Robin Lee2bd92d52015-04-09 17:13:08 +0100106 return null;
107 }
108 }
109
Robin Leeab6a65c2015-05-01 17:42:30 +0100110 public String getLabel() {
111 return mName;
112 }
113
Robin Lee2bd92d52015-04-09 17:13:08 +0100114 public String getPackageName() {
115 return mPackageName;
116 }
117
Robin Leeab6a65c2015-05-01 17:42:30 +0100118 private Context getUserContext() throws PackageManager.NameNotFoundException {
Robin Lee7bf86542015-11-16 15:24:36 +0000119 UserHandle user = UserHandle.of(mUserId);
Robin Leeab6a65c2015-05-01 17:42:30 +0100120 return getContext().createPackageContextAsUser(
121 getContext().getPackageName(), 0 /* flags */, user);
122 }
123
Robin Lee2bd92d52015-04-09 17:13:08 +0100124 public int compareTo(Preference preference) {
125 if (preference instanceof AppPreference) {
126 AppPreference another = (AppPreference) preference;
127 int result;
128 if ((result = another.mState - mState) == 0 &&
129 (result = mName.compareToIgnoreCase(another.mName)) == 0 &&
130 (result = mPackageName.compareTo(another.mPackageName)) == 0) {
Robin Lee7bf86542015-11-16 15:24:36 +0000131 result = mUserId - another.mUserId;
Robin Lee2bd92d52015-04-09 17:13:08 +0100132 }
133 return result;
Victor Chang14c2ac42016-03-15 18:48:08 +0000134 } else if (preference instanceof LegacyVpnPreference) {
Robin Lee2bd92d52015-04-09 17:13:08 +0100135 // Use comparator from ConfigPreference
Victor Chang14c2ac42016-03-15 18:48:08 +0000136 LegacyVpnPreference another = (LegacyVpnPreference) preference;
Robin Lee2bd92d52015-04-09 17:13:08 +0100137 return -another.compareTo(this);
138 } else {
139 return super.compareTo(preference);
140 }
141 }
142}
143