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 android.content.DialogInterface;
20 import android.net.VpnManager;
21 import android.os.Bundle;
22 import android.os.Handler;
23 import android.os.Message;
24 import android.os.SystemClock;
25 import android.os.UserHandle;
26 import android.util.Log;
27 import android.view.View;
28 import android.widget.TextView;
29 
30 import com.android.internal.app.AlertActivity;
31 import com.android.internal.net.VpnConfig;
32 
33 import java.io.DataInputStream;
34 import java.io.FileInputStream;
35 
36 public class ManageDialog extends AlertActivity implements
37         DialogInterface.OnClickListener, Handler.Callback {
38     private static final String TAG = "VpnManage";
39 
40     private VpnConfig mConfig;
41 
42     private VpnManager mVm;
43 
44     private TextView mDuration;
45     private TextView mDataTransmitted;
46     private TextView mDataReceived;
47     private boolean mDataRowsHidden;
48 
49     private Handler mHandler;
50 
51     @Override
onCreate(Bundle savedInstanceState)52     protected void onCreate(Bundle savedInstanceState) {
53         super.onCreate(savedInstanceState);
54 
55         try {
56             mVm = getSystemService(VpnManager.class);
57 
58             mConfig = mVm.getVpnConfig(UserHandle.myUserId());
59 
60             // mConfig can be null if we are a restricted user, in that case don't show this dialog
61             if (mConfig == null) {
62                 finish();
63                 return;
64             }
65 
66             View view = View.inflate(this, R.layout.manage, null);
67             if (mConfig.session != null) {
68                 ((TextView) view.findViewById(R.id.session)).setText(mConfig.session);
69             }
70             mDuration = (TextView) view.findViewById(R.id.duration);
71             mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
72             mDataReceived = (TextView) view.findViewById(R.id.data_received);
73             mDataRowsHidden = true;
74 
75             if (mConfig.legacy) {
76                 mAlertParams.mTitle = getText(R.string.legacy_title);
77             } else {
78                 mAlertParams.mTitle = VpnConfig.getVpnLabel(this, mConfig.user);
79             }
80             if (mConfig.configureIntent != null) {
81                 mAlertParams.mPositiveButtonText = getText(R.string.configure);
82                 mAlertParams.mPositiveButtonListener = this;
83             }
84             mAlertParams.mNeutralButtonText = getText(R.string.disconnect);
85             mAlertParams.mNeutralButtonListener = this;
86             mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
87             mAlertParams.mNegativeButtonListener = this;
88             mAlertParams.mView = view;
89             setupAlert();
90 
91             if (mHandler == null) {
92                 mHandler = new Handler(this);
93             }
94             mHandler.sendEmptyMessage(0);
95         } catch (Exception e) {
96             Log.e(TAG, "onResume", e);
97             finish();
98         }
99     }
100 
101     @Override
onDestroy()102     protected void onDestroy() {
103         if (!isFinishing()) {
104             finish();
105         }
106         super.onDestroy();
107     }
108 
109     @Override
onClick(DialogInterface dialog, int which)110     public void onClick(DialogInterface dialog, int which) {
111         try {
112             if (which == DialogInterface.BUTTON_POSITIVE) {
113                 mConfig.configureIntent.send();
114             } else if (which == DialogInterface.BUTTON_NEUTRAL) {
115                 final int myUserId = UserHandle.myUserId();
116                 if (mConfig.legacy) {
117                     mVm.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, myUserId);
118                 } else {
119                     mVm.prepareVpn(mConfig.user, VpnConfig.LEGACY_VPN, myUserId);
120                 }
121             }
122         } catch (Exception e) {
123             Log.e(TAG, "onClick", e);
124             finish();
125         }
126     }
127 
128     @Override
handleMessage(Message message)129     public boolean handleMessage(Message message) {
130         mHandler.removeMessages(0);
131 
132         if (!isFinishing()) {
133             if (mConfig.startTime != -1) {
134                 long seconds = (SystemClock.elapsedRealtime() - mConfig.startTime) / 1000;
135                 mDuration.setText(String.format("%02d:%02d:%02d",
136                         seconds / 3600, seconds / 60 % 60, seconds % 60));
137             }
138 
139             String[] numbers = getNumbers();
140             if (numbers != null) {
141                 // First unhide the related data rows.
142                 if (mDataRowsHidden) {
143                     findViewById(R.id.data_transmitted_row).setVisibility(View.VISIBLE);
144                     findViewById(R.id.data_received_row).setVisibility(View.VISIBLE);
145                     mDataRowsHidden = false;
146                 }
147 
148                 // [1] and [2] are received data in bytes and packets.
149                 mDataReceived.setText(getString(R.string.data_value_format,
150                         numbers[1], numbers[2]));
151 
152                 // [9] and [10] are transmitted data in bytes and packets.
153                 mDataTransmitted.setText(getString(R.string.data_value_format,
154                         numbers[9], numbers[10]));
155             }
156             mHandler.sendEmptyMessageDelayed(0, 1000);
157         }
158         return true;
159     }
160 
getNumbers()161     private String[] getNumbers() {
162         DataInputStream in = null;
163         try {
164             // See dev_seq_printf_stats() in net/core/dev.c.
165             in = new DataInputStream(new FileInputStream("/proc/net/dev"));
166             String prefix = mConfig.interfaze + ':';
167 
168             while (true) {
169                 String line = in.readLine().trim();
170                 if (line.startsWith(prefix)) {
171                     String[] numbers = line.substring(prefix.length()).split(" +");
172                     for (int i = 1; i < 17; ++i) {
173                         if (!numbers[i].equals("0")) {
174                             return numbers;
175                         }
176                     }
177                     break;
178                 }
179             }
180         } catch (Exception e) {
181             // ignore
182         } finally {
183             try {
184                 in.close();
185             } catch (Exception e) {
186                 // ignore
187             }
188         }
189         return null;
190     }
191 }
192