1c157673a590e670a9a509ec13d47ffada0b56335John Grossman/* 2c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Copyright (C) 2012 The Android Open Source Project 3c157673a590e670a9a509ec13d47ffada0b56335John Grossman * 4c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Licensed under the Apache License, Version 2.0 (the "License"); 5c157673a590e670a9a509ec13d47ffada0b56335John Grossman * you may not use this file except in compliance with the License. 6c157673a590e670a9a509ec13d47ffada0b56335John Grossman * You may obtain a copy of the License at 7c157673a590e670a9a509ec13d47ffada0b56335John Grossman * 8c157673a590e670a9a509ec13d47ffada0b56335John Grossman * http://www.apache.org/licenses/LICENSE-2.0 9c157673a590e670a9a509ec13d47ffada0b56335John Grossman * 10c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Unless required by applicable law or agreed to in writing, software 11c157673a590e670a9a509ec13d47ffada0b56335John Grossman * distributed under the License is distributed on an "AS IS" BASIS, 12c157673a590e670a9a509ec13d47ffada0b56335John Grossman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c157673a590e670a9a509ec13d47ffada0b56335John Grossman * See the License for the specific language governing permissions and 14c157673a590e670a9a509ec13d47ffada0b56335John Grossman * limitations under the License. 15c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 16c157673a590e670a9a509ec13d47ffada0b56335John Grossman 17c157673a590e670a9a509ec13d47ffada0b56335John Grossmanpackage com.android.server; 18c157673a590e670a9a509ec13d47ffada0b56335John Grossman 19c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport java.io.FileDescriptor; 20c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport java.io.PrintWriter; 21c157673a590e670a9a509ec13d47ffada0b56335John Grossman 22c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.content.BroadcastReceiver; 23c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.content.Context; 24c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.content.Intent; 25c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.content.IntentFilter; 26c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.content.pm.PackageManager; 27c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.net.ConnectivityManager; 28c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.net.INetworkManagementEventObserver; 29c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.net.InterfaceConfiguration; 30c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.Binder; 31c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.CommonTimeConfig; 32c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.Handler; 33c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.IBinder; 34c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.INetworkManagementService; 35c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.RemoteException; 36c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.ServiceManager; 37c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.os.SystemProperties; 38c157673a590e670a9a509ec13d47ffada0b56335John Grossmanimport android.util.Log; 39c157673a590e670a9a509ec13d47ffada0b56335John Grossman 40df86a9f2e92d077386b146fe483b2cf14850737dLorenzo Colittiimport com.android.server.net.BaseNetworkObserver; 41df86a9f2e92d077386b146fe483b2cf14850737dLorenzo Colitti 42c157673a590e670a9a509ec13d47ffada0b56335John Grossman/** 43c157673a590e670a9a509ec13d47ffada0b56335John Grossman * @hide 44c157673a590e670a9a509ec13d47ffada0b56335John Grossman * <p>CommonTimeManagementService manages the configuration of the native Common Time service, 45c157673a590e670a9a509ec13d47ffada0b56335John Grossman * reconfiguring the native service as appropriate in response to changes in network configuration. 46c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 47c157673a590e670a9a509ec13d47ffada0b56335John Grossmanclass CommonTimeManagementService extends Binder { 48c157673a590e670a9a509ec13d47ffada0b56335John Grossman /* 49c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Constants and globals. 50c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 51c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final String TAG = CommonTimeManagementService.class.getSimpleName(); 52c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final int NATIVE_SERVICE_RECONNECT_TIMEOUT = 5000; 53c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final String AUTO_DISABLE_PROP = "ro.common_time.auto_disable"; 54c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final String ALLOW_WIFI_PROP = "ro.common_time.allow_wifi"; 55c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final String SERVER_PRIO_PROP = "ro.common_time.server_prio"; 56c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final String NO_INTERFACE_TIMEOUT_PROP = "ro.common_time.no_iface_timeout"; 57c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final boolean AUTO_DISABLE; 58c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final boolean ALLOW_WIFI; 59c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final byte BASE_SERVER_PRIO; 60c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final int NO_INTERFACE_TIMEOUT; 61c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static final InterfaceScoreRule[] IFACE_SCORE_RULES; 62c157673a590e670a9a509ec13d47ffada0b56335John Grossman 63c157673a590e670a9a509ec13d47ffada0b56335John Grossman static { 64c157673a590e670a9a509ec13d47ffada0b56335John Grossman int tmp; 65c157673a590e670a9a509ec13d47ffada0b56335John Grossman AUTO_DISABLE = (0 != SystemProperties.getInt(AUTO_DISABLE_PROP, 1)); 66c157673a590e670a9a509ec13d47ffada0b56335John Grossman ALLOW_WIFI = (0 != SystemProperties.getInt(ALLOW_WIFI_PROP, 0)); 67c157673a590e670a9a509ec13d47ffada0b56335John Grossman tmp = SystemProperties.getInt(SERVER_PRIO_PROP, 1); 68c157673a590e670a9a509ec13d47ffada0b56335John Grossman NO_INTERFACE_TIMEOUT = SystemProperties.getInt(NO_INTERFACE_TIMEOUT_PROP, 60000); 69c157673a590e670a9a509ec13d47ffada0b56335John Grossman 70c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (tmp < 1) 71c157673a590e670a9a509ec13d47ffada0b56335John Grossman BASE_SERVER_PRIO = 1; 72c157673a590e670a9a509ec13d47ffada0b56335John Grossman else 73c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (tmp > 30) 74c157673a590e670a9a509ec13d47ffada0b56335John Grossman BASE_SERVER_PRIO = 30; 75c157673a590e670a9a509ec13d47ffada0b56335John Grossman else 76c157673a590e670a9a509ec13d47ffada0b56335John Grossman BASE_SERVER_PRIO = (byte)tmp; 77c157673a590e670a9a509ec13d47ffada0b56335John Grossman 78c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (ALLOW_WIFI) { 79c157673a590e670a9a509ec13d47ffada0b56335John Grossman IFACE_SCORE_RULES = new InterfaceScoreRule[] { 80c157673a590e670a9a509ec13d47ffada0b56335John Grossman new InterfaceScoreRule("wlan", (byte)1), 81c157673a590e670a9a509ec13d47ffada0b56335John Grossman new InterfaceScoreRule("eth", (byte)2), 82c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 83c157673a590e670a9a509ec13d47ffada0b56335John Grossman } else { 84c157673a590e670a9a509ec13d47ffada0b56335John Grossman IFACE_SCORE_RULES = new InterfaceScoreRule[] { 85c157673a590e670a9a509ec13d47ffada0b56335John Grossman new InterfaceScoreRule("eth", (byte)2), 86c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 87c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 88c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 89c157673a590e670a9a509ec13d47ffada0b56335John Grossman 90c157673a590e670a9a509ec13d47ffada0b56335John Grossman /* 91c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Internal state 92c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 93c157673a590e670a9a509ec13d47ffada0b56335John Grossman private final Context mContext; 94c157673a590e670a9a509ec13d47ffada0b56335John Grossman private INetworkManagementService mNetMgr; 95c157673a590e670a9a509ec13d47ffada0b56335John Grossman private CommonTimeConfig mCTConfig; 96c157673a590e670a9a509ec13d47ffada0b56335John Grossman private String mCurIface; 97c157673a590e670a9a509ec13d47ffada0b56335John Grossman private Handler mReconnectHandler = new Handler(); 98c157673a590e670a9a509ec13d47ffada0b56335John Grossman private Handler mNoInterfaceHandler = new Handler(); 99c157673a590e670a9a509ec13d47ffada0b56335John Grossman private Object mLock = new Object(); 100c157673a590e670a9a509ec13d47ffada0b56335John Grossman private boolean mDetectedAtStartup = false; 101c157673a590e670a9a509ec13d47ffada0b56335John Grossman private byte mEffectivePrio = BASE_SERVER_PRIO; 102c157673a590e670a9a509ec13d47ffada0b56335John Grossman 103c157673a590e670a9a509ec13d47ffada0b56335John Grossman /* 104c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Callback handler implementations. 105c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 106df86a9f2e92d077386b146fe483b2cf14850737dLorenzo Colitti private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() { 107c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void interfaceStatusChanged(String iface, boolean up) { 108c157673a590e670a9a509ec13d47ffada0b56335John Grossman reevaluateServiceState(); 109c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 110c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void interfaceLinkStateChanged(String iface, boolean up) { 111c157673a590e670a9a509ec13d47ffada0b56335John Grossman reevaluateServiceState(); 112c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 113c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void interfaceAdded(String iface) { 114c157673a590e670a9a509ec13d47ffada0b56335John Grossman reevaluateServiceState(); 115c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 116c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void interfaceRemoved(String iface) { 117c157673a590e670a9a509ec13d47ffada0b56335John Grossman reevaluateServiceState(); 118c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 119c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 120c157673a590e670a9a509ec13d47ffada0b56335John Grossman 121c157673a590e670a9a509ec13d47ffada0b56335John Grossman private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() { 122c157673a590e670a9a509ec13d47ffada0b56335John Grossman @Override 123c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void onReceive(Context context, Intent intent) { 124c157673a590e670a9a509ec13d47ffada0b56335John Grossman reevaluateServiceState(); 125c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 126c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 127c157673a590e670a9a509ec13d47ffada0b56335John Grossman 128c157673a590e670a9a509ec13d47ffada0b56335John Grossman private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener = 129c157673a590e670a9a509ec13d47ffada0b56335John Grossman new CommonTimeConfig.OnServerDiedListener() { 130c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void onServerDied() { 131c157673a590e670a9a509ec13d47ffada0b56335John Grossman scheduleTimeConfigReconnect(); 132c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 133c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 134c157673a590e670a9a509ec13d47ffada0b56335John Grossman 135c157673a590e670a9a509ec13d47ffada0b56335John Grossman private Runnable mReconnectRunnable = new Runnable() { 136c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void run() { connectToTimeConfig(); } 137c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 138c157673a590e670a9a509ec13d47ffada0b56335John Grossman 139c157673a590e670a9a509ec13d47ffada0b56335John Grossman private Runnable mNoInterfaceRunnable = new Runnable() { 140c157673a590e670a9a509ec13d47ffada0b56335John Grossman public void run() { handleNoInterfaceTimeout(); } 141c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 142c157673a590e670a9a509ec13d47ffada0b56335John Grossman 143c157673a590e670a9a509ec13d47ffada0b56335John Grossman /* 144c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Public interface (constructor, systemReady and dump) 145c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 146c157673a590e670a9a509ec13d47ffada0b56335John Grossman public CommonTimeManagementService(Context context) { 147c157673a590e670a9a509ec13d47ffada0b56335John Grossman mContext = context; 148c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 149c157673a590e670a9a509ec13d47ffada0b56335John Grossman 150a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov void systemRunning() { 151c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (ServiceManager.checkService(CommonTimeConfig.SERVICE_NAME) == null) { 152c157673a590e670a9a509ec13d47ffada0b56335John Grossman Log.i(TAG, "No common time service detected on this platform. " + 153c157673a590e670a9a509ec13d47ffada0b56335John Grossman "Common time services will be unavailable."); 154c157673a590e670a9a509ec13d47ffada0b56335John Grossman return; 155c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 156c157673a590e670a9a509ec13d47ffada0b56335John Grossman 157c157673a590e670a9a509ec13d47ffada0b56335John Grossman mDetectedAtStartup = true; 158c157673a590e670a9a509ec13d47ffada0b56335John Grossman 159c157673a590e670a9a509ec13d47ffada0b56335John Grossman IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 160c157673a590e670a9a509ec13d47ffada0b56335John Grossman mNetMgr = INetworkManagementService.Stub.asInterface(b); 161c157673a590e670a9a509ec13d47ffada0b56335John Grossman 162c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Network manager is running along-side us, so we should never receiver a remote exception 163c157673a590e670a9a509ec13d47ffada0b56335John Grossman // while trying to register this observer. 164c157673a590e670a9a509ec13d47ffada0b56335John Grossman try { 165c157673a590e670a9a509ec13d47ffada0b56335John Grossman mNetMgr.registerObserver(mIfaceObserver); 166c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 167c157673a590e670a9a509ec13d47ffada0b56335John Grossman catch (RemoteException e) { } 168c157673a590e670a9a509ec13d47ffada0b56335John Grossman 169c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Register with the connectivity manager for connectivity changed intents. 170c157673a590e670a9a509ec13d47ffada0b56335John Grossman IntentFilter filter = new IntentFilter(); 171c157673a590e670a9a509ec13d47ffada0b56335John Grossman filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 172c157673a590e670a9a509ec13d47ffada0b56335John Grossman mContext.registerReceiver(mConnectivityMangerObserver, filter); 173c157673a590e670a9a509ec13d47ffada0b56335John Grossman 174c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Connect to the common time config service and apply the initial configuration. 175c157673a590e670a9a509ec13d47ffada0b56335John Grossman connectToTimeConfig(); 176c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 177c157673a590e670a9a509ec13d47ffada0b56335John Grossman 178c157673a590e670a9a509ec13d47ffada0b56335John Grossman @Override 179c157673a590e670a9a509ec13d47ffada0b56335John Grossman protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 180c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 181c157673a590e670a9a509ec13d47ffada0b56335John Grossman != PackageManager.PERMISSION_GRANTED) { 182c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format( 183c157673a590e670a9a509ec13d47ffada0b56335John Grossman "Permission Denial: can't dump CommonTimeManagement service from from " + 184c157673a590e670a9a509ec13d47ffada0b56335John Grossman "pid=%d, uid=%d", Binder.getCallingPid(), Binder.getCallingUid())); 185c157673a590e670a9a509ec13d47ffada0b56335John Grossman return; 186c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 187c157673a590e670a9a509ec13d47ffada0b56335John Grossman 188c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (!mDetectedAtStartup) { 189c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println("Native Common Time service was not detected at startup. " + 190c157673a590e670a9a509ec13d47ffada0b56335John Grossman "Service is unavailable"); 191c157673a590e670a9a509ec13d47ffada0b56335John Grossman return; 192c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 193c157673a590e670a9a509ec13d47ffada0b56335John Grossman 194c157673a590e670a9a509ec13d47ffada0b56335John Grossman synchronized (mLock) { 195c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println("Current Common Time Management Service Config:"); 196c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format(" Native service : %s", 197c157673a590e670a9a509ec13d47ffada0b56335John Grossman (null == mCTConfig) ? "reconnecting" 198c157673a590e670a9a509ec13d47ffada0b56335John Grossman : "alive")); 199c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format(" Bound interface : %s", 200c157673a590e670a9a509ec13d47ffada0b56335John Grossman (null == mCurIface ? "unbound" : mCurIface))); 201c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format(" Allow WiFi : %s", ALLOW_WIFI ? "yes" : "no")); 202c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format(" Allow Auto Disable : %s", AUTO_DISABLE ? "yes" : "no")); 203c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format(" Server Priority : %d", mEffectivePrio)); 204c157673a590e670a9a509ec13d47ffada0b56335John Grossman pw.println(String.format(" No iface timeout : %d", NO_INTERFACE_TIMEOUT)); 205c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 206c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 207c157673a590e670a9a509ec13d47ffada0b56335John Grossman 208c157673a590e670a9a509ec13d47ffada0b56335John Grossman /* 209c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Inner helper classes 210c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 211c157673a590e670a9a509ec13d47ffada0b56335John Grossman private static class InterfaceScoreRule { 212c157673a590e670a9a509ec13d47ffada0b56335John Grossman public final String mPrefix; 213c157673a590e670a9a509ec13d47ffada0b56335John Grossman public final byte mScore; 214c157673a590e670a9a509ec13d47ffada0b56335John Grossman public InterfaceScoreRule(String prefix, byte score) { 215c157673a590e670a9a509ec13d47ffada0b56335John Grossman mPrefix = prefix; 216c157673a590e670a9a509ec13d47ffada0b56335John Grossman mScore = score; 217c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 218c157673a590e670a9a509ec13d47ffada0b56335John Grossman }; 219c157673a590e670a9a509ec13d47ffada0b56335John Grossman 220c157673a590e670a9a509ec13d47ffada0b56335John Grossman /* 221c157673a590e670a9a509ec13d47ffada0b56335John Grossman * Internal implementation 222c157673a590e670a9a509ec13d47ffada0b56335John Grossman */ 223c157673a590e670a9a509ec13d47ffada0b56335John Grossman private void cleanupTimeConfig() { 224c157673a590e670a9a509ec13d47ffada0b56335John Grossman mReconnectHandler.removeCallbacks(mReconnectRunnable); 225c157673a590e670a9a509ec13d47ffada0b56335John Grossman mNoInterfaceHandler.removeCallbacks(mNoInterfaceRunnable); 226c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (null != mCTConfig) { 227c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig.release(); 228c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig = null; 229c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 230c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 231c157673a590e670a9a509ec13d47ffada0b56335John Grossman 232c157673a590e670a9a509ec13d47ffada0b56335John Grossman private void connectToTimeConfig() { 233c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Get access to the common time service configuration interface. If we catch a remote 234c157673a590e670a9a509ec13d47ffada0b56335John Grossman // exception in the process (service crashed or no running for w/e reason), schedule an 235c157673a590e670a9a509ec13d47ffada0b56335John Grossman // attempt to reconnect in the future. 236c157673a590e670a9a509ec13d47ffada0b56335John Grossman cleanupTimeConfig(); 237c157673a590e670a9a509ec13d47ffada0b56335John Grossman try { 238c157673a590e670a9a509ec13d47ffada0b56335John Grossman synchronized (mLock) { 239c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig = new CommonTimeConfig(); 240c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig.setServerDiedListener(mCTServerDiedListener); 241c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCurIface = mCTConfig.getInterfaceBinding(); 242c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig.setAutoDisable(AUTO_DISABLE); 243c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig.setMasterElectionPriority(mEffectivePrio); 244c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 245c157673a590e670a9a509ec13d47ffada0b56335John Grossman 246c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (NO_INTERFACE_TIMEOUT >= 0) 247c157673a590e670a9a509ec13d47ffada0b56335John Grossman mNoInterfaceHandler.postDelayed(mNoInterfaceRunnable, NO_INTERFACE_TIMEOUT); 248c157673a590e670a9a509ec13d47ffada0b56335John Grossman 249c157673a590e670a9a509ec13d47ffada0b56335John Grossman reevaluateServiceState(); 250c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 251c157673a590e670a9a509ec13d47ffada0b56335John Grossman catch (RemoteException e) { 252c157673a590e670a9a509ec13d47ffada0b56335John Grossman scheduleTimeConfigReconnect(); 253c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 254c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 255c157673a590e670a9a509ec13d47ffada0b56335John Grossman 256c157673a590e670a9a509ec13d47ffada0b56335John Grossman private void scheduleTimeConfigReconnect() { 257c157673a590e670a9a509ec13d47ffada0b56335John Grossman cleanupTimeConfig(); 258c157673a590e670a9a509ec13d47ffada0b56335John Grossman Log.w(TAG, String.format("Native service died, will reconnect in %d mSec", 259c157673a590e670a9a509ec13d47ffada0b56335John Grossman NATIVE_SERVICE_RECONNECT_TIMEOUT)); 260c157673a590e670a9a509ec13d47ffada0b56335John Grossman mReconnectHandler.postDelayed(mReconnectRunnable, 261c157673a590e670a9a509ec13d47ffada0b56335John Grossman NATIVE_SERVICE_RECONNECT_TIMEOUT); 262c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 263c157673a590e670a9a509ec13d47ffada0b56335John Grossman 264c157673a590e670a9a509ec13d47ffada0b56335John Grossman private void handleNoInterfaceTimeout() { 265c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (null != mCTConfig) { 266c157673a590e670a9a509ec13d47ffada0b56335John Grossman Log.i(TAG, "Timeout waiting for interface to come up. " + 267c157673a590e670a9a509ec13d47ffada0b56335John Grossman "Forcing networkless master mode."); 268c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (CommonTimeConfig.ERROR_DEAD_OBJECT == mCTConfig.forceNetworklessMasterMode()) 269c157673a590e670a9a509ec13d47ffada0b56335John Grossman scheduleTimeConfigReconnect(); 270c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 271c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 272c157673a590e670a9a509ec13d47ffada0b56335John Grossman 273c157673a590e670a9a509ec13d47ffada0b56335John Grossman private void reevaluateServiceState() { 274c157673a590e670a9a509ec13d47ffada0b56335John Grossman String bindIface = null; 275c157673a590e670a9a509ec13d47ffada0b56335John Grossman byte bestScore = -1; 276c157673a590e670a9a509ec13d47ffada0b56335John Grossman try { 277c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Check to see if this interface is suitable to use for time synchronization. 278c157673a590e670a9a509ec13d47ffada0b56335John Grossman // 279c157673a590e670a9a509ec13d47ffada0b56335John Grossman // TODO : This selection algorithm needs to be enhanced for use with mobile devices. In 280c157673a590e670a9a509ec13d47ffada0b56335John Grossman // particular, the choice of whether to a wireless interface or not should not be an all 281c157673a590e670a9a509ec13d47ffada0b56335John Grossman // or nothing thing controlled by properties. It would probably be better if the 282c157673a590e670a9a509ec13d47ffada0b56335John Grossman // platform had some concept of public wireless networks vs. home or friendly wireless 283c157673a590e670a9a509ec13d47ffada0b56335John Grossman // networks (something a user would configure in settings or when a new interface is 284c157673a590e670a9a509ec13d47ffada0b56335John Grossman // added). Then this algorithm could pick only wireless interfaces which were flagged 285c157673a590e670a9a509ec13d47ffada0b56335John Grossman // as friendly, and be dormant when on public wireless networks. 286c157673a590e670a9a509ec13d47ffada0b56335John Grossman // 287c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Another issue which needs to be dealt with is the use of driver supplied interface 288c157673a590e670a9a509ec13d47ffada0b56335John Grossman // name to determine the network type. The fact that the wireless interface on a device 289c157673a590e670a9a509ec13d47ffada0b56335John Grossman // is named "wlan0" is just a matter of convention; its not a 100% rule. For example, 290c157673a590e670a9a509ec13d47ffada0b56335John Grossman // there are devices out there where the wireless is name "tiwlan0", not "wlan0". The 291c157673a590e670a9a509ec13d47ffada0b56335John Grossman // internal network management interfaces in Android have all of the information needed 292c157673a590e670a9a509ec13d47ffada0b56335John Grossman // to make a proper classification, there is just no way (currently) to fetch an 293c157673a590e670a9a509ec13d47ffada0b56335John Grossman // interface's type (available from the ConnectionManager) as well as its address 294c157673a590e670a9a509ec13d47ffada0b56335John Grossman // (available from either the java.net interfaces or from the NetworkManagment service). 295c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Both can enumerate interfaces, but that is no way to correlate their results (no 296c157673a590e670a9a509ec13d47ffada0b56335John Grossman // common shared key; although using the interface name in the connection manager would 297c157673a590e670a9a509ec13d47ffada0b56335John Grossman // be a good start). Until this gets resolved, we resort to substring searching for 298c157673a590e670a9a509ec13d47ffada0b56335John Grossman // tags like wlan and eth. 299c157673a590e670a9a509ec13d47ffada0b56335John Grossman // 300c157673a590e670a9a509ec13d47ffada0b56335John Grossman String ifaceList[] = mNetMgr.listInterfaces(); 301c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (null != ifaceList) { 302c157673a590e670a9a509ec13d47ffada0b56335John Grossman for (String iface : ifaceList) { 303c157673a590e670a9a509ec13d47ffada0b56335John Grossman 304c157673a590e670a9a509ec13d47ffada0b56335John Grossman byte thisScore = -1; 305c157673a590e670a9a509ec13d47ffada0b56335John Grossman for (InterfaceScoreRule r : IFACE_SCORE_RULES) { 306c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (iface.contains(r.mPrefix)) { 307c157673a590e670a9a509ec13d47ffada0b56335John Grossman thisScore = r.mScore; 308c157673a590e670a9a509ec13d47ffada0b56335John Grossman break; 309c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 310c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 311c157673a590e670a9a509ec13d47ffada0b56335John Grossman 312c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (thisScore <= bestScore) 313c157673a590e670a9a509ec13d47ffada0b56335John Grossman continue; 314c157673a590e670a9a509ec13d47ffada0b56335John Grossman 315c157673a590e670a9a509ec13d47ffada0b56335John Grossman InterfaceConfiguration config = mNetMgr.getInterfaceConfig(iface); 316c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (null == config) 317c157673a590e670a9a509ec13d47ffada0b56335John Grossman continue; 318c157673a590e670a9a509ec13d47ffada0b56335John Grossman 319c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (config.isActive()) { 320c157673a590e670a9a509ec13d47ffada0b56335John Grossman bindIface = iface; 321c157673a590e670a9a509ec13d47ffada0b56335John Grossman bestScore = thisScore; 322c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 323c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 324c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 325c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 326c157673a590e670a9a509ec13d47ffada0b56335John Grossman catch (RemoteException e) { 327c157673a590e670a9a509ec13d47ffada0b56335John Grossman // Bad news; we should not be getting remote exceptions from the connectivity manager 328c157673a590e670a9a509ec13d47ffada0b56335John Grossman // since it is running in SystemServer along side of us. It probably does not matter 329c157673a590e670a9a509ec13d47ffada0b56335John Grossman // what we do here, but go ahead and unbind the common time service in this case, just 330c157673a590e670a9a509ec13d47ffada0b56335John Grossman // so we have some defined behavior. 331c157673a590e670a9a509ec13d47ffada0b56335John Grossman bindIface = null; 332c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 333c157673a590e670a9a509ec13d47ffada0b56335John Grossman 334c157673a590e670a9a509ec13d47ffada0b56335John Grossman boolean doRebind = true; 335c157673a590e670a9a509ec13d47ffada0b56335John Grossman synchronized (mLock) { 336c157673a590e670a9a509ec13d47ffada0b56335John Grossman if ((null != bindIface) && (null == mCurIface)) { 337c157673a590e670a9a509ec13d47ffada0b56335John Grossman Log.e(TAG, String.format("Binding common time service to %s.", bindIface)); 338c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCurIface = bindIface; 339c157673a590e670a9a509ec13d47ffada0b56335John Grossman } else 340c157673a590e670a9a509ec13d47ffada0b56335John Grossman if ((null == bindIface) && (null != mCurIface)) { 341c157673a590e670a9a509ec13d47ffada0b56335John Grossman Log.e(TAG, "Unbinding common time service."); 342c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCurIface = null; 343c157673a590e670a9a509ec13d47ffada0b56335John Grossman } else 344c157673a590e670a9a509ec13d47ffada0b56335John Grossman if ((null != bindIface) && (null != mCurIface) && !bindIface.equals(mCurIface)) { 345c157673a590e670a9a509ec13d47ffada0b56335John Grossman Log.e(TAG, String.format("Switching common time service binding from %s to %s.", 346c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCurIface, bindIface)); 347c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCurIface = bindIface; 348c157673a590e670a9a509ec13d47ffada0b56335John Grossman } else { 349c157673a590e670a9a509ec13d47ffada0b56335John Grossman doRebind = false; 350c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 351c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 352c157673a590e670a9a509ec13d47ffada0b56335John Grossman 353c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (doRebind && (null != mCTConfig)) { 354c157673a590e670a9a509ec13d47ffada0b56335John Grossman byte newPrio = (bestScore > 0) 355c157673a590e670a9a509ec13d47ffada0b56335John Grossman ? (byte)(bestScore * BASE_SERVER_PRIO) 356c157673a590e670a9a509ec13d47ffada0b56335John Grossman : BASE_SERVER_PRIO; 357c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (newPrio != mEffectivePrio) { 358c157673a590e670a9a509ec13d47ffada0b56335John Grossman mEffectivePrio = newPrio; 359c157673a590e670a9a509ec13d47ffada0b56335John Grossman mCTConfig.setMasterElectionPriority(mEffectivePrio); 360c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 361c157673a590e670a9a509ec13d47ffada0b56335John Grossman 362c157673a590e670a9a509ec13d47ffada0b56335John Grossman int res = mCTConfig.setNetworkBinding(mCurIface); 363c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (res != CommonTimeConfig.SUCCESS) 364c157673a590e670a9a509ec13d47ffada0b56335John Grossman scheduleTimeConfigReconnect(); 365c157673a590e670a9a509ec13d47ffada0b56335John Grossman 366c157673a590e670a9a509ec13d47ffada0b56335John Grossman else if (NO_INTERFACE_TIMEOUT >= 0) { 367c157673a590e670a9a509ec13d47ffada0b56335John Grossman mNoInterfaceHandler.removeCallbacks(mNoInterfaceRunnable); 368c157673a590e670a9a509ec13d47ffada0b56335John Grossman if (null == mCurIface) 369c157673a590e670a9a509ec13d47ffada0b56335John Grossman mNoInterfaceHandler.postDelayed(mNoInterfaceRunnable, NO_INTERFACE_TIMEOUT); 370c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 371c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 372c157673a590e670a9a509ec13d47ffada0b56335John Grossman } 373c157673a590e670a9a509ec13d47ffada0b56335John Grossman} 374