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