1/*
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
19import android.content.Context;
20import android.content.pm.PackageInfo;
21import android.content.pm.PackageManager;
22import android.graphics.drawable.Drawable;
23import android.os.UserHandle;
24import android.support.v7.preference.Preference;
25
26import com.android.internal.net.LegacyVpnInfo;
27import com.android.internal.net.VpnConfig;
28
29/**
30 * {@link android.support.v7.preference.Preference} containing information about a VPN
31 * application. Tracks the package name and connection state.
32 */
33public class AppPreference extends ManageablePreference {
34    public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED;
35    public static final int STATE_DISCONNECTED = STATE_NONE;
36
37    private final String mPackageName;
38    private final String mName;
39
40    public AppPreference(Context context, int userId, String packageName) {
41        super(context, null /* attrs */);
42        super.setUserId(userId);
43
44        mPackageName = packageName;
45
46        // Fetch icon and VPN label
47        String label = packageName;
48        Drawable icon = null;
49        try {
50            // Make all calls to the package manager as the appropriate user.
51            Context userContext = getUserContext();
52            PackageManager pm = userContext.getPackageManager();
53            // The nested catch block is for the case that the app doesn't exist, so we can fall
54            // back to the default activity icon.
55            try {
56                PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */);
57                if (pkgInfo != null) {
58                    icon = pkgInfo.applicationInfo.loadIcon(pm);
59                    label = VpnConfig.getVpnLabel(userContext, mPackageName).toString();
60                }
61            } catch (PackageManager.NameNotFoundException pkgNotFound) {
62                // Use default app label and icon as fallback
63            }
64            if (icon == null) {
65                icon = pm.getDefaultActivityIcon();
66            }
67        } catch (PackageManager.NameNotFoundException userNotFound) {
68            // No user, no useful information to obtain. Quietly fail.
69        }
70        mName = label;
71
72        setTitle(mName);
73        setIcon(icon);
74    }
75
76    public PackageInfo getPackageInfo() {
77        try {
78            PackageManager pm = getUserContext().getPackageManager();
79            return pm.getPackageInfo(mPackageName, 0 /* flags */);
80        } catch (PackageManager.NameNotFoundException nnfe) {
81            return null;
82        }
83    }
84
85    public String getLabel() {
86        return mName;
87    }
88
89    public String getPackageName() {
90        return mPackageName;
91    }
92
93    private Context getUserContext() throws PackageManager.NameNotFoundException {
94        UserHandle user = UserHandle.of(mUserId);
95        return getContext().createPackageContextAsUser(
96                getContext().getPackageName(), 0 /* flags */, user);
97    }
98
99    public int compareTo(Preference preference) {
100        if (preference instanceof AppPreference) {
101            AppPreference another = (AppPreference) preference;
102            int result;
103            if ((result = another.mState - mState) == 0 &&
104                    (result = mName.compareToIgnoreCase(another.mName)) == 0 &&
105                    (result = mPackageName.compareTo(another.mPackageName)) == 0) {
106                result = mUserId - another.mUserId;
107            }
108            return result;
109        } else if (preference instanceof LegacyVpnPreference) {
110            // Use comparator from ConfigPreference
111            LegacyVpnPreference another = (LegacyVpnPreference) preference;
112            return -another.compareTo(this);
113        } else {
114            return super.compareTo(preference);
115        }
116    }
117}
118
119