1 /*
2  * Copyright (C) 2017 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.FLAG_ALT_FOCUSABLE_IM;
20 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
21 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
22 
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.net.VpnManager;
27 import android.os.Bundle;
28 import android.os.UserHandle;
29 import android.provider.Settings;
30 import android.text.SpannableStringBuilder;
31 import android.text.method.LinkMovementMethod;
32 import android.text.style.ClickableSpan;
33 import android.util.Log;
34 import android.view.View;
35 import android.widget.TextView;
36 
37 import com.android.internal.app.AlertActivity;
38 import com.android.internal.net.VpnConfig;
39 
40 public class AlwaysOnDisconnectedDialog extends AlertActivity
41         implements DialogInterface.OnClickListener{
42 
43     private static final String TAG = "VpnDisconnected";
44 
45     private VpnManager mService;
46     private int mUserId;
47     private String mVpnPackage;
48 
49     @Override
onCreate(Bundle savedInstanceState)50     public void onCreate(Bundle savedInstanceState) {
51         super.onCreate(savedInstanceState);
52 
53         mUserId = UserHandle.myUserId();
54         final VpnManager vm = getSystemService(VpnManager.class);
55         mVpnPackage = vm.getAlwaysOnVpnPackageForUser(mUserId);
56         if (mVpnPackage == null) {
57             finish();
58             return;
59         }
60 
61         View view = View.inflate(this, R.layout.always_on_disconnected, null);
62         TextView messageView = view.findViewById(R.id.message);
63         messageView.setText(getMessage(getIntent().getBooleanExtra("lockdown", false)));
64         messageView.setMovementMethod(LinkMovementMethod.getInstance());
65 
66         mAlertParams.mTitle = getString(R.string.always_on_disconnected_title);
67         mAlertParams.mPositiveButtonText = getString(R.string.open_app);
68         mAlertParams.mPositiveButtonListener = this;
69         mAlertParams.mNegativeButtonText = getString(R.string.dismiss);
70         mAlertParams.mNegativeButtonListener = this;
71         mAlertParams.mCancelable = false;
72         mAlertParams.mView = view;
73         setupAlert();
74 
75         getWindow().setCloseOnTouchOutside(false);
76         getWindow().setType(TYPE_SYSTEM_ALERT);
77         getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
78         getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
79     }
80 
81     @Override
onClick(DialogInterface dialog, int which)82     public void onClick(DialogInterface dialog, int which) {
83         switch (which) {
84             case BUTTON_POSITIVE:
85                 PackageManager pm = getPackageManager();
86                 final Intent intent = pm.getLaunchIntentForPackage(mVpnPackage);
87                 if (intent != null) {
88                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
89                     startActivity(intent);
90                 }
91                 finish();
92                 break;
93             case BUTTON_NEGATIVE:
94                 finish();
95                 break;
96             default:
97                 break;
98         }
99     }
100 
getVpnLabel()101     private CharSequence getVpnLabel() {
102         try {
103             return VpnConfig.getVpnLabel(this, mVpnPackage);
104         } catch (PackageManager.NameNotFoundException e) {
105             Log.w(TAG, "Can't getVpnLabel() for " + mVpnPackage, e);
106             return mVpnPackage;
107         }
108     }
109 
getMessage(boolean isLockdown)110     private CharSequence getMessage(boolean isLockdown) {
111         final SpannableStringBuilder message = new SpannableStringBuilder();
112         final int baseMessageResId = isLockdown
113                 ? R.string.always_on_disconnected_message_lockdown
114                 : R.string.always_on_disconnected_message;
115         message.append(getString(baseMessageResId, getVpnLabel()));
116         message.append(getString(R.string.always_on_disconnected_message_separator));
117         message.append(getString(R.string.always_on_disconnected_message_settings_link),
118                 new VpnSpan(), 0 /*flags*/);
119         return message;
120     }
121 
122     private class VpnSpan extends ClickableSpan {
123         @Override
onClick(View unused)124         public void onClick(View unused) {
125             final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
126             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
127             startActivity(intent);
128         }
129     }
130 }
131