19ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk/** 29ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Copyright (c) 2013, The Android Open Source Project 39ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * 49ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 59ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * you may not use this file except in compliance with the License. 69ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * You may obtain a copy of the License at 79ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * 89ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 99ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * 109ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Unless required by applicable law or agreed to in writing, software 119ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 129ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * See the License for the specific language governing permissions and 149ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * limitations under the License. 159ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk */ 16602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkpackage com.android.server.connectivity; 17602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 18602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.app.AlarmManager; 19602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.app.PendingIntent; 20602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.content.BroadcastReceiver; 219ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.content.ComponentName; 22602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.content.ContentResolver; 23602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.content.Context; 24602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.content.Intent; 25602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.content.IntentFilter; 269ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.content.ServiceConnection; 276f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monkimport android.net.Proxy; 28602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.net.ProxyProperties; 296f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monkimport android.os.Binder; 30decd295b1371238c97c170226c6145948492eda1Jason Monkimport android.os.Handler; 319ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.os.IBinder; 32602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.os.RemoteException; 33602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.os.ServiceManager; 34602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.os.SystemClock; 35602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.os.SystemProperties; 366f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monkimport android.os.UserHandle; 37602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.provider.Settings; 38602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.text.TextUtils; 39602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport android.util.Log; 40602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 419ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport com.android.internal.annotations.GuardedBy; 426f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monkimport com.android.net.IProxyCallback; 436f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monkimport com.android.net.IProxyPortListener; 44602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport com.android.net.IProxyService; 459ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport com.android.server.IoThread; 46602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 479ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport libcore.io.Streams; 48602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 49602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport java.io.IOException; 50602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport java.net.URL; 51602b232a06ede86999aa362a12eb28cbc782dc1dJason Monkimport java.net.URLConnection; 52602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 53602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk/** 54602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk * @hide 55602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk */ 569ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkpublic class PacManager { 57da205a749fadb3a87357d9bd607f094c7717764aJason Monk public static final String PAC_PACKAGE = "com.android.pacprocessor"; 58da205a749fadb3a87357d9bd607f094c7717764aJason Monk public static final String PAC_SERVICE = "com.android.pacprocessor.PacService"; 59da205a749fadb3a87357d9bd607f094c7717764aJason Monk public static final String PAC_SERVICE_NAME = "com.android.net.IProxyService"; 60602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 61da205a749fadb3a87357d9bd607f094c7717764aJason Monk public static final String PROXY_PACKAGE = "com.android.proxyhandler"; 62da205a749fadb3a87357d9bd607f094c7717764aJason Monk public static final String PROXY_SERVICE = "com.android.proxyhandler.ProxyService"; 63602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 649ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private static final String TAG = "PacManager"; 65602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 66602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private static final String ACTION_PAC_REFRESH = "android.net.proxy.PAC_REFRESH"; 67602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 68602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private static final String DEFAULT_DELAYS = "8 32 120 14400 43200"; 69602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private static final int DELAY_1 = 0; 70602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private static final int DELAY_4 = 3; 71602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private static final int DELAY_LONG = 4; 72602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 73602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk /** Keep these values up-to-date with ProxyService.java */ 74602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk public static final String KEY_PROXY = "keyProxy"; 75602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private String mCurrentPac; 769ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @GuardedBy("mProxyLock") 779ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private String mPacUrl; 78602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 79602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private AlarmManager mAlarmManager; 809ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @GuardedBy("mProxyLock") 81602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private IProxyService mProxyService; 82602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private PendingIntent mPacRefreshIntent; 839ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private ServiceConnection mConnection; 84da205a749fadb3a87357d9bd607f094c7717764aJason Monk private ServiceConnection mProxyConnection; 85602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private Context mContext; 86602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 87602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private int mCurrentDelay; 886f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk private int mLastPort; 89602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 90d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk private boolean mHasSentBroadcast; 91d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk private boolean mHasDownloaded; 92d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk 93decd295b1371238c97c170226c6145948492eda1Jason Monk private Handler mConnectivityHandler; 94decd295b1371238c97c170226c6145948492eda1Jason Monk private int mProxyMessage; 95decd295b1371238c97c170226c6145948492eda1Jason Monk 969ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk /** 979ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Used for locking when setting mProxyService and all references to mPacUrl or mCurrentPac. 989ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk */ 999ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private final Object mProxyLock = new Object(); 1009ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 1019ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private Runnable mPacDownloader = new Runnable() { 1029ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 1039ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void run() { 1049ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk String file; 1059ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk synchronized (mProxyLock) { 1069ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mPacUrl == null) return; 1079ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk try { 1089ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk file = get(mPacUrl); 1099ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } catch (IOException ioe) { 1109ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk file = null; 1119ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.w(TAG, "Failed to load PAC file: " + ioe); 1129ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1139ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1149ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (file != null) { 1159ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk synchronized (mProxyLock) { 1169ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (!file.equals(mCurrentPac)) { 1179ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk setCurrentProxyScript(file); 1189ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1199ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 120d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk mHasDownloaded = true; 121d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk sendProxyIfNeeded(); 1229ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk longSchedule(); 1239ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } else { 1249ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk reschedule(); 1259ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1269ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1279ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk }; 1289ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 129602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk class PacRefreshIntentReceiver extends BroadcastReceiver { 130602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk public void onReceive(Context context, Intent intent) { 1319ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk IoThread.getHandler().post(mPacDownloader); 132602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 133602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 134602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 135decd295b1371238c97c170226c6145948492eda1Jason Monk public PacManager(Context context, Handler handler, int proxyMessage) { 136602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mContext = context; 1376f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk mLastPort = -1; 138602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 139602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mPacRefreshIntent = PendingIntent.getBroadcast( 140602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk context, 0, new Intent(ACTION_PAC_REFRESH), 0); 141602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk context.registerReceiver(new PacRefreshIntentReceiver(), 142602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk new IntentFilter(ACTION_PAC_REFRESH)); 143decd295b1371238c97c170226c6145948492eda1Jason Monk mConnectivityHandler = handler; 144decd295b1371238c97c170226c6145948492eda1Jason Monk mProxyMessage = proxyMessage; 145602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 146602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 147602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private AlarmManager getAlarmManager() { 148602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk if (mAlarmManager == null) { 149602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 150602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 151602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return mAlarmManager; 152602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 153602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 1546f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk /** 1556f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * Updates the PAC Manager with current Proxy information. This is called by 1566f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * the ConnectivityService directly before a broadcast takes place to allow 1576f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * the PacManager to indicate that the broadcast should not be sent and the 1586f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * PacManager will trigger a new broadcast when it is ready. 1596f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * 1606f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * @param proxy Proxy information that is about to be broadcast. 1616f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk * @return Returns true when the broadcast should not be sent 1626f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk */ 1636f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk public synchronized boolean setCurrentProxyScriptUrl(ProxyProperties proxy) { 164602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk if (!TextUtils.isEmpty(proxy.getPacFileUrl())) { 16590760c8fa36574d6cc9224046758317ca6f640bfJason Monk if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) { 166decd295b1371238c97c170226c6145948492eda1Jason Monk // Allow to send broadcast, nothing to do. 167decd295b1371238c97c170226c6145948492eda1Jason Monk return false; 168decd295b1371238c97c170226c6145948492eda1Jason Monk } 1699ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk synchronized (mProxyLock) { 170602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mPacUrl = proxy.getPacFileUrl(); 171602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 1729ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mCurrentDelay = DELAY_1; 173d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk mHasSentBroadcast = false; 174d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk mHasDownloaded = false; 1759ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk getAlarmManager().cancel(mPacRefreshIntent); 1769ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk bind(); 1776f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk return true; 178602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } else { 1799ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk getAlarmManager().cancel(mPacRefreshIntent); 1809ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk synchronized (mProxyLock) { 1819ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacUrl = null; 1829ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mCurrentPac = null; 1839ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mProxyService != null) { 1849ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk try { 1859ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mProxyService.stopPacSystem(); 1869ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } catch (RemoteException e) { 1879ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.w(TAG, "Failed to stop PAC service", e); 1889ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } finally { 1899ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk unbind(); 1909ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1919ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 192602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 1936f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk return false; 194602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 195602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 196602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 197602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk /** 198602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk * Does a post and reports back the status code. 199602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk * 200602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk * @throws IOException 201602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk */ 2029ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private static String get(String urlString) throws IOException { 203602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk URL url = new URL(urlString); 204602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY); 2059ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk return new String(Streams.readFully(urlConnection.getInputStream())); 206602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 207602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 208602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private int getNextDelay(int currentDelay) { 209602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk if (++currentDelay > DELAY_4) { 210602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return DELAY_4; 211602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 212602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return currentDelay; 213602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 214602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 215602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private void longSchedule() { 216602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mCurrentDelay = DELAY_1; 217602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk setDownloadIn(DELAY_LONG); 218602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 219602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 220602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private void reschedule() { 221602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mCurrentDelay = getNextDelay(mCurrentDelay); 222602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk setDownloadIn(mCurrentDelay); 223602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 224602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 225602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private String getPacChangeDelay() { 226602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk final ContentResolver cr = mContext.getContentResolver(); 227602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 228602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk /** Check system properties for the default value then use secure settings value, if any. */ 229602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk String defaultDelay = SystemProperties.get( 230602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk "conn." + Settings.Global.PAC_CHANGE_DELAY, 231602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk DEFAULT_DELAYS); 232602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk String val = Settings.Global.getString(cr, Settings.Global.PAC_CHANGE_DELAY); 233602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return (val == null) ? defaultDelay : val; 234602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 235602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 236602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private long getDownloadDelay(int delayIndex) { 237602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk String[] list = getPacChangeDelay().split(" "); 238602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk if (delayIndex < list.length) { 239602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return Long.parseLong(list[delayIndex]); 240602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 241602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return 0; 242602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 243602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 244602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private void setDownloadIn(int delayIndex) { 245602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk long delay = getDownloadDelay(delayIndex); 246602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk long timeTillTrigger = 1000 * delay + SystemClock.elapsedRealtime(); 247602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk getAlarmManager().set(AlarmManager.ELAPSED_REALTIME, timeTillTrigger, mPacRefreshIntent); 248602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 249602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk 250602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk private boolean setCurrentProxyScript(String script) { 251a48ad8bd858d6ffe77838a282dbf71e01967957cWink Saville if (mProxyService == null) { 252a48ad8bd858d6ffe77838a282dbf71e01967957cWink Saville Log.e(TAG, "setCurrentProxyScript: no proxy service"); 253a48ad8bd858d6ffe77838a282dbf71e01967957cWink Saville return false; 254a48ad8bd858d6ffe77838a282dbf71e01967957cWink Saville } 255602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk try { 2569ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mProxyService.setPacFile(script); 257602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk mCurrentPac = script; 258602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } catch (RemoteException e) { 259602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk Log.e(TAG, "Unable to set PAC file", e); 260602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 261602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk return true; 262602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk } 2639ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 2649ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private void bind() { 2659ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mContext == null) { 2669ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "No context for binding"); 2679ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk return; 2689ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 2699ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Intent intent = new Intent(); 270da205a749fadb3a87357d9bd607f094c7717764aJason Monk intent.setClassName(PAC_PACKAGE, PAC_SERVICE); 2716f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk // Already bound no need to bind again. 272bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk if ((mProxyConnection != null) && (mConnection != null)) { 2736f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk if (mLastPort != -1) { 2746f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk sendPacBroadcast(new ProxyProperties(mPacUrl, mLastPort)); 2756f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } else { 2766f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk Log.e(TAG, "Received invalid port from Local Proxy," 2776f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk + " PAC will not be operational"); 2786f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 2796f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk return; 2806f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 2819ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mConnection = new ServiceConnection() { 2829ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 2839ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void onServiceDisconnected(ComponentName component) { 2849ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk synchronized (mProxyLock) { 2859ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mProxyService = null; 2869ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 2879ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 2889ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 2899ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 2909ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void onServiceConnected(ComponentName component, IBinder binder) { 2919ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk synchronized (mProxyLock) { 2929ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk try { 293da205a749fadb3a87357d9bd607f094c7717764aJason Monk Log.d(TAG, "Adding service " + PAC_SERVICE_NAME + " " 2949ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk + binder.getInterfaceDescriptor()); 2959ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } catch (RemoteException e1) { 2969ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "Remote Exception", e1); 2979ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 298da205a749fadb3a87357d9bd607f094c7717764aJason Monk ServiceManager.addService(PAC_SERVICE_NAME, binder); 2999ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mProxyService = IProxyService.Stub.asInterface(binder); 3009ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mProxyService == null) { 3019ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "No proxy service"); 3029ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } else { 3039ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk try { 3049ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mProxyService.startPacSystem(); 3059ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } catch (RemoteException e) { 3069ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e); 3079ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 3089ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk IoThread.getHandler().post(mPacDownloader); 3099ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 3109ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 3119ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 3129ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk }; 3139ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mContext.bindService(intent, mConnection, 3149ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE); 315da205a749fadb3a87357d9bd607f094c7717764aJason Monk 316da205a749fadb3a87357d9bd607f094c7717764aJason Monk intent = new Intent(); 317da205a749fadb3a87357d9bd607f094c7717764aJason Monk intent.setClassName(PROXY_PACKAGE, PROXY_SERVICE); 318da205a749fadb3a87357d9bd607f094c7717764aJason Monk mProxyConnection = new ServiceConnection() { 319da205a749fadb3a87357d9bd607f094c7717764aJason Monk @Override 320da205a749fadb3a87357d9bd607f094c7717764aJason Monk public void onServiceDisconnected(ComponentName component) { 321da205a749fadb3a87357d9bd607f094c7717764aJason Monk } 322da205a749fadb3a87357d9bd607f094c7717764aJason Monk 323da205a749fadb3a87357d9bd607f094c7717764aJason Monk @Override 324da205a749fadb3a87357d9bd607f094c7717764aJason Monk public void onServiceConnected(ComponentName component, IBinder binder) { 3256f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk IProxyCallback callbackService = IProxyCallback.Stub.asInterface(binder); 3266f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk if (callbackService != null) { 3276f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk try { 3286f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk callbackService.getProxyPort(new IProxyPortListener.Stub() { 3296f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk @Override 3306f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk public void setProxyPort(int port) throws RemoteException { 331d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk if (mLastPort != -1) { 332d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk // Always need to send if port changed 333d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk mHasSentBroadcast = false; 334d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk } 3356f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk mLastPort = port; 3366f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk if (port != -1) { 3376f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk Log.d(TAG, "Local proxy is bound on " + port); 338d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk sendProxyIfNeeded(); 3396f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } else { 3406f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk Log.e(TAG, "Received invalid port from Local Proxy," 3416f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk + " PAC will not be operational"); 3426f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 3436f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 3446f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk }); 3456f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } catch (RemoteException e) { 3466f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk e.printStackTrace(); 3476f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 3486f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 349da205a749fadb3a87357d9bd607f094c7717764aJason Monk } 350da205a749fadb3a87357d9bd607f094c7717764aJason Monk }; 351da205a749fadb3a87357d9bd607f094c7717764aJason Monk mContext.bindService(intent, mProxyConnection, 352da205a749fadb3a87357d9bd607f094c7717764aJason Monk Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE); 3539ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 3549ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 3559ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private void unbind() { 356bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk if (mConnection != null) { 357bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk mContext.unbindService(mConnection); 358bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk mConnection = null; 359bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk } 360bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk if (mProxyConnection != null) { 361bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk mContext.unbindService(mProxyConnection); 362bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk mProxyConnection = null; 363bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk } 364bc018d89c27cdd93d1c0222a6e27965455974b9eJason Monk mProxyService = null; 365d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk mLastPort = -1; 3666f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk } 3676f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk 3686f8a68f49a7e8cf86104e721a1e8be7568b5f730Jason Monk private void sendPacBroadcast(ProxyProperties proxy) { 369decd295b1371238c97c170226c6145948492eda1Jason Monk mConnectivityHandler.sendMessage(mConnectivityHandler.obtainMessage(mProxyMessage, proxy)); 3709ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 371d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk 372d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk private synchronized void sendProxyIfNeeded() { 373d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk if (!mHasDownloaded || (mLastPort == -1)) { 374d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk return; 375d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk } 376d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk if (!mHasSentBroadcast) { 377d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk sendPacBroadcast(new ProxyProperties(mPacUrl, mLastPort)); 378d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk mHasSentBroadcast = true; 379d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk } 380d443479a45279f8f52daf4034698f2ab3c3e62f1Jason Monk } 381602b232a06ede86999aa362a12eb28cbc782dc1dJason Monk} 382