1 /*
2  * Copyright (C) 2011 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.vpndialogs;
18 
19 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
20 
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.pm.PackageManager;
24 import android.graphics.drawable.Drawable;
25 import android.net.IConnectivityManager;
26 import android.os.Bundle;
27 import android.os.RemoteException;
28 import android.os.ServiceManager;
29 import android.os.UserHandle;
30 import android.os.UserManager;
31 import android.text.Html;
32 import android.text.Html.ImageGetter;
33 import android.util.Log;
34 import android.util.TypedValue;
35 import android.view.View;
36 import android.widget.Button;
37 import android.widget.TextView;
38 
39 import com.android.internal.app.AlertActivity;
40 import com.android.internal.net.VpnConfig;
41 
42 public class ConfirmDialog extends AlertActivity
43         implements DialogInterface.OnClickListener, ImageGetter {
44     private static final String TAG = "VpnConfirm";
45 
46     private String mPackage;
47 
48     private IConnectivityManager mService;
49 
50     @Override
onCreate(Bundle savedInstanceState)51     protected void onCreate(Bundle savedInstanceState) {
52         super.onCreate(savedInstanceState);
53         mPackage = getCallingPackage();
54         mService = IConnectivityManager.Stub.asInterface(
55                 ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
56 
57         if (prepareVpn()) {
58             setResult(RESULT_OK);
59             finish();
60             return;
61         }
62         if (UserManager.get(this).hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
63             finish();
64             return;
65         }
66         final String alwaysOnVpnPackage = getAlwaysOnVpnPackage();
67         // Can't prepare new vpn app when another vpn is always-on
68         if (alwaysOnVpnPackage != null && !alwaysOnVpnPackage.equals(mPackage)) {
69             finish();
70             return;
71         }
72         View view = View.inflate(this, R.layout.confirm, null);
73         ((TextView) view.findViewById(R.id.warning)).setText(
74                 Html.fromHtml(getString(R.string.warning, getVpnLabel()),
75                         this, null /* tagHandler */));
76         mAlertParams.mTitle = getText(R.string.prompt);
77         mAlertParams.mPositiveButtonText = getText(android.R.string.ok);
78         mAlertParams.mPositiveButtonListener = this;
79         mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
80         mAlertParams.mView = view;
81         setupAlert();
82 
83         getWindow().setCloseOnTouchOutside(false);
84         getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
85         Button button = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
86         button.setFilterTouchesWhenObscured(true);
87     }
88 
getAlwaysOnVpnPackage()89     private String getAlwaysOnVpnPackage() {
90         try {
91            return mService.getAlwaysOnVpnPackage(UserHandle.myUserId());
92         } catch (RemoteException e) {
93             Log.e(TAG, "fail to call getAlwaysOnVpnPackage", e);
94             // Fallback to null to show the dialog
95             return null;
96         }
97     }
98 
prepareVpn()99     private boolean prepareVpn() {
100         try {
101             return mService.prepareVpn(mPackage, null, UserHandle.myUserId());
102         } catch (RemoteException e) {
103             throw new IllegalStateException(e);
104         }
105     }
106 
getVpnLabel()107     private CharSequence getVpnLabel() {
108         try {
109             return VpnConfig.getVpnLabel(this, mPackage);
110         } catch (PackageManager.NameNotFoundException e) {
111             throw new IllegalStateException(e);
112         }
113     }
114 
115     @Override
getDrawable(String source)116     public Drawable getDrawable(String source) {
117         // Should only reach this when fetching the VPN icon for the warning string.
118         final Drawable icon = getDrawable(R.drawable.ic_vpn_dialog);
119         icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
120 
121         final TypedValue tv = new TypedValue();
122         if (getTheme().resolveAttribute(android.R.attr.textColorPrimary, tv, true)) {
123             icon.setTint(getColor(tv.resourceId));
124         } else {
125             Log.w(TAG, "Unable to resolve theme color");
126         }
127 
128         return icon;
129     }
130 
131     @Override
onBackPressed()132     public void onBackPressed() {
133     }
134 
135     @Override
onClick(DialogInterface dialog, int which)136     public void onClick(DialogInterface dialog, int which) {
137         try {
138             if (mService.prepareVpn(null, mPackage, UserHandle.myUserId())) {
139                 // Authorize this app to initiate VPN connections in the future without user
140                 // intervention.
141                 mService.setVpnPackageAuthorization(mPackage, UserHandle.myUserId(), true);
142                 setResult(RESULT_OK);
143             }
144         } catch (Exception e) {
145             Log.e(TAG, "onClick", e);
146         }
147     }
148 }
149