diff options
Diffstat (limited to 'services/java/com/android/server/CommonTimeManagementService.java')
-rw-r--r-- | services/java/com/android/server/CommonTimeManagementService.java | 376 |
1 files changed, 0 insertions, 376 deletions
diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java deleted file mode 100644 index 710fb9d..0000000 --- a/services/java/com/android/server/CommonTimeManagementService.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.net.InetAddress; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.IConnectivityManager; -import android.net.INetworkManagementEventObserver; -import android.net.InterfaceConfiguration; -import android.net.NetworkInfo; -import android.os.Binder; -import android.os.CommonTimeConfig; -import android.os.Handler; -import android.os.IBinder; -import android.os.INetworkManagementService; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemProperties; -import android.util.Log; - -import com.android.server.net.BaseNetworkObserver; - -/** - * @hide - * <p>CommonTimeManagementService manages the configuration of the native Common Time service, - * reconfiguring the native service as appropriate in response to changes in network configuration. - */ -class CommonTimeManagementService extends Binder { - /* - * Constants and globals. - */ - private static final String TAG = CommonTimeManagementService.class.getSimpleName(); - private static final int NATIVE_SERVICE_RECONNECT_TIMEOUT = 5000; - private static final String AUTO_DISABLE_PROP = "ro.common_time.auto_disable"; - private static final String ALLOW_WIFI_PROP = "ro.common_time.allow_wifi"; - private static final String SERVER_PRIO_PROP = "ro.common_time.server_prio"; - private static final String NO_INTERFACE_TIMEOUT_PROP = "ro.common_time.no_iface_timeout"; - private static final boolean AUTO_DISABLE; - private static final boolean ALLOW_WIFI; - private static final byte BASE_SERVER_PRIO; - private static final int NO_INTERFACE_TIMEOUT; - private static final InterfaceScoreRule[] IFACE_SCORE_RULES; - - static { - int tmp; - AUTO_DISABLE = (0 != SystemProperties.getInt(AUTO_DISABLE_PROP, 1)); - ALLOW_WIFI = (0 != SystemProperties.getInt(ALLOW_WIFI_PROP, 0)); - tmp = SystemProperties.getInt(SERVER_PRIO_PROP, 1); - NO_INTERFACE_TIMEOUT = SystemProperties.getInt(NO_INTERFACE_TIMEOUT_PROP, 60000); - - if (tmp < 1) - BASE_SERVER_PRIO = 1; - else - if (tmp > 30) - BASE_SERVER_PRIO = 30; - else - BASE_SERVER_PRIO = (byte)tmp; - - if (ALLOW_WIFI) { - IFACE_SCORE_RULES = new InterfaceScoreRule[] { - new InterfaceScoreRule("wlan", (byte)1), - new InterfaceScoreRule("eth", (byte)2), - }; - } else { - IFACE_SCORE_RULES = new InterfaceScoreRule[] { - new InterfaceScoreRule("eth", (byte)2), - }; - } - }; - - /* - * Internal state - */ - private final Context mContext; - private INetworkManagementService mNetMgr; - private CommonTimeConfig mCTConfig; - private String mCurIface; - private Handler mReconnectHandler = new Handler(); - private Handler mNoInterfaceHandler = new Handler(); - private Object mLock = new Object(); - private boolean mDetectedAtStartup = false; - private byte mEffectivePrio = BASE_SERVER_PRIO; - - /* - * Callback handler implementations. - */ - private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() { - public void interfaceStatusChanged(String iface, boolean up) { - reevaluateServiceState(); - } - public void interfaceLinkStateChanged(String iface, boolean up) { - reevaluateServiceState(); - } - public void interfaceAdded(String iface) { - reevaluateServiceState(); - } - public void interfaceRemoved(String iface) { - reevaluateServiceState(); - } - }; - - private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - reevaluateServiceState(); - } - }; - - private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener = - new CommonTimeConfig.OnServerDiedListener() { - public void onServerDied() { - scheduleTimeConfigReconnect(); - } - }; - - private Runnable mReconnectRunnable = new Runnable() { - public void run() { connectToTimeConfig(); } - }; - - private Runnable mNoInterfaceRunnable = new Runnable() { - public void run() { handleNoInterfaceTimeout(); } - }; - - /* - * Public interface (constructor, systemReady and dump) - */ - public CommonTimeManagementService(Context context) { - mContext = context; - } - - void systemRunning() { - if (ServiceManager.checkService(CommonTimeConfig.SERVICE_NAME) == null) { - Log.i(TAG, "No common time service detected on this platform. " + - "Common time services will be unavailable."); - return; - } - - mDetectedAtStartup = true; - - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - mNetMgr = INetworkManagementService.Stub.asInterface(b); - - // Network manager is running along-side us, so we should never receiver a remote exception - // while trying to register this observer. - try { - mNetMgr.registerObserver(mIfaceObserver); - } - catch (RemoteException e) { } - - // Register with the connectivity manager for connectivity changed intents. - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(mConnectivityMangerObserver, filter); - - // Connect to the common time config service and apply the initial configuration. - connectToTimeConfig(); - } - - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println(String.format( - "Permission Denial: can't dump CommonTimeManagement service from from " + - "pid=%d, uid=%d", Binder.getCallingPid(), Binder.getCallingUid())); - return; - } - - if (!mDetectedAtStartup) { - pw.println("Native Common Time service was not detected at startup. " + - "Service is unavailable"); - return; - } - - synchronized (mLock) { - pw.println("Current Common Time Management Service Config:"); - pw.println(String.format(" Native service : %s", - (null == mCTConfig) ? "reconnecting" - : "alive")); - pw.println(String.format(" Bound interface : %s", - (null == mCurIface ? "unbound" : mCurIface))); - pw.println(String.format(" Allow WiFi : %s", ALLOW_WIFI ? "yes" : "no")); - pw.println(String.format(" Allow Auto Disable : %s", AUTO_DISABLE ? "yes" : "no")); - pw.println(String.format(" Server Priority : %d", mEffectivePrio)); - pw.println(String.format(" No iface timeout : %d", NO_INTERFACE_TIMEOUT)); - } - } - - /* - * Inner helper classes - */ - private static class InterfaceScoreRule { - public final String mPrefix; - public final byte mScore; - public InterfaceScoreRule(String prefix, byte score) { - mPrefix = prefix; - mScore = score; - } - }; - - /* - * Internal implementation - */ - private void cleanupTimeConfig() { - mReconnectHandler.removeCallbacks(mReconnectRunnable); - mNoInterfaceHandler.removeCallbacks(mNoInterfaceRunnable); - if (null != mCTConfig) { - mCTConfig.release(); - mCTConfig = null; - } - } - - private void connectToTimeConfig() { - // Get access to the common time service configuration interface. If we catch a remote - // exception in the process (service crashed or no running for w/e reason), schedule an - // attempt to reconnect in the future. - cleanupTimeConfig(); - try { - synchronized (mLock) { - mCTConfig = new CommonTimeConfig(); - mCTConfig.setServerDiedListener(mCTServerDiedListener); - mCurIface = mCTConfig.getInterfaceBinding(); - mCTConfig.setAutoDisable(AUTO_DISABLE); - mCTConfig.setMasterElectionPriority(mEffectivePrio); - } - - if (NO_INTERFACE_TIMEOUT >= 0) - mNoInterfaceHandler.postDelayed(mNoInterfaceRunnable, NO_INTERFACE_TIMEOUT); - - reevaluateServiceState(); - } - catch (RemoteException e) { - scheduleTimeConfigReconnect(); - } - } - - private void scheduleTimeConfigReconnect() { - cleanupTimeConfig(); - Log.w(TAG, String.format("Native service died, will reconnect in %d mSec", - NATIVE_SERVICE_RECONNECT_TIMEOUT)); - mReconnectHandler.postDelayed(mReconnectRunnable, - NATIVE_SERVICE_RECONNECT_TIMEOUT); - } - - private void handleNoInterfaceTimeout() { - if (null != mCTConfig) { - Log.i(TAG, "Timeout waiting for interface to come up. " + - "Forcing networkless master mode."); - if (CommonTimeConfig.ERROR_DEAD_OBJECT == mCTConfig.forceNetworklessMasterMode()) - scheduleTimeConfigReconnect(); - } - } - - private void reevaluateServiceState() { - String bindIface = null; - byte bestScore = -1; - try { - // Check to see if this interface is suitable to use for time synchronization. - // - // TODO : This selection algorithm needs to be enhanced for use with mobile devices. In - // particular, the choice of whether to a wireless interface or not should not be an all - // or nothing thing controlled by properties. It would probably be better if the - // platform had some concept of public wireless networks vs. home or friendly wireless - // networks (something a user would configure in settings or when a new interface is - // added). Then this algorithm could pick only wireless interfaces which were flagged - // as friendly, and be dormant when on public wireless networks. - // - // Another issue which needs to be dealt with is the use of driver supplied interface - // name to determine the network type. The fact that the wireless interface on a device - // is named "wlan0" is just a matter of convention; its not a 100% rule. For example, - // there are devices out there where the wireless is name "tiwlan0", not "wlan0". The - // internal network management interfaces in Android have all of the information needed - // to make a proper classification, there is just no way (currently) to fetch an - // interface's type (available from the ConnectionManager) as well as its address - // (available from either the java.net interfaces or from the NetworkManagment service). - // Both can enumerate interfaces, but that is no way to correlate their results (no - // common shared key; although using the interface name in the connection manager would - // be a good start). Until this gets resolved, we resort to substring searching for - // tags like wlan and eth. - // - String ifaceList[] = mNetMgr.listInterfaces(); - if (null != ifaceList) { - for (String iface : ifaceList) { - - byte thisScore = -1; - for (InterfaceScoreRule r : IFACE_SCORE_RULES) { - if (iface.contains(r.mPrefix)) { - thisScore = r.mScore; - break; - } - } - - if (thisScore <= bestScore) - continue; - - InterfaceConfiguration config = mNetMgr.getInterfaceConfig(iface); - if (null == config) - continue; - - if (config.isActive()) { - bindIface = iface; - bestScore = thisScore; - } - } - } - } - catch (RemoteException e) { - // Bad news; we should not be getting remote exceptions from the connectivity manager - // since it is running in SystemServer along side of us. It probably does not matter - // what we do here, but go ahead and unbind the common time service in this case, just - // so we have some defined behavior. - bindIface = null; - } - - boolean doRebind = true; - synchronized (mLock) { - if ((null != bindIface) && (null == mCurIface)) { - Log.e(TAG, String.format("Binding common time service to %s.", bindIface)); - mCurIface = bindIface; - } else - if ((null == bindIface) && (null != mCurIface)) { - Log.e(TAG, "Unbinding common time service."); - mCurIface = null; - } else - if ((null != bindIface) && (null != mCurIface) && !bindIface.equals(mCurIface)) { - Log.e(TAG, String.format("Switching common time service binding from %s to %s.", - mCurIface, bindIface)); - mCurIface = bindIface; - } else { - doRebind = false; - } - } - - if (doRebind && (null != mCTConfig)) { - byte newPrio = (bestScore > 0) - ? (byte)(bestScore * BASE_SERVER_PRIO) - : BASE_SERVER_PRIO; - if (newPrio != mEffectivePrio) { - mEffectivePrio = newPrio; - mCTConfig.setMasterElectionPriority(mEffectivePrio); - } - - int res = mCTConfig.setNetworkBinding(mCurIface); - if (res != CommonTimeConfig.SUCCESS) - scheduleTimeConfigReconnect(); - - else if (NO_INTERFACE_TIMEOUT >= 0) { - mNoInterfaceHandler.removeCallbacks(mNoInterfaceRunnable); - if (null == mCurIface) - mNoInterfaceHandler.postDelayed(mNoInterfaceRunnable, NO_INTERFACE_TIMEOUT); - } - } - } -} |