diff --git a/CleanSpec.mk b/CleanSpec.mk
index e728897..cc0e762 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -243,6 +243,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/os/storage/*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/platformprotos_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
deleted file mode 100644
index 2ecf317..0000000
--- a/core/java/android/os/CommonClock.java
+++ /dev/null
@@ -1,405 +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 android.os;
-
-import java.net.InetSocketAddress;
-import java.util.NoSuchElementException;
-import android.os.Binder;
-import android.os.CommonTimeUtils;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-
-/**
- * Used for accessing the android common time service's common clock and receiving notifications
- * about common time synchronization status changes.
- * @hide
- */
-public class CommonClock {
-    /**
-     * Sentinel value returned by {@link #getTime()} and {@link #getEstimatedError()} when the
-     * common time service is not able to determine the current common time due to a lack of
-     * synchronization.
-     */
-    public static final long TIME_NOT_SYNCED = -1;
-
-    /**
-     * Sentinel value returned by {@link #getTimelineId()} when the common time service is not
-     * currently synced to any timeline.
-     */
-    public static final long INVALID_TIMELINE_ID = 0;
-
-    /**
-     * Sentinel value returned by {@link #getEstimatedError()} when the common time service is not
-     * currently synced to any timeline.
-     */
-    public static final int ERROR_ESTIMATE_UNKNOWN = 0x7FFFFFFF;
-
-    /**
-     * Value used by {@link #getState()} to indicate that there was an internal error while
-     * attempting to determine the state of the common time service.
-     */
-    public static final int STATE_INVALID = -1;
-
-    /**
-     * Value used by {@link #getState()} to indicate that the common time service is in its initial
-     * state and attempting to find the current timeline master, if any.  The service will
-     * transition to either {@link #STATE_CLIENT} if it finds an active master, or to
-     * {@link #STATE_MASTER} if no active master is found and this client becomes the master of a
-     * new timeline.
-     */
-    public static final int STATE_INITIAL = 0;
-
-    /**
-     * Value used by {@link #getState()} to indicate that the common time service is in its client
-     * state and is synchronizing its time to a different timeline master on the network.
-     */
-    public static final int STATE_CLIENT = 1;
-
-    /**
-     * Value used by {@link #getState()} to indicate that the common time service is in its master
-     * state and is serving as the timeline master for other common time service clients on the
-     * network.
-     */
-    public static final int STATE_MASTER = 2;
-
-    /**
-     * Value used by {@link #getState()} to indicate that the common time service is in its Ronin
-     * state.  Common time service instances in the client state enter the Ronin state after their
-     * timeline master becomes unreachable on the network.  Common time services who enter the Ronin
-     * state will begin a new master election for the timeline they were recently clients of.  As
-     * clients detect they are not the winner and drop out of the election, they will transition to
-     * the {@link #STATE_WAIT_FOR_ELECTION} state.  When there is only one client remaining in the
-     * election, it will assume ownership of the timeline and transition to the
-     * {@link #STATE_MASTER} state.  During the election, all clients will allow their timeline to
-     * drift without applying correction.
-     */
-    public static final int STATE_RONIN = 3;
-
-    /**
-     * Value used by {@link #getState()} to indicate that the common time service is waiting for a
-     * master election to conclude and for the new master to announce itself before transitioning to
-     * the {@link #STATE_CLIENT} state.  If no new master announces itself within the timeout
-     * threshold, the time service will transition back to the {@link #STATE_RONIN} state in order
-     * to restart the election.
-     */
-    public static final int STATE_WAIT_FOR_ELECTION = 4;
-
-    /**
-     * Name of the underlying native binder service
-     */
-    public static final String SERVICE_NAME = "common_time.clock";
-
-    /**
-     * Class constructor.
-     * @throws android.os.RemoteException
-     */
-    public CommonClock()
-    throws RemoteException {
-        mRemote = ServiceManager.getService(SERVICE_NAME);
-        if (null == mRemote)
-            throw new RemoteException();
-
-        mInterfaceDesc = mRemote.getInterfaceDescriptor();
-        mUtils = new CommonTimeUtils(mRemote, mInterfaceDesc);
-        mRemote.linkToDeath(mDeathHandler, 0);
-        registerTimelineChangeListener();
-    }
-
-    /**
-     * Handy class factory method.
-     */
-    static public CommonClock create() {
-        CommonClock retVal;
-
-        try {
-            retVal = new CommonClock();
-        }
-        catch (RemoteException e) {
-            retVal = null;
-        }
-
-        return retVal;
-    }
-
-    /**
-     * Release all native resources held by this {@link android.os.CommonClock} instance.  Once
-     * resources have been released, the {@link android.os.CommonClock} instance is disconnected from
-     * the native service and will throw a {@link android.os.RemoteException} if any of its
-     * methods are called.  Clients should always call release on their client instances before
-     * releasing their last Java reference to the instance.  Failure to do this will cause
-     * non-deterministic native resource reclamation and may cause the common time service to remain
-     * active on the network for longer than it should.
-     */
-    public void release() {
-        unregisterTimelineChangeListener();
-        if (null != mRemote) {
-            try {
-                mRemote.unlinkToDeath(mDeathHandler, 0);
-            }
-            catch (NoSuchElementException e) { }
-            mRemote = null;
-        }
-        mUtils = null;
-    }
-
-    /**
-     * Gets the common clock's current time.
-     *
-     * @return a signed 64-bit value representing the current common time in microseconds, or the
-     * special value {@link #TIME_NOT_SYNCED} if the common time service is currently not
-     * synchronized.
-     * @throws android.os.RemoteException
-     */
-    public long getTime()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetLong(METHOD_GET_COMMON_TIME, TIME_NOT_SYNCED);
-    }
-
-    /**
-     * Gets the current estimation of common clock's synchronization accuracy from the common time
-     * service.
-     *
-     * @return a signed 32-bit value representing the common time service's estimation of
-     * synchronization accuracy in microseconds, or the special value
-     * {@link #ERROR_ESTIMATE_UNKNOWN} if the common time service is currently not synchronized.
-     * Negative values indicate that the local server estimates that the nominal common time is
-     * behind the local server's time (in other words, the local clock is running fast) Positive
-     * values indicate that the local server estimates that the nominal common time is ahead of the
-     * local server's time (in other words, the local clock is running slow)
-     * @throws android.os.RemoteException
-     */
-    public int getEstimatedError()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetInt(METHOD_GET_ESTIMATED_ERROR, ERROR_ESTIMATE_UNKNOWN);
-    }
-
-    /**
-     * Gets the ID of the timeline the common time service is currently synchronizing its clock to.
-     *
-     * @return a long representing the unique ID of the timeline the common time service is
-     * currently synchronizing with, or {@link #INVALID_TIMELINE_ID} if the common time service is
-     * currently not synchronized.
-     * @throws android.os.RemoteException
-     */
-    public long getTimelineId()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetLong(METHOD_GET_TIMELINE_ID, INVALID_TIMELINE_ID);
-    }
-
-    /**
-     * Gets the current state of this clock's common time service in the the master election
-     * algorithm.
-     *
-     * @return a integer indicating the current state of the this clock's common time service in the
-     * master election algorithm or {@link #STATE_INVALID} if there is an internal error.
-     * @throws android.os.RemoteException
-     */
-    public int getState()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetInt(METHOD_GET_STATE, STATE_INVALID);
-    }
-
-    /**
-     * Gets the IP address and UDP port of the current timeline master.
-     *
-     * @return an InetSocketAddress containing the IP address and UDP port of the current timeline
-     * master, or null if there is no current master.
-     * @throws android.os.RemoteException
-     */
-    public InetSocketAddress getMasterAddr()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetSockaddr(METHOD_GET_MASTER_ADDRESS);
-    }
-
-    /**
-     * The OnTimelineChangedListener interface defines a method called by the
-     * {@link android.os.CommonClock} instance to indicate that the time synchronization service has
-     * either synchronized with a new timeline, or is no longer a member of any timeline.  The
-     * client application can implement this interface and register the listener with the
-     * {@link #setTimelineChangedListener(OnTimelineChangedListener)} method.
-     */
-    public interface OnTimelineChangedListener  {
-        /**
-         * Method called when the time service's timeline has changed.
-         *
-         * @param newTimelineId a long which uniquely identifies the timeline the time
-         * synchronization service is now a member of, or {@link #INVALID_TIMELINE_ID} if the the
-         * service is not synchronized to any timeline.
-         */
-        void onTimelineChanged(long newTimelineId);
-    }
-
-    /**
-     * Registers an OnTimelineChangedListener interface.
-     * <p>Call this method with a null listener to stop receiving server death notifications.
-     */
-    public void setTimelineChangedListener(OnTimelineChangedListener listener) {
-        synchronized (mListenerLock) {
-            mTimelineChangedListener = listener;
-        }
-    }
-
-    /**
-     * The OnServerDiedListener interface defines a method called by the
-     * {@link android.os.CommonClock} instance to indicate that the connection to the native media
-     * server has been broken and that the {@link android.os.CommonClock} instance will need to be
-     * released and re-created.  The client application can implement this interface and register
-     * the listener with the {@link #setServerDiedListener(OnServerDiedListener)} method.
-     */
-    public interface OnServerDiedListener  {
-        /**
-         * Method called when the native media server has died.  <p>If the native common time
-         * service encounters a fatal error and needs to restart, the binder connection from the
-         * {@link android.os.CommonClock} instance to the common time service will be broken.  To
-         * restore functionality, clients should {@link #release()} their old visualizer and create
-         * a new instance.
-         */
-        void onServerDied();
-    }
-
-    /**
-     * Registers an OnServerDiedListener interface.
-     * <p>Call this method with a null listener to stop receiving server death notifications.
-     */
-    public void setServerDiedListener(OnServerDiedListener listener) {
-        synchronized (mListenerLock) {
-            mServerDiedListener = listener;
-        }
-    }
-
-    protected void finalize() throws Throwable { release(); }
-
-    private void throwOnDeadServer() throws RemoteException {
-        if ((null == mRemote) || (null == mUtils))
-            throw new RemoteException();
-    }
-
-    private final Object mListenerLock = new Object();
-    private OnTimelineChangedListener mTimelineChangedListener = null;
-    private OnServerDiedListener mServerDiedListener = null;
-
-    private IBinder mRemote = null;
-    private String mInterfaceDesc = "";
-    private CommonTimeUtils mUtils;
-
-    private IBinder.DeathRecipient mDeathHandler = new IBinder.DeathRecipient() {
-        public void binderDied() {
-            synchronized (mListenerLock) {
-                if (null != mServerDiedListener)
-                    mServerDiedListener.onServerDied();
-            }
-        }
-    };
-
-    private class TimelineChangedListener extends Binder {
-        @Override
-        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-        throws RemoteException {
-            switch (code) {
-                case METHOD_CBK_ON_TIMELINE_CHANGED:
-                    data.enforceInterface(DESCRIPTOR);
-                    long timelineId = data.readLong();
-                    synchronized (mListenerLock) {
-                        if (null != mTimelineChangedListener)
-                            mTimelineChangedListener.onTimelineChanged(timelineId);
-                    }
-                    return true;
-            }
-
-            return super.onTransact(code, data, reply, flags);
-        }
-
-        private static final String DESCRIPTOR = "android.os.ICommonClockListener";
-    };
-
-    private TimelineChangedListener mCallbackTgt = null;
-
-    private void registerTimelineChangeListener() throws RemoteException {
-        if (null != mCallbackTgt)
-            return;
-
-        boolean success = false;
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-        mCallbackTgt = new TimelineChangedListener();
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-            data.writeStrongBinder(mCallbackTgt);
-            mRemote.transact(METHOD_REGISTER_LISTENER, data, reply, 0);
-            success = (0 == reply.readInt());
-        }
-        catch (RemoteException e) {
-            success = false;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-
-        // Did we catch a remote exception or fail to register our callback target?  If so, our
-        // object must already be dead (or be as good as dead).  Clear out all of our state so that
-        // our other methods will properly indicate a dead object.
-        if (!success) {
-            mCallbackTgt = null;
-            mRemote = null;
-            mUtils = null;
-        }
-    }
-
-    private void unregisterTimelineChangeListener() {
-        if (null == mCallbackTgt)
-            return;
-
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-            data.writeStrongBinder(mCallbackTgt);
-            mRemote.transact(METHOD_UNREGISTER_LISTENER, data, reply, 0);
-        }
-        catch (RemoteException e) { }
-        finally {
-            reply.recycle();
-            data.recycle();
-            mCallbackTgt = null;
-        }
-    }
-
-    private static final int METHOD_IS_COMMON_TIME_VALID = IBinder.FIRST_CALL_TRANSACTION;
-    private static final int METHOD_COMMON_TIME_TO_LOCAL_TIME = METHOD_IS_COMMON_TIME_VALID + 1;
-    private static final int METHOD_LOCAL_TIME_TO_COMMON_TIME = METHOD_COMMON_TIME_TO_LOCAL_TIME + 1;
-    private static final int METHOD_GET_COMMON_TIME = METHOD_LOCAL_TIME_TO_COMMON_TIME + 1;
-    private static final int METHOD_GET_COMMON_FREQ = METHOD_GET_COMMON_TIME + 1;
-    private static final int METHOD_GET_LOCAL_TIME = METHOD_GET_COMMON_FREQ + 1;
-    private static final int METHOD_GET_LOCAL_FREQ = METHOD_GET_LOCAL_TIME + 1;
-    private static final int METHOD_GET_ESTIMATED_ERROR = METHOD_GET_LOCAL_FREQ + 1;
-    private static final int METHOD_GET_TIMELINE_ID = METHOD_GET_ESTIMATED_ERROR + 1;
-    private static final int METHOD_GET_STATE = METHOD_GET_TIMELINE_ID + 1;
-    private static final int METHOD_GET_MASTER_ADDRESS = METHOD_GET_STATE + 1;
-    private static final int METHOD_REGISTER_LISTENER = METHOD_GET_MASTER_ADDRESS + 1;
-    private static final int METHOD_UNREGISTER_LISTENER = METHOD_REGISTER_LISTENER + 1;
-
-    private static final int METHOD_CBK_ON_TIMELINE_CHANGED = IBinder.FIRST_CALL_TRANSACTION;
-}
diff --git a/core/java/android/os/CommonTimeConfig.java b/core/java/android/os/CommonTimeConfig.java
deleted file mode 100644
index 1f9fab5..0000000
--- a/core/java/android/os/CommonTimeConfig.java
+++ /dev/null
@@ -1,447 +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 android.os;
-
-import java.net.InetSocketAddress;
-import java.util.NoSuchElementException;
-
-import android.os.CommonTimeUtils;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-
-/**
- * Used for configuring and controlling the status of the android common time service.
- * @hide
- */
-public class CommonTimeConfig {
-    /**
-     * Successful operation.
-     */
-    public static final int SUCCESS = 0;
-    /**
-     * Unspecified error.
-     */
-    public static final int ERROR = -1;
-    /**
-     * Operation failed due to bad parameter value.
-     */
-    public static final int ERROR_BAD_VALUE = -4;
-    /**
-     * Operation failed due to dead remote object.
-     */
-    public static final int ERROR_DEAD_OBJECT = -7;
-
-    /**
-     * Sentinel value returned by {@link #getMasterElectionGroupId()} when an error occurs trying to
-     * fetch the master election group.
-     */
-    public static final long INVALID_GROUP_ID = -1;
-
-    /**
-     * Name of the underlying native binder service
-     */
-    public static final String SERVICE_NAME = "common_time.config";
-
-    /**
-     * Class constructor.
-     * @throws android.os.RemoteException
-     */
-    public CommonTimeConfig()
-    throws RemoteException {
-        mRemote = ServiceManager.getService(SERVICE_NAME);
-        if (null == mRemote)
-            throw new RemoteException();
-
-        mInterfaceDesc = mRemote.getInterfaceDescriptor();
-        mUtils = new CommonTimeUtils(mRemote, mInterfaceDesc);
-        mRemote.linkToDeath(mDeathHandler, 0);
-    }
-
-    /**
-     * Handy class factory method.
-     */
-    static public CommonTimeConfig create() {
-        CommonTimeConfig retVal;
-
-        try {
-            retVal = new CommonTimeConfig();
-        }
-        catch (RemoteException e) {
-            retVal = null;
-        }
-
-        return retVal;
-    }
-
-    /**
-     * Release all native resources held by this {@link android.os.CommonTimeConfig} instance.  Once
-     * resources have been released, the {@link android.os.CommonTimeConfig} instance is
-     * disconnected from the native service and will throw a {@link android.os.RemoteException} if
-     * any of its methods are called.  Clients should always call release on their client instances
-     * before releasing their last Java reference to the instance.  Failure to do this will cause
-     * non-deterministic native resource reclamation and may cause the common time service to remain
-     * active on the network for longer than it should.
-     */
-    public void release() {
-        if (null != mRemote) {
-            try {
-                mRemote.unlinkToDeath(mDeathHandler, 0);
-            }
-            catch (NoSuchElementException e) { }
-            mRemote = null;
-        }
-        mUtils = null;
-    }
-
-    /**
-     * Gets the current priority of the common time service used in the master election protocol.
-     *
-     * @return an 8 bit value indicating the priority of this common time service relative to other
-     * common time services operating in the same domain.
-     * @throws android.os.RemoteException
-     */
-    public byte getMasterElectionPriority()
-    throws RemoteException {
-        throwOnDeadServer();
-        return (byte)mUtils.transactGetInt(METHOD_GET_MASTER_ELECTION_PRIORITY, -1);
-    }
-
-    /**
-     * Sets the current priority of the common time service used in the master election protocol.
-     *
-     * @param priority priority of the common time service used in the master election protocol.
-     * Lower numbers are lower priority.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setMasterElectionPriority(byte priority) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-        return mUtils.transactSetInt(METHOD_SET_MASTER_ELECTION_PRIORITY, priority);
-    }
-
-    /**
-     * Gets the IP endpoint used by the time service to participate in the master election protocol.
-     *
-     * @return an InetSocketAddress containing the IP address and UDP port being used by the
-     * system's common time service to participate in the master election protocol.
-     * @throws android.os.RemoteException
-     */
-    public InetSocketAddress getMasterElectionEndpoint()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetSockaddr(METHOD_GET_MASTER_ELECTION_ENDPOINT);
-    }
-
-    /**
-     * Sets the IP endpoint used by the common time service to participate in the master election
-     * protocol.
-     *
-     * @param ep The IP address and UDP port to be used by the common time service to participate in
-     * the master election protocol.  The supplied IP address must be either the broadcast or
-     * multicast address, unicast addresses are considered to be illegal values.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setMasterElectionEndpoint(InetSocketAddress ep) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-        return mUtils.transactSetSockaddr(METHOD_SET_MASTER_ELECTION_ENDPOINT, ep);
-    }
-
-    /**
-     * Gets the current group ID used by the common time service in the master election protocol.
-     *
-     * @return The 64-bit group ID of the common time service.
-     * @throws android.os.RemoteException
-     */
-    public long getMasterElectionGroupId()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetLong(METHOD_GET_MASTER_ELECTION_GROUP_ID, INVALID_GROUP_ID);
-    }
-
-    /**
-     * Sets the current group ID used by the common time service in the master election protocol.
-     *
-     * @param id The 64-bit group ID of the common time service.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setMasterElectionGroupId(long id) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-        return mUtils.transactSetLong(METHOD_SET_MASTER_ELECTION_GROUP_ID, id);
-    }
-
-    /**
-     * Gets the name of the network interface which the common time service attempts to bind to.
-     *
-     * @return a string with the network interface name which the common time service is bound to,
-     * or null if the service is currently unbound.  Examples of interface names are things like
-     * "eth0", or "wlan0".
-     * @throws android.os.RemoteException
-     */
-    public String getInterfaceBinding()
-    throws RemoteException {
-        throwOnDeadServer();
-
-        String ifaceName = mUtils.transactGetString(METHOD_GET_INTERFACE_BINDING, null);
-
-        if ((null != ifaceName) && (0 == ifaceName.length()))
-                return null;
-
-        return ifaceName;
-    }
-
-    /**
-     * Sets the name of the network interface which the common time service should attempt to bind
-     * to.
-     *
-     * @param ifaceName The name of the network interface ("eth0", "wlan0", etc...) wich the common
-     * time service should attempt to bind to, or null to force the common time service to unbind
-     * from the network and run in networkless mode.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setNetworkBinding(String ifaceName) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-
-        return mUtils.transactSetString(METHOD_SET_INTERFACE_BINDING,
-                                       (null == ifaceName) ? "" : ifaceName);
-    }
-
-    /**
-     * Gets the amount of time the common time service will wait between master announcements when
-     * it is the timeline master.
-     *
-     * @return The time (in milliseconds) between master announcements.
-     * @throws android.os.RemoteException
-     */
-    public int getMasterAnnounceInterval()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetInt(METHOD_GET_MASTER_ANNOUNCE_INTERVAL, -1);
-    }
-
-    /**
-     * Sets the amount of time the common time service will wait between master announcements when
-     * it is the timeline master.
-     *
-     * @param interval The time (in milliseconds) between master announcements.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setMasterAnnounceInterval(int interval) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-        return mUtils.transactSetInt(METHOD_SET_MASTER_ANNOUNCE_INTERVAL, interval);
-    }
-
-    /**
-     * Gets the amount of time the common time service will wait between time synchronization
-     * requests when it is the client of another common time service on the network.
-     *
-     * @return The time (in milliseconds) between time sync requests.
-     * @throws android.os.RemoteException
-     */
-    public int getClientSyncInterval()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetInt(METHOD_GET_CLIENT_SYNC_INTERVAL, -1);
-    }
-
-    /**
-     * Sets the amount of time the common time service will wait between time synchronization
-     * requests when it is the client of another common time service on the network.
-     *
-     * @param interval The time (in milliseconds) between time sync requests.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setClientSyncInterval(int interval) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-        return mUtils.transactSetInt(METHOD_SET_CLIENT_SYNC_INTERVAL, interval);
-    }
-
-    /**
-     * Gets the panic threshold for the estimated error level of the common time service.  When the
-     * common time service's estimated error rises above this level, the service will panic and
-     * reset, causing a discontinuity in the currently synchronized timeline.
-     *
-     * @return The threshold (in microseconds) past which the common time service will panic.
-     * @throws android.os.RemoteException
-     */
-    public int getPanicThreshold()
-    throws RemoteException {
-        throwOnDeadServer();
-        return mUtils.transactGetInt(METHOD_GET_PANIC_THRESHOLD, -1);
-    }
-
-    /**
-     * Sets the panic threshold for the estimated error level of the common time service.  When the
-     * common time service's estimated error rises above this level, the service will panic and
-     * reset, causing a discontinuity in the currently synchronized timeline.
-     *
-     * @param threshold The threshold (in microseconds) past which the common time service will
-     * panic.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setPanicThreshold(int threshold) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-        return mUtils.transactSetInt(METHOD_SET_PANIC_THRESHOLD, threshold);
-    }
-
-    /**
-     * Gets the current state of the common time service's auto disable flag.
-     *
-     * @return The current state of the common time service's auto disable flag.
-     * @throws android.os.RemoteException
-     */
-    public boolean getAutoDisable()
-    throws RemoteException {
-        throwOnDeadServer();
-        return (1 == mUtils.transactGetInt(METHOD_GET_AUTO_DISABLE, 1));
-    }
-
-    /**
-     * Sets the current state of the common time service's auto disable flag.  When the time
-     * service's auto disable flag is set, it will automatically cease all network activity when
-     * it has no active local clients, resuming activity the next time the service has interested
-     * local clients.  When the auto disabled flag is cleared, the common time service will continue
-     * to participate the time synchronization group even when it has no active local clients.
-     *
-     * @param autoDisable The desired state of the common time service's auto disable flag.
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int setAutoDisable(boolean autoDisable) {
-        if (checkDeadServer())
-            return ERROR_DEAD_OBJECT;
-
-        return mUtils.transactSetInt(METHOD_SET_AUTO_DISABLE, autoDisable ? 1 : 0);
-    }
-
-    /**
-     * At startup, the time service enters the initial state and remains there until it is given a
-     * network interface to bind to.  Common time will be unavailable to clients of the common time
-     * service until the service joins a network (even an empty network).  Devices may use the
-     * {@link #forceNetworklessMasterMode()} method to force a time service in the INITIAL state
-     * with no network configuration to assume MASTER status for a brand new timeline in order to
-     * allow clients of the common time service to operate, even though the device is isolated and
-     * not on any network.  When a networkless master does join a network, it will defer to any
-     * masters already on the network, or continue to maintain the timeline it made up during its
-     * networkless state if no other masters are detected.  Attempting to force a client into master
-     * mode while it is actively bound to a network will fail with the status code {@link #ERROR}
-     *
-     * @return {@link #SUCCESS} in case of success,
-     * {@link #ERROR} or {@link #ERROR_DEAD_OBJECT} in case of failure.
-     */
-    public int forceNetworklessMasterMode() {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-            mRemote.transact(METHOD_FORCE_NETWORKLESS_MASTER_MODE, data, reply, 0);
-
-            return reply.readInt();
-        }
-        catch (RemoteException e) {
-            return ERROR_DEAD_OBJECT;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-    }
-
-    /**
-     * The OnServerDiedListener interface defines a method called by the
-     * {@link android.os.CommonTimeConfig} instance to indicate that the connection to the native
-     * media server has been broken and that the {@link android.os.CommonTimeConfig} instance will
-     * need to be released and re-created.  The client application can implement this interface and
-     * register the listener with the {@link #setServerDiedListener(OnServerDiedListener)} method.
-     */
-    public interface OnServerDiedListener  {
-        /**
-         * Method called when the native common time service has died.  <p>If the native common time
-         * service encounters a fatal error and needs to restart, the binder connection from the
-         * {@link android.os.CommonTimeConfig} instance to the common time service will be broken.
-         */
-        void onServerDied();
-    }
-
-    /**
-     * Registers an OnServerDiedListener interface.
-     * <p>Call this method with a null listener to stop receiving server death notifications.
-     */
-    public void setServerDiedListener(OnServerDiedListener listener) {
-        synchronized (mListenerLock) {
-            mServerDiedListener = listener;
-        }
-    }
-
-    protected void finalize() throws Throwable { release(); }
-
-    private boolean checkDeadServer() {
-        return ((null == mRemote) || (null == mUtils));
-    }
-
-    private void throwOnDeadServer() throws RemoteException {
-        if (checkDeadServer())
-            throw new RemoteException();
-    }
-
-    private final Object mListenerLock = new Object();
-    private OnServerDiedListener mServerDiedListener = null;
-
-    private IBinder mRemote = null;
-    private String mInterfaceDesc = "";
-    private CommonTimeUtils mUtils;
-
-    private IBinder.DeathRecipient mDeathHandler = new IBinder.DeathRecipient() {
-        public void binderDied() {
-            synchronized (mListenerLock) {
-                if (null != mServerDiedListener)
-                    mServerDiedListener.onServerDied();
-            }
-        }
-    };
-
-    private static final int METHOD_GET_MASTER_ELECTION_PRIORITY = IBinder.FIRST_CALL_TRANSACTION;
-    private static final int METHOD_SET_MASTER_ELECTION_PRIORITY = METHOD_GET_MASTER_ELECTION_PRIORITY + 1;
-    private static final int METHOD_GET_MASTER_ELECTION_ENDPOINT = METHOD_SET_MASTER_ELECTION_PRIORITY + 1;
-    private static final int METHOD_SET_MASTER_ELECTION_ENDPOINT = METHOD_GET_MASTER_ELECTION_ENDPOINT + 1;
-    private static final int METHOD_GET_MASTER_ELECTION_GROUP_ID = METHOD_SET_MASTER_ELECTION_ENDPOINT + 1;
-    private static final int METHOD_SET_MASTER_ELECTION_GROUP_ID = METHOD_GET_MASTER_ELECTION_GROUP_ID + 1;
-    private static final int METHOD_GET_INTERFACE_BINDING = METHOD_SET_MASTER_ELECTION_GROUP_ID + 1;
-    private static final int METHOD_SET_INTERFACE_BINDING = METHOD_GET_INTERFACE_BINDING + 1;
-    private static final int METHOD_GET_MASTER_ANNOUNCE_INTERVAL = METHOD_SET_INTERFACE_BINDING + 1;
-    private static final int METHOD_SET_MASTER_ANNOUNCE_INTERVAL = METHOD_GET_MASTER_ANNOUNCE_INTERVAL + 1;
-    private static final int METHOD_GET_CLIENT_SYNC_INTERVAL = METHOD_SET_MASTER_ANNOUNCE_INTERVAL + 1;
-    private static final int METHOD_SET_CLIENT_SYNC_INTERVAL = METHOD_GET_CLIENT_SYNC_INTERVAL + 1;
-    private static final int METHOD_GET_PANIC_THRESHOLD = METHOD_SET_CLIENT_SYNC_INTERVAL + 1;
-    private static final int METHOD_SET_PANIC_THRESHOLD = METHOD_GET_PANIC_THRESHOLD + 1;
-    private static final int METHOD_GET_AUTO_DISABLE = METHOD_SET_PANIC_THRESHOLD + 1;
-    private static final int METHOD_SET_AUTO_DISABLE = METHOD_GET_AUTO_DISABLE + 1;
-    private static final int METHOD_FORCE_NETWORKLESS_MASTER_MODE = METHOD_SET_AUTO_DISABLE + 1;
-}
diff --git a/core/java/android/os/CommonTimeUtils.java b/core/java/android/os/CommonTimeUtils.java
deleted file mode 100644
index ba060b8..0000000
--- a/core/java/android/os/CommonTimeUtils.java
+++ /dev/null
@@ -1,293 +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 android.os;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetSocketAddress;
-import java.util.Locale;
-import static android.system.OsConstants.*;
-
-class CommonTimeUtils {
-    /**
-     * Successful operation.
-     */
-    public static final int SUCCESS = 0;
-    /**
-     * Unspecified error.
-     */
-    public static final int ERROR = -1;
-    /**
-     * Operation failed due to bad parameter value.
-     */
-    public static final int ERROR_BAD_VALUE = -4;
-    /**
-     * Operation failed due to dead remote object.
-     */
-    public static final int ERROR_DEAD_OBJECT = -7;
-
-    public CommonTimeUtils(IBinder remote, String interfaceDesc) {
-        mRemote = remote;
-        mInterfaceDesc = interfaceDesc;
-    }
-
-    public int transactGetInt(int method_code, int error_ret_val)
-    throws RemoteException {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-        int ret_val;
-
-        try {
-            int res;
-            data.writeInterfaceToken(mInterfaceDesc);
-            mRemote.transact(method_code, data, reply, 0);
-
-            res = reply.readInt();
-            ret_val = (0 == res) ? reply.readInt() : error_ret_val;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-
-        return ret_val;
-    }
-
-    public int transactSetInt(int method_code, int val) {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-            data.writeInt(val);
-            mRemote.transact(method_code, data, reply, 0);
-
-            return reply.readInt();
-        }
-        catch (RemoteException e) {
-            return ERROR_DEAD_OBJECT;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-    }
-
-    public long transactGetLong(int method_code, long error_ret_val)
-    throws RemoteException {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-        long ret_val;
-
-        try {
-            int res;
-            data.writeInterfaceToken(mInterfaceDesc);
-            mRemote.transact(method_code, data, reply, 0);
-
-            res = reply.readInt();
-            ret_val = (0 == res) ? reply.readLong() : error_ret_val;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-
-        return ret_val;
-    }
-
-    public int transactSetLong(int method_code, long val) {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-            data.writeLong(val);
-            mRemote.transact(method_code, data, reply, 0);
-
-            return reply.readInt();
-        }
-        catch (RemoteException e) {
-            return ERROR_DEAD_OBJECT;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-    }
-
-    public String transactGetString(int method_code, String error_ret_val)
-    throws RemoteException {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-        String ret_val;
-
-        try {
-            int res;
-            data.writeInterfaceToken(mInterfaceDesc);
-            mRemote.transact(method_code, data, reply, 0);
-
-            res = reply.readInt();
-            ret_val = (0 == res) ? reply.readString() : error_ret_val;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-
-        return ret_val;
-    }
-
-    public int transactSetString(int method_code, String val) {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-            data.writeString(val);
-            mRemote.transact(method_code, data, reply, 0);
-
-            return reply.readInt();
-        }
-        catch (RemoteException e) {
-            return ERROR_DEAD_OBJECT;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-    }
-
-    public InetSocketAddress transactGetSockaddr(int method_code)
-    throws RemoteException {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-        InetSocketAddress ret_val = null;
-
-        try {
-            int res;
-            data.writeInterfaceToken(mInterfaceDesc);
-            mRemote.transact(method_code, data, reply, 0);
-
-            res = reply.readInt();
-            if (0 == res) {
-                int type;
-                int port = 0;
-                String addrStr = null;
-
-                type = reply.readInt();
-
-                if (AF_INET == type) {
-                    int addr = reply.readInt();
-                    port = reply.readInt();
-                    addrStr = String.format(Locale.US, "%d.%d.%d.%d",
-                                                       (addr >> 24) & 0xFF,
-                                                       (addr >> 16) & 0xFF,
-                                                       (addr >>  8) & 0xFF,
-                                                        addr        & 0xFF);
-                } else if (AF_INET6 == type) {
-                    int addr1 = reply.readInt();
-                    int addr2 = reply.readInt();
-                    int addr3 = reply.readInt();
-                    int addr4 = reply.readInt();
-
-                    port = reply.readInt();
-
-                    int flowinfo = reply.readInt();
-                    int scope_id = reply.readInt();
-
-                    addrStr = String.format(Locale.US, "[%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X]",
-                                                       (addr1 >> 16) & 0xFFFF, addr1 & 0xFFFF,
-                                                       (addr2 >> 16) & 0xFFFF, addr2 & 0xFFFF,
-                                                       (addr3 >> 16) & 0xFFFF, addr3 & 0xFFFF,
-                                                       (addr4 >> 16) & 0xFFFF, addr4 & 0xFFFF);
-                }
-
-                if (null != addrStr) {
-                    ret_val = new InetSocketAddress(addrStr, port);
-                }
-            }
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-
-        return ret_val;
-    }
-
-    public int transactSetSockaddr(int method_code, InetSocketAddress addr) {
-        android.os.Parcel data  = android.os.Parcel.obtain();
-        android.os.Parcel reply = android.os.Parcel.obtain();
-        int ret_val = ERROR;
-
-        try {
-            data.writeInterfaceToken(mInterfaceDesc);
-
-            if (null == addr) {
-                data.writeInt(0);
-            } else {
-                data.writeInt(1);
-                final InetAddress a = addr.getAddress();
-                final byte[]      b = a.getAddress();
-                final int         p = addr.getPort();
-
-                if (a instanceof Inet4Address) {
-                    int v4addr = (((int)b[0] & 0xFF) << 24) |
-                                 (((int)b[1] & 0xFF) << 16) |
-                                 (((int)b[2] & 0xFF) << 8) |
-                                  ((int)b[3] & 0xFF);
-
-                    data.writeInt(AF_INET);
-                    data.writeInt(v4addr);
-                    data.writeInt(p);
-                } else
-                if (a instanceof Inet6Address) {
-                    int i;
-                    Inet6Address v6 = (Inet6Address)a;
-                    data.writeInt(AF_INET6);
-                    for (i = 0; i < 4; ++i) {
-                        int aword = (((int)b[(i*4) + 0] & 0xFF) << 24) |
-                                    (((int)b[(i*4) + 1] & 0xFF) << 16) |
-                                    (((int)b[(i*4) + 2] & 0xFF) << 8) |
-                                     ((int)b[(i*4) + 3] & 0xFF);
-                        data.writeInt(aword);
-                    }
-                    data.writeInt(p);
-                    data.writeInt(0);   // flow info
-                    data.writeInt(v6.getScopeId());
-                } else {
-                    return ERROR_BAD_VALUE;
-                }
-            }
-
-            mRemote.transact(method_code, data, reply, 0);
-            ret_val = reply.readInt();
-        }
-        catch (RemoteException e) {
-            ret_val = ERROR_DEAD_OBJECT;
-        }
-        finally {
-            reply.recycle();
-            data.recycle();
-        }
-
-        return ret_val;
-    }
-
-    private IBinder mRemote;
-    private String mInterfaceDesc;
-};
diff --git a/libs/common_time/Android.mk b/libs/common_time/Android.mk
deleted file mode 100644
index 636f057..0000000
--- a/libs/common_time/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#
-# common_time_service
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    common_clock_service.cpp \
-    common_time_config_service.cpp \
-    common_time_server.cpp \
-    common_time_server_api.cpp \
-    common_time_server_packets.cpp \
-    clock_recovery.cpp \
-    common_clock.cpp \
-    main.cpp \
-    utils.cpp \
-    LinearTransform.cpp
-
-# Uncomment to enable vesbose logging and debug service.
-#TIME_SERVICE_DEBUG=true
-ifeq ($(TIME_SERVICE_DEBUG), true)
-LOCAL_SRC_FILES += diag_thread.cpp
-LOCAL_CFLAGS += -DTIME_SERVICE_DEBUG
-endif
-
-LOCAL_SHARED_LIBRARIES := \
-    libbinder \
-    libcommon_time_client \
-    libutils \
-    liblog
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := common_time
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
-include $(BUILD_EXECUTABLE)
diff --git a/libs/common_time/LinearTransform.cpp b/libs/common_time/LinearTransform.cpp
deleted file mode 100644
index 6730855..0000000
--- a/libs/common_time/LinearTransform.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#define __STDC_LIMIT_MACROS
-
-#include "LinearTransform.h"
-#include <assert.h>
-
-
-// disable sanitize as these functions may intentionally overflow (see comments below).
-// the ifdef can be removed when host builds use clang.
-#if defined(__clang__)
-#define ATTRIBUTE_NO_SANITIZE_INTEGER __attribute__((no_sanitize("integer")))
-#else
-#define ATTRIBUTE_NO_SANITIZE_INTEGER
-#endif
-
-namespace android {
-
-// sanitize failure with T = int32_t and x = 0x80000000
-template<class T>
-ATTRIBUTE_NO_SANITIZE_INTEGER
-static inline T ABS(T x) { return (x < 0) ? -x : x; }
-
-// Static math methods involving linear transformations
-// remote sanitize failure on overflow case.
-ATTRIBUTE_NO_SANITIZE_INTEGER
-static bool scale_u64_to_u64(
-        uint64_t val,
-        uint32_t N,
-        uint32_t D,
-        uint64_t* res,
-        bool round_up_not_down) {
-    uint64_t tmp1, tmp2;
-    uint32_t r;
-
-    assert(res);
-    assert(D);
-
-    // Let U32(X) denote a uint32_t containing the upper 32 bits of a 64 bit
-    // integer X.
-    // Let L32(X) denote a uint32_t containing the lower 32 bits of a 64 bit
-    // integer X.
-    // Let X[A, B] with A <= B denote bits A through B of the integer X.
-    // Let (A | B) denote the concatination of two 32 bit ints, A and B.
-    // IOW X = (A | B) => U32(X) == A && L32(X) == B
-    //
-    // compute M = val * N (a 96 bit int)
-    // ---------------------------------
-    // tmp2 = U32(val) * N (a 64 bit int)
-    // tmp1 = L32(val) * N (a 64 bit int)
-    // which means
-    // M = val * N = (tmp2 << 32) + tmp1
-    tmp2 = (val >> 32) * N;
-    tmp1 = (val & UINT32_MAX) * N;
-
-    // compute M[32, 95]
-    // tmp2 = tmp2 + U32(tmp1)
-    //      = (U32(val) * N) + U32(L32(val) * N)
-    //      = M[32, 95]
-    tmp2 += tmp1 >> 32;
-
-    // if M[64, 95] >= D, then M/D has bits > 63 set and we have
-    // an overflow.
-    if ((tmp2 >> 32) >= D) {
-        *res = UINT64_MAX;
-        return false;
-    }
-
-    // Divide.  Going in we know
-    // tmp2 = M[32, 95]
-    // U32(tmp2) < D
-    r = tmp2 % D;
-    tmp2 /= D;
-
-    // At this point
-    // tmp1      = L32(val) * N
-    // tmp2      = M[32, 95] / D
-    //           = (M / D)[32, 95]
-    // r         = M[32, 95] % D
-    // U32(tmp2) = 0
-    //
-    // compute tmp1 = (r | M[0, 31])
-    tmp1 = (tmp1 & UINT32_MAX) | ((uint64_t)r << 32);
-
-    // Divide again.  Keep the remainder around in order to round properly.
-    r = tmp1 % D;
-    tmp1 /= D;
-
-    // At this point
-    // tmp2      = (M / D)[32, 95]
-    // tmp1      = (M / D)[ 0, 31]
-    // r         =  M % D
-    // U32(tmp1) = 0
-    // U32(tmp2) = 0
-
-    // Pack the result and deal with the round-up case (As well as the
-    // remote possiblility over overflow in such a case).
-    *res = (tmp2 << 32) | tmp1;
-    if (r && round_up_not_down) {
-        ++(*res);
-        if (!(*res)) {
-            *res = UINT64_MAX;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// at least one known sanitize failure (see comment below)
-ATTRIBUTE_NO_SANITIZE_INTEGER
-static bool linear_transform_s64_to_s64(
-        int64_t  val,
-        int64_t  basis1,
-        int32_t  N,
-        uint32_t D,
-        bool     invert_frac,
-        int64_t  basis2,
-        int64_t* out) {
-    uint64_t scaled, res;
-    uint64_t abs_val;
-    bool is_neg;
-
-    if (!out)
-        return false;
-
-    // Compute abs(val - basis_64). Keep track of whether or not this delta
-    // will be negative after the scale opertaion.
-    if (val < basis1) {
-        is_neg = true;
-        abs_val = basis1 - val;
-    } else {
-        is_neg = false;
-        abs_val = val - basis1;
-    }
-
-    if (N < 0)
-        is_neg = !is_neg;
-
-    if (!scale_u64_to_u64(abs_val,
-                          invert_frac ? D : ABS(N),
-                          invert_frac ? ABS(N) : D,
-                          &scaled,
-                          is_neg))
-        return false; // overflow/undeflow
-
-    // if scaled is >= 0x8000<etc>, then we are going to overflow or
-    // underflow unless ABS(basis2) is large enough to pull us back into the
-    // non-overflow/underflow region.
-    if (scaled & INT64_MIN) {
-        if (is_neg && (basis2 < 0))
-            return false; // certain underflow
-
-        if (!is_neg && (basis2 >= 0))
-            return false; // certain overflow
-
-        if (ABS(basis2) <= static_cast<int64_t>(scaled & INT64_MAX))
-            return false; // not enough
-
-        // Looks like we are OK
-        *out = (is_neg ? (-scaled) : scaled) + basis2;
-    } else {
-        // Scaled fits within signed bounds, so we just need to check for
-        // over/underflow for two signed integers.  Basically, if both scaled
-        // and basis2 have the same sign bit, and the result has a different
-        // sign bit, then we have under/overflow.  An easy way to compute this
-        // is
-        // (scaled_signbit XNOR basis_signbit) &&
-        // (scaled_signbit XOR res_signbit)
-        // ==
-        // (scaled_signbit XOR basis_signbit XOR 1) &&
-        // (scaled_signbit XOR res_signbit)
-
-        if (is_neg)
-            scaled = -scaled; // known sanitize failure
-        res = scaled + basis2;
-
-        if ((scaled ^ basis2 ^ INT64_MIN) & (scaled ^ res) & INT64_MIN)
-            return false;
-
-        *out = res;
-    }
-
-    return true;
-}
-
-bool LinearTransform::doForwardTransform(int64_t a_in, int64_t* b_out) const {
-    if (0 == a_to_b_denom)
-        return false;
-
-    return linear_transform_s64_to_s64(a_in,
-                                       a_zero,
-                                       a_to_b_numer,
-                                       a_to_b_denom,
-                                       false,
-                                       b_zero,
-                                       b_out);
-}
-
-bool LinearTransform::doReverseTransform(int64_t b_in, int64_t* a_out) const {
-    if (0 == a_to_b_numer)
-        return false;
-
-    return linear_transform_s64_to_s64(b_in,
-                                       b_zero,
-                                       a_to_b_numer,
-                                       a_to_b_denom,
-                                       true,
-                                       a_zero,
-                                       a_out);
-}
-
-template <class T> void LinearTransform::reduce(T* N, T* D) {
-    T a, b;
-    if (!N || !D || !(*D)) {
-        assert(false);
-        return;
-    }
-
-    a = *N;
-    b = *D;
-
-    if (a == 0) {
-        *D = 1;
-        return;
-    }
-
-    // This implements Euclid's method to find GCD.
-    if (a < b) {
-        T tmp = a;
-        a = b;
-        b = tmp;
-    }
-
-    while (1) {
-        // a is now the greater of the two.
-        const T remainder = a % b;
-        if (remainder == 0) {
-            *N /= b;
-            *D /= b;
-            return;
-        }
-        // by swapping remainder and b, we are guaranteeing that a is
-        // still the greater of the two upon entrance to the loop.
-        a = b;
-        b = remainder;
-    }
-};
-
-template void LinearTransform::reduce<uint64_t>(uint64_t* N, uint64_t* D);
-template void LinearTransform::reduce<uint32_t>(uint32_t* N, uint32_t* D);
-
-// sanitize failure if *N = 0x80000000
-ATTRIBUTE_NO_SANITIZE_INTEGER
-void LinearTransform::reduce(int32_t* N, uint32_t* D) {
-    if (N && D && *D) {
-        if (*N < 0) {
-            *N = -(*N);
-            reduce(reinterpret_cast<uint32_t*>(N), D);
-            *N = -(*N);
-        } else {
-            reduce(reinterpret_cast<uint32_t*>(N), D);
-        }
-    }
-}
-
-}  // namespace android
diff --git a/libs/common_time/LinearTransform.h b/libs/common_time/LinearTransform.h
deleted file mode 100644
index bf6ab8e..0000000
--- a/libs/common_time/LinearTransform.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef _LINEAR_TRANSFORM_H
-#define _LINEAR_TRANSFORM_H
-
-#include <stdint.h>
-
-namespace android {
-
-// LinearTransform defines a structure which hold the definition of a
-// transformation from single dimensional coordinate system A into coordinate
-// system B (and back again).  Values in A and in B are 64 bit, the linear
-// scale factor is expressed as a rational number using two 32 bit values.
-//
-// Specifically, let
-// f(a) = b
-// F(b) = f^-1(b) = a
-// then
-//
-// f(a) = (((a - a_zero) * a_to_b_numer) / a_to_b_denom) + b_zero;
-//
-// and
-//
-// F(b) = (((b - b_zero) * a_to_b_denom) / a_to_b_numer) + a_zero;
-//
-struct LinearTransform {
-  int64_t  a_zero;
-  int64_t  b_zero;
-  int32_t  a_to_b_numer;
-  uint32_t a_to_b_denom;
-
-  // Transform from A->B
-  // Returns true on success, or false in the case of a singularity or an
-  // overflow.
-  bool doForwardTransform(int64_t a_in, int64_t* b_out) const;
-
-  // Transform from B->A
-  // Returns true on success, or false in the case of a singularity or an
-  // overflow.
-  bool doReverseTransform(int64_t b_in, int64_t* a_out) const;
-
-  // Helpers which will reduce the fraction N/D using Euclid's method.
-  template <class T> static void reduce(T* N, T* D);
-  static void reduce(int32_t* N, uint32_t* D);
-};
-
-
-}
-
-#endif  // _LINEAR_TRANSFORM_H
diff --git a/libs/common_time/clock_recovery.cpp b/libs/common_time/clock_recovery.cpp
deleted file mode 100644
index 392caa0..0000000
--- a/libs/common_time/clock_recovery.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-/*
- * A service that exchanges time synchronization information between
- * a master that defines a timeline and clients that follow the timeline.
- */
-
-#define __STDC_LIMIT_MACROS
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-#include <inttypes.h>
-#include <stdint.h>
-
-#include <common_time/local_clock.h>
-#include <assert.h>
-
-#include "clock_recovery.h"
-#include "common_clock.h"
-#ifdef TIME_SERVICE_DEBUG
-#include "diag_thread.h"
-#endif
-
-// Define log macro so we can make LOGV into LOGE when we are exclusively
-// debugging this code.
-#ifdef TIME_SERVICE_DEBUG
-#define LOG_TS ALOGE
-#else
-#define LOG_TS ALOGV
-#endif
-
-namespace android {
-
-ClockRecoveryLoop::ClockRecoveryLoop(LocalClock* local_clock,
-                                     CommonClock* common_clock) {
-    assert(NULL != local_clock);
-    assert(NULL != common_clock);
-
-    local_clock_  = local_clock;
-    common_clock_ = common_clock;
-
-    local_clock_can_slew_ = local_clock_->initCheck() &&
-                           (local_clock_->setLocalSlew(0) == OK);
-    tgt_correction_ = 0;
-    cur_correction_ = 0;
-
-    // Precompute the max rate at which we are allowed to change the VCXO
-    // control.
-    uint64_t N = 0x10000ull * 1000ull;
-    uint64_t D = local_clock_->getLocalFreq() * kMinFullRangeSlewChange_mSec;
-    LinearTransform::reduce(&N, &D);
-    while ((N > INT32_MAX) || (D > UINT32_MAX)) {
-        N >>= 1;
-        D >>= 1;
-        LinearTransform::reduce(&N, &D);
-    }
-    time_to_cur_slew_.a_to_b_numer = static_cast<int32_t>(N);
-    time_to_cur_slew_.a_to_b_denom = static_cast<uint32_t>(D);
-
-    reset(true, true);
-
-#ifdef TIME_SERVICE_DEBUG
-    diag_thread_ = new DiagThread(common_clock_, local_clock_);
-    if (diag_thread_ != NULL) {
-        status_t res = diag_thread_->startWorkThread();
-        if (res != OK)
-            ALOGW("Failed to start A@H clock recovery diagnostic thread.");
-    } else
-        ALOGW("Failed to allocate diagnostic thread.");
-#endif
-}
-
-ClockRecoveryLoop::~ClockRecoveryLoop() {
-#ifdef TIME_SERVICE_DEBUG
-    diag_thread_->stopWorkThread();
-#endif
-}
-
-// Constants.
-const float ClockRecoveryLoop::dT = 1.0;
-const float ClockRecoveryLoop::Kc = 1.0f;
-const float ClockRecoveryLoop::Ti = 15.0f;
-const float ClockRecoveryLoop::Tf = 0.05;
-const float ClockRecoveryLoop::bias_Fc = 0.01;
-const float ClockRecoveryLoop::bias_RC = (dT / (2 * 3.14159f * bias_Fc));
-const float ClockRecoveryLoop::bias_Alpha = (dT / (bias_RC + dT));
-const int64_t ClockRecoveryLoop::panic_thresh_ = 50000;
-const int64_t ClockRecoveryLoop::control_thresh_ = 10000;
-const float ClockRecoveryLoop::COmin = -100.0f;
-const float ClockRecoveryLoop::COmax = 100.0f;
-const uint32_t ClockRecoveryLoop::kMinFullRangeSlewChange_mSec = 300;
-const int ClockRecoveryLoop::kSlewChangeStepPeriod_mSec = 10;
-
-
-void ClockRecoveryLoop::reset(bool position, bool frequency) {
-    Mutex::Autolock lock(&lock_);
-    reset_l(position, frequency);
-}
-
-uint32_t ClockRecoveryLoop::findMinRTTNdx(DisciplineDataPoint* data,
-                                          uint32_t count) {
-    uint32_t min_rtt = 0;
-    for (uint32_t i = 1; i < count; ++i)
-        if (data[min_rtt].rtt > data[i].rtt)
-            min_rtt = i;
-
-    return min_rtt;
-}
-
-bool ClockRecoveryLoop::pushDisciplineEvent(int64_t local_time,
-                                            int64_t nominal_common_time,
-                                            int64_t rtt) {
-    Mutex::Autolock lock(&lock_);
-
-    int64_t local_common_time = 0;
-    common_clock_->localToCommon(local_time, &local_common_time);
-    int64_t raw_delta = nominal_common_time - local_common_time;
-
-#ifdef TIME_SERVICE_DEBUG
-    ALOGE("local=%lld, common=%lld, delta=%lld, rtt=%lld\n",
-         local_common_time, nominal_common_time,
-         raw_delta, rtt);
-#endif
-
-    // If we have not defined a basis for common time, then we need to use these
-    // initial points to do so.  In order to avoid significant initial error
-    // from a particularly bad startup data point, we collect the first N data
-    // points and choose the best of them before moving on.
-    if (!common_clock_->isValid()) {
-        if (startup_filter_wr_ < kStartupFilterSize) {
-            DisciplineDataPoint& d =  startup_filter_data_[startup_filter_wr_];
-            d.local_time = local_time;
-            d.nominal_common_time = nominal_common_time;
-            d.rtt = rtt;
-            startup_filter_wr_++;
-        }
-
-        if (startup_filter_wr_ == kStartupFilterSize) {
-            uint32_t min_rtt = findMinRTTNdx(startup_filter_data_,
-                    kStartupFilterSize);
-
-            common_clock_->setBasis(
-                    startup_filter_data_[min_rtt].local_time,
-                    startup_filter_data_[min_rtt].nominal_common_time);
-        }
-
-        return true;
-    }
-
-    int64_t observed_common;
-    int64_t delta;
-    float delta_f, dCO;
-    int32_t tgt_correction;
-
-    if (OK != common_clock_->localToCommon(local_time, &observed_common)) {
-        // Since we just checked to make certain that this conversion was valid,
-        // and no one else in the system should be messing with it, if this
-        // conversion is suddenly invalid, it is a good reason to panic.
-        ALOGE("Failed to convert local time to common time in %s:%d",
-                __PRETTY_FUNCTION__, __LINE__);
-        return false;
-    }
-
-    // Implement a filter which should match NTP filtering behavior when a
-    // client is associated with only one peer of lower stratum.  Basically,
-    // always use the best of the N last data points, where best is defined as
-    // lowest round trip time.  NTP uses an N of 8; we use a value of 6.
-    //
-    // TODO(johngro) : experiment with other filter strategies.  The goal here
-    // is to mitigate the effects of high RTT data points which typically have
-    // large asymmetries in the TX/RX legs.  Downside of the existing NTP
-    // approach (particularly because of the PID controller we are using to
-    // produce the control signal from the filtered data) are that the rate at
-    // which discipline events are actually acted upon becomes irregular and can
-    // become drawn out (the time between actionable event can go way up).  If
-    // the system receives a strong high quality data point, the proportional
-    // component of the controller can produce a strong correction which is left
-    // in place for too long causing overshoot.  In addition, the integral
-    // component of the system currently is an approximation based on the
-    // assumption of a more or less homogeneous sampling of the error.  Its
-    // unclear what the effect of undermining this assumption would be right
-    // now.
-
-    // Two ideas which come to mind immediately would be to...
-    // 1) Keep a history of more data points (32 or so) and ignore data points
-    //    whose RTT is more than a certain number of standard deviations outside
-    //    of the norm.
-    // 2) Eliminate the PID controller portion of this system entirely.
-    //    Instead, move to a system which uses a very wide filter (128 data
-    //    points or more) with a sum-of-least-squares line fitting approach to
-    //    tracking the long term drift.  This would take the place of the I
-    //    component in the current PID controller.  Also use a much more narrow
-    //    outlier-rejector filter (as described in #1) to drive a short term
-    //    correction factor similar to the P component of the PID controller.
-    assert(filter_wr_ < kFilterSize);
-    filter_data_[filter_wr_].local_time           = local_time;
-    filter_data_[filter_wr_].observed_common_time = observed_common;
-    filter_data_[filter_wr_].nominal_common_time  = nominal_common_time;
-    filter_data_[filter_wr_].rtt                  = rtt;
-    filter_data_[filter_wr_].point_used           = false;
-    uint32_t current_point = filter_wr_;
-    filter_wr_ = (filter_wr_ + 1) % kFilterSize;
-    if (!filter_wr_)
-        filter_full_ = true;
-
-    uint32_t scan_end = filter_full_ ? kFilterSize : filter_wr_;
-    uint32_t min_rtt = findMinRTTNdx(filter_data_, scan_end);
-    // We only use packets with low RTTs for control. If the packet RTT
-    // is less than the panic threshold, we can probably eat the jitter with the
-    // control loop. Otherwise, take the packet only if it better than all
-    // of the packets we have in the history. That way we try to track
-    // something, even if it is noisy.
-    if (current_point == min_rtt || rtt < control_thresh_) {
-        delta_f = delta = nominal_common_time - observed_common;
-
-        last_error_est_valid_ = true;
-        last_error_est_usec_ = delta;
-
-        // Compute the error then clamp to the panic threshold.  If we ever
-        // exceed this amt of error, its time to panic and reset the system.
-        // Given that the error in the measurement of the error could be as
-        // high as the RTT of the data point, we don't actually panic until
-        // the implied error (delta) is greater than the absolute panic
-        // threashold plus the RTT.  IOW - we don't panic until we are
-        // absoluely sure that our best case sync is worse than the absolute
-        // panic threshold.
-        int64_t effective_panic_thresh = panic_thresh_ + rtt;
-        if ((delta > effective_panic_thresh) ||
-            (delta < -effective_panic_thresh)) {
-            // PANIC!!!
-            reset_l(false, true);
-            return false;
-        }
-
-    } else {
-        // We do not have a good packet to look at, but we also do not want to
-        // free-run the clock at some crazy slew rate. So we guess the
-        // trajectory of the clock based on the last controller output and the
-        // estimated bias of our clock against the master.
-        // The net effect of this is that CO == CObias after some extended
-        // period of no feedback.
-        delta_f = last_delta_f_ - dT*(CO - CObias);
-        delta = delta_f;
-    }
-
-    // Velocity form PI control equation.
-    dCO = Kc * (1.0f + dT/Ti) * delta_f - Kc * last_delta_f_;
-    CO += dCO * Tf; // Filter CO by applying gain <1 here.
-
-    // Save error terms for later.
-    last_delta_f_ = delta_f;
-
-    // Clamp CO to +/- 100ppm.
-    if (CO < COmin)
-        CO = COmin;
-    else if (CO > COmax)
-        CO = COmax;
-
-    // Update the controller bias.
-    CObias = bias_Alpha * CO + (1.0f - bias_Alpha) * lastCObias;
-    lastCObias = CObias;
-
-    // Convert PPM to 16-bit int range. Add some guard band (-0.01) so we
-    // don't get fp weirdness.
-    tgt_correction = CO * 327.66;
-
-    // If there was a change in the amt of correction to use, update the
-    // system.
-    setTargetCorrection_l(tgt_correction);
-
-    LOG_TS("clock_loop %" PRId64 " %f %f %f %d\n", raw_delta, delta_f, CO, CObias, tgt_correction);
-
-#ifdef TIME_SERVICE_DEBUG
-    diag_thread_->pushDisciplineEvent(
-            local_time,
-            observed_common,
-            nominal_common_time,
-            tgt_correction,
-            rtt);
-#endif
-
-    return true;
-}
-
-int32_t ClockRecoveryLoop::getLastErrorEstimate() {
-    Mutex::Autolock lock(&lock_);
-
-    if (last_error_est_valid_)
-        return last_error_est_usec_;
-    else
-        return ICommonClock::kErrorEstimateUnknown;
-}
-
-void ClockRecoveryLoop::reset_l(bool position, bool frequency) {
-    assert(NULL != common_clock_);
-
-    if (position) {
-        common_clock_->resetBasis();
-        startup_filter_wr_ = 0;
-    }
-
-    if (frequency) {
-        last_error_est_valid_ = false;
-        last_error_est_usec_ = 0;
-        last_delta_f_ = 0.0;
-        CO = 0.0f;
-        lastCObias = CObias = 0.0f;
-        setTargetCorrection_l(0);
-        applySlew_l();
-    }
-
-    filter_wr_   = 0;
-    filter_full_ = false;
-}
-
-void ClockRecoveryLoop::setTargetCorrection_l(int32_t tgt) {
-    // When we make a change to the slew rate, we need to be careful to not
-    // change it too quickly as it can anger some HDMI sinks out there, notably
-    // some Sony panels from the 2010-2011 timeframe.  From experimenting with
-    // some of these sinks, it seems like swinging from one end of the range to
-    // another in less that 190mSec or so can start to cause trouble.  Adding in
-    // a hefty margin, we limit the system to a full range sweep in no less than
-    // 300mSec.
-    if (tgt_correction_ != tgt) {
-        int64_t now = local_clock_->getLocalTime();
-
-        tgt_correction_ = tgt;
-
-        // Set up the transformation to figure out what the slew should be at
-        // any given point in time in the future.
-        time_to_cur_slew_.a_zero = now;
-        time_to_cur_slew_.b_zero = cur_correction_;
-
-        // Make sure the sign of the slope is headed in the proper direction.
-        bool needs_increase = (cur_correction_ < tgt_correction_);
-        bool is_increasing  = (time_to_cur_slew_.a_to_b_numer > 0);
-        if (( needs_increase && !is_increasing) ||
-            (!needs_increase &&  is_increasing)) {
-            time_to_cur_slew_.a_to_b_numer = -time_to_cur_slew_.a_to_b_numer;
-        }
-
-        // Finally, figure out when the change will be finished and start the
-        // slew operation.
-        time_to_cur_slew_.doReverseTransform(tgt_correction_,
-                                             &slew_change_end_time_);
-
-        applySlew_l();
-    }
-}
-
-bool ClockRecoveryLoop::applySlew_l() {
-    bool ret = true;
-
-    // If cur == tgt, there is no ongoing sleq rate change and we are already
-    // finished.
-    if (cur_correction_ == tgt_correction_)
-        goto bailout;
-
-    if (local_clock_can_slew_) {
-        int64_t now = local_clock_->getLocalTime();
-        int64_t tmp;
-
-        if (now >= slew_change_end_time_) {
-            cur_correction_ = tgt_correction_;
-            next_slew_change_timeout_.setTimeout(-1);
-        } else {
-            time_to_cur_slew_.doForwardTransform(now, &tmp);
-
-            if (tmp > INT16_MAX)
-                cur_correction_ = INT16_MAX;
-            else if (tmp < INT16_MIN)
-                cur_correction_ = INT16_MIN;
-            else
-                cur_correction_ = static_cast<int16_t>(tmp);
-
-            next_slew_change_timeout_.setTimeout(kSlewChangeStepPeriod_mSec);
-            ret = false;
-        }
-
-        local_clock_->setLocalSlew(cur_correction_);
-    } else {
-        // Since we are not actually changing the rate of a HW clock, we don't
-        // need to worry to much about changing the slew rate so fast that we
-        // anger any downstream HDMI devices.
-        cur_correction_ = tgt_correction_;
-        next_slew_change_timeout_.setTimeout(-1);
-
-        // The SW clock recovery implemented by the common clock class expects
-        // values expressed in PPM. CO is in ppm.
-        common_clock_->setSlew(local_clock_->getLocalTime(), CO);
-    }
-
-bailout:
-    return ret;
-}
-
-int ClockRecoveryLoop::applyRateLimitedSlew() {
-    Mutex::Autolock lock(&lock_);
-
-    int ret = next_slew_change_timeout_.msecTillTimeout();
-    if (!ret) {
-        if (applySlew_l())
-            next_slew_change_timeout_.setTimeout(-1);
-        ret = next_slew_change_timeout_.msecTillTimeout();
-    }
-
-    return ret;
-}
-
-}  // namespace android
diff --git a/libs/common_time/clock_recovery.h b/libs/common_time/clock_recovery.h
deleted file mode 100644
index 8066a39..0000000
--- a/libs/common_time/clock_recovery.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef __CLOCK_RECOVERY_H__
-#define __CLOCK_RECOVERY_H__
-
-#include <stdint.h>
-#include <common_time/ICommonClock.h>
-#include <utils/threads.h>
-
-#include "LinearTransform.h"
-
-#ifdef TIME_SERVICE_DEBUG
-#include "diag_thread.h"
-#endif
-
-#include "utils.h"
-
-namespace android {
-
-class CommonClock;
-class LocalClock;
-
-class ClockRecoveryLoop {
-  public:
-     ClockRecoveryLoop(LocalClock* local_clock, CommonClock* common_clock);
-    ~ClockRecoveryLoop();
-
-    void reset(bool position, bool frequency);
-    bool pushDisciplineEvent(int64_t local_time,
-                             int64_t nominal_common_time,
-                             int64_t data_point_rtt);
-    int32_t getLastErrorEstimate();
-
-    // Applies the next step in any ongoing slew change operation.  Returns a
-    // timeout suitable for use with poll/select indicating the number of mSec
-    // until the next change should be applied.
-    int applyRateLimitedSlew();
-
-  private:
-
-    // Tuned using the "Good Gain" method.
-    // See:
-    // http://techteach.no/publications/books/dynamics_and_control/tuning_pid_controller.pdf
-
-    // Controller period (1Hz for now).
-    static const float dT;
-
-    // Controller gain, positive and unitless. Larger values converge faster,
-    // but can cause instability.
-    static const float Kc;
-
-    // Integral reset time. Smaller values cause loop to track faster, but can
-    // also cause instability.
-    static const float Ti;
-
-    // Controller output filter time constant. Range (0-1). Smaller values make
-    // output smoother, but slow convergence.
-    static const float Tf;
-
-    // Low-pass filter for bias tracker.
-    static const float bias_Fc; // HZ
-    static const float bias_RC; // Computed in constructor.
-    static const float bias_Alpha; // Computed inconstructor.
-
-    // The maximum allowed error (as indicated by a  pushDisciplineEvent) before
-    // we panic.
-    static const int64_t panic_thresh_;
-
-    // The maximum allowed error rtt time for packets to be used for control
-    // feedback, unless the packet is the best in recent memory.
-    static const int64_t control_thresh_;
-
-    typedef struct {
-        int64_t local_time;
-        int64_t observed_common_time;
-        int64_t nominal_common_time;
-        int64_t rtt;
-        bool point_used;
-    } DisciplineDataPoint;
-
-    static uint32_t findMinRTTNdx(DisciplineDataPoint* data, uint32_t count);
-
-    void reset_l(bool position, bool frequency);
-    void setTargetCorrection_l(int32_t tgt);
-    bool applySlew_l();
-
-    // The local clock HW abstraction we use as the basis for common time.
-    LocalClock* local_clock_;
-    bool local_clock_can_slew_;
-
-    // The common clock we end up controlling along with the lock used to
-    // serialize operations.
-    CommonClock* common_clock_;
-    Mutex lock_;
-
-    // parameters maintained while running and reset during a reset
-    // of the frequency correction.
-    bool    last_error_est_valid_;
-    int32_t last_error_est_usec_;
-    float last_delta_f_;
-    int32_t tgt_correction_;
-    int32_t cur_correction_;
-    LinearTransform time_to_cur_slew_;
-    int64_t slew_change_end_time_;
-    Timeout next_slew_change_timeout_;
-
-    // Contoller Output.
-    float CO;
-
-    // Bias tracking for trajectory estimation.
-    float CObias;
-    float lastCObias;
-
-    // Controller output bounds. The controller will not try to
-    // slew faster that +/-100ppm offset from center per interation.
-    static const float COmin;
-    static const float COmax;
-
-    // State kept for filtering the discipline data.
-    static const uint32_t kFilterSize = 16;
-    DisciplineDataPoint filter_data_[kFilterSize];
-    uint32_t filter_wr_;
-    bool filter_full_;
-
-    static const uint32_t kStartupFilterSize = 4;
-    DisciplineDataPoint startup_filter_data_[kStartupFilterSize];
-    uint32_t startup_filter_wr_;
-
-    // Minimum number of milliseconds over which we allow a full range change
-    // (from rail to rail) of the VCXO control signal.  This is the rate
-    // limiting factor which keeps us from changing the clock rate so fast that
-    // we get in trouble with certain HDMI sinks.
-    static const uint32_t kMinFullRangeSlewChange_mSec;
-
-    // How much time (in msec) to wait 
-    static const int kSlewChangeStepPeriod_mSec;
-
-#ifdef TIME_SERVICE_DEBUG
-    sp<DiagThread> diag_thread_;
-#endif
-};
-
-}  // namespace android
-
-#endif  // __CLOCK_RECOVERY_H__
diff --git a/libs/common_time/common_clock.cpp b/libs/common_time/common_clock.cpp
deleted file mode 100644
index aed52f1..0000000
--- a/libs/common_time/common_clock.cpp
+++ /dev/null
@@ -1,150 +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.
- */
-
-#define __STDC_LIMIT_MACROS
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <inttypes.h>
-#include <stdint.h>
-
-#include <utils/Errors.h>
-
-#include "common_clock.h"
-
-namespace android {
-
-CommonClock::CommonClock() {
-    cur_slew_        = 0;
-    cur_trans_valid_ = false;
-
-    cur_trans_.a_zero = 0;
-    cur_trans_.b_zero = 0;
-    cur_trans_.a_to_b_numer = local_to_common_freq_numer_ = 1;
-    cur_trans_.a_to_b_denom = local_to_common_freq_denom_ = 1;
-    duration_trans_ = cur_trans_;
-}
-
-bool CommonClock::init(uint64_t local_freq) {
-    Mutex::Autolock lock(&lock_);
-
-    if (!local_freq)
-        return false;
-
-    uint64_t numer = kCommonFreq;
-    uint64_t denom = local_freq;
-
-    LinearTransform::reduce(&numer, &denom);
-    if ((numer > UINT32_MAX) || (denom > UINT32_MAX)) {
-        ALOGE("Overflow in CommonClock::init while trying to reduce %" PRIu64 "/%" PRIu64,
-             kCommonFreq, local_freq);
-        return false;
-    }
-
-    cur_trans_.a_to_b_numer = local_to_common_freq_numer_ =
-        static_cast<uint32_t>(numer);
-    cur_trans_.a_to_b_denom = local_to_common_freq_denom_ =
-        static_cast<uint32_t>(denom);
-    duration_trans_ = cur_trans_;
-
-    return true;
-}
-
-status_t CommonClock::localToCommon(int64_t local, int64_t *common_out) const {
-    Mutex::Autolock lock(&lock_);
-
-    if (!cur_trans_valid_)
-        return INVALID_OPERATION;
-
-    if (!cur_trans_.doForwardTransform(local, common_out))
-        return INVALID_OPERATION;
-
-    return OK;
-}
-
-status_t CommonClock::commonToLocal(int64_t common, int64_t *local_out) const {
-    Mutex::Autolock lock(&lock_);
-
-    if (!cur_trans_valid_)
-        return INVALID_OPERATION;
-
-    if (!cur_trans_.doReverseTransform(common, local_out))
-        return INVALID_OPERATION;
-
-    return OK;
-}
-
-int64_t CommonClock::localDurationToCommonDuration(int64_t localDur) const {
-    int64_t ret;
-    duration_trans_.doForwardTransform(localDur, &ret);
-    return ret;
-}
-
-void CommonClock::setBasis(int64_t local, int64_t common) {
-    Mutex::Autolock lock(&lock_);
-
-    cur_trans_.a_zero = local;
-    cur_trans_.b_zero = common;
-    cur_trans_valid_ = true;
-}
-
-void CommonClock::resetBasis() {
-    Mutex::Autolock lock(&lock_);
-
-    cur_trans_.a_zero = 0;
-    cur_trans_.b_zero = 0;
-    cur_trans_valid_ = false;
-}
-
-status_t CommonClock::setSlew(int64_t change_time, int32_t ppm) {
-    Mutex::Autolock lock(&lock_);
-
-    int64_t new_local_basis;
-    int64_t new_common_basis;
-
-    if (cur_trans_valid_) {
-        new_local_basis = change_time;
-        if (!cur_trans_.doForwardTransform(change_time, &new_common_basis)) {
-            ALOGE("Overflow when attempting to set slew rate to %d", ppm);
-            return INVALID_OPERATION;
-        }
-    } else {
-        new_local_basis = 0;
-        new_common_basis = 0;
-    }
-
-    cur_slew_ = ppm;
-    uint32_t n1 = local_to_common_freq_numer_;
-    uint32_t n2 = 1000000 + cur_slew_;
-
-    uint32_t d1 = local_to_common_freq_denom_;
-    uint32_t d2 = 1000000;
-
-    // n1/d1 has already been reduced, no need to do so here.
-    LinearTransform::reduce(&n1, &d2);
-    LinearTransform::reduce(&n2, &d1);
-    LinearTransform::reduce(&n2, &d2);
-
-    cur_trans_.a_zero = new_local_basis;
-    cur_trans_.b_zero = new_common_basis;
-    cur_trans_.a_to_b_numer = n1 * n2;
-    cur_trans_.a_to_b_denom = d1 * d2;
-
-    return OK;
-}
-
-}  // namespace android
diff --git a/libs/common_time/common_clock.h b/libs/common_time/common_clock.h
deleted file mode 100644
index 5e4e5f5..0000000
--- a/libs/common_time/common_clock.h
+++ /dev/null
@@ -1,58 +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.
- */
-
-#ifndef __COMMON_CLOCK_H__
-#define __COMMON_CLOCK_H__
-
-#include <stdint.h>
-
-#include <utils/Errors.h>
-#include <utils/threads.h>
-
-#include "LinearTransform.h"
-
-namespace android {
-
-class CommonClock {
-  public:
-    CommonClock();
-
-    bool      init(uint64_t local_freq);
-
-    status_t  localToCommon(int64_t local, int64_t *common_out) const;
-    status_t  commonToLocal(int64_t common, int64_t *local_out) const;
-    int64_t   localDurationToCommonDuration(int64_t localDur) const;
-    uint64_t  getCommonFreq() const { return kCommonFreq; }
-    bool      isValid() const { return cur_trans_valid_; }
-    status_t  setSlew(int64_t change_time, int32_t ppm);
-    void      setBasis(int64_t local, int64_t common);
-    void      resetBasis();
-  private:
-    mutable Mutex lock_;
-
-    int32_t  cur_slew_;
-    uint32_t local_to_common_freq_numer_;
-    uint32_t local_to_common_freq_denom_;
-
-    LinearTransform duration_trans_;
-    LinearTransform cur_trans_;
-    bool cur_trans_valid_;
-
-    static const uint64_t kCommonFreq = 1000000ull;
-};
-
-}  // namespace android
-#endif  // __COMMON_CLOCK_H__
diff --git a/libs/common_time/common_clock_service.cpp b/libs/common_time/common_clock_service.cpp
deleted file mode 100644
index 592ab1d..0000000
--- a/libs/common_time/common_clock_service.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#include <common_time/local_clock.h>
-#include <utils/String8.h>
-
-#include "common_clock_service.h"
-#include "common_clock.h"
-#include "common_time_server.h"
-
-namespace android {
-
-sp<CommonClockService> CommonClockService::instantiate(
-        CommonTimeServer& timeServer) {
-    sp<CommonClockService> tcc = new CommonClockService(timeServer);
-    if (tcc == NULL)
-        return NULL;
-
-    defaultServiceManager()->addService(ICommonClock::kServiceName, tcc);
-    return tcc;
-}
-
-status_t CommonClockService::dump(int fd, const Vector<String16>& args) {
-    Mutex::Autolock lock(mRegistrationLock);
-    return mTimeServer.dumpClockInterface(fd, args, mListeners.size());
-}
-
-status_t CommonClockService::isCommonTimeValid(bool* valid,
-                                               uint32_t* timelineID) {
-    return mTimeServer.isCommonTimeValid(valid, timelineID);
-}
-
-status_t CommonClockService::commonTimeToLocalTime(int64_t  commonTime,
-                                                   int64_t* localTime) {
-    return mTimeServer.getCommonClock().commonToLocal(commonTime, localTime);
-}
-
-status_t CommonClockService::localTimeToCommonTime(int64_t  localTime,
-                                                   int64_t* commonTime) {
-    return mTimeServer.getCommonClock().localToCommon(localTime, commonTime);
-}
-
-status_t CommonClockService::getCommonTime(int64_t* commonTime) {
-    return localTimeToCommonTime(mTimeServer.getLocalClock().getLocalTime(), commonTime);
-}
-
-status_t CommonClockService::getCommonFreq(uint64_t* freq) {
-    *freq = mTimeServer.getCommonClock().getCommonFreq();
-    return OK;
-}
-
-status_t CommonClockService::getLocalTime(int64_t* localTime) {
-    *localTime = mTimeServer.getLocalClock().getLocalTime();
-    return OK;
-}
-
-status_t CommonClockService::getLocalFreq(uint64_t* freq) {
-    *freq = mTimeServer.getLocalClock().getLocalFreq();
-    return OK;
-}
-
-status_t CommonClockService::getEstimatedError(int32_t* estimate) {
-    *estimate = mTimeServer.getEstimatedError();
-    return OK;
-}
-
-status_t CommonClockService::getTimelineID(uint64_t* id) {
-    *id = mTimeServer.getTimelineID();
-    return OK;
-}
-
-status_t CommonClockService::getState(State* state) {
-    *state = mTimeServer.getState();
-    return OK;
-}
-
-status_t CommonClockService::getMasterAddr(struct sockaddr_storage* addr) {
-    return mTimeServer.getMasterAddr(addr);
-}
-
-status_t CommonClockService::registerListener(
-        const sp<ICommonClockListener>& listener) {
-    Mutex::Autolock lock(mRegistrationLock);
-
-    {   // scoping for autolock pattern
-        Mutex::Autolock lock(mCallbackLock);
-        // check whether this is a duplicate
-        for (size_t i = 0; i < mListeners.size(); i++) {
-            if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener))
-                return ALREADY_EXISTS;
-        }
-    }
-
-    mListeners.add(listener);
-    mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
-    return IInterface::asBinder(listener)->linkToDeath(this);
-}
-
-status_t CommonClockService::unregisterListener(
-        const sp<ICommonClockListener>& listener) {
-    Mutex::Autolock lock(mRegistrationLock);
-    status_t ret_val = NAME_NOT_FOUND;
-
-    {   // scoping for autolock pattern
-        Mutex::Autolock lock(mCallbackLock);
-        for (size_t i = 0; i < mListeners.size(); i++) {
-            if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) {
-                IInterface::asBinder(mListeners[i])->unlinkToDeath(this);
-                mListeners.removeAt(i);
-                ret_val = OK;
-                break;
-            }
-        }
-    }
-
-    mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
-    return ret_val;
-}
-
-void CommonClockService::binderDied(const wp<IBinder>& who) {
-    Mutex::Autolock lock(mRegistrationLock);
-
-    {   // scoping for autolock pattern
-        Mutex::Autolock lock(mCallbackLock);
-        for (size_t i = 0; i < mListeners.size(); i++) {
-            if (IInterface::asBinder(mListeners[i]) == who) {
-                mListeners.removeAt(i);
-                break;
-            }
-        }
-    }
-
-    mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
-}
-
-void CommonClockService::notifyOnTimelineChanged(uint64_t timelineID) {
-    Mutex::Autolock lock(mCallbackLock);
-
-    for (size_t i = 0; i < mListeners.size(); i++) {
-        mListeners[i]->onTimelineChanged(timelineID);
-    }
-}
-
-}; // namespace android
diff --git a/libs/common_time/common_clock_service.h b/libs/common_time/common_clock_service.h
deleted file mode 100644
index aea507e..0000000
--- a/libs/common_time/common_clock_service.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef ANDROID_COMMON_CLOCK_SERVICE_H
-#define ANDROID_COMMON_CLOCK_SERVICE_H
-
-#include <sys/socket.h>
-#include <common_time/ICommonClock.h>
-
-namespace android {
-
-class CommonTimeServer;
-
-class CommonClockService : public BnCommonClock,
-                           public android::IBinder::DeathRecipient {
-  public:
-    static sp<CommonClockService> instantiate(CommonTimeServer& timeServer);
-
-    virtual status_t dump(int fd, const Vector<String16>& args);
-
-    virtual status_t isCommonTimeValid(bool* valid, uint32_t *timelineID);
-    virtual status_t commonTimeToLocalTime(int64_t  common_time,
-                                           int64_t* local_time);
-    virtual status_t localTimeToCommonTime(int64_t  local_time,
-                                           int64_t* common_time);
-    virtual status_t getCommonTime(int64_t* common_time);
-    virtual status_t getCommonFreq(uint64_t* freq);
-    virtual status_t getLocalTime(int64_t* local_time);
-    virtual status_t getLocalFreq(uint64_t* freq);
-    virtual status_t getEstimatedError(int32_t* estimate);
-    virtual status_t getTimelineID(uint64_t* id);
-    virtual status_t getState(ICommonClock::State* state);
-    virtual status_t getMasterAddr(struct sockaddr_storage* addr);
-
-    virtual status_t registerListener(
-            const sp<ICommonClockListener>& listener);
-    virtual status_t unregisterListener(
-            const sp<ICommonClockListener>& listener);
-
-    void notifyOnTimelineChanged(uint64_t timelineID);
-
-  private:
-    explicit CommonClockService(CommonTimeServer& timeServer)
-        : mTimeServer(timeServer) { };
-
-    virtual void binderDied(const wp<IBinder>& who);
-
-    CommonTimeServer& mTimeServer;
-
-    // locks used to synchronize access to the list of registered listeners.
-    // The callback lock is held whenever the list is used to perform callbacks
-    // or while the list is being modified.  The registration lock used to
-    // serialize access across registerListener, unregisterListener, and
-    // binderDied.
-    //
-    // The reason for two locks is that registerListener, unregisterListener,
-    // and binderDied each call into the core service and obtain the core
-    // service thread lock when they call reevaluateAutoDisableState.  The core
-    // service thread obtains the main thread lock whenever its thread is
-    // running, and sometimes needs to call notifyOnTimelineChanged which then
-    // obtains the callback lock.  If callers of registration functions were
-    // holding the callback lock when they called into the core service, we
-    // would have a classic A/B, B/A ordering deadlock.  To avoid this, the
-    // registration functions hold the registration lock for the duration of
-    // their call, but hold the callback lock only while they mutate the list.
-    // This way, the list's size cannot change (because of the registration
-    // lock) during the call into reevaluateAutoDisableState, but the core work
-    // thread can still safely call notifyOnTimelineChanged while holding the
-    // main thread lock.
-    Mutex mCallbackLock;
-    Mutex mRegistrationLock;
-
-    Vector<sp<ICommonClockListener> > mListeners;
-};
-
-};  // namespace android
-
-#endif  // ANDROID_COMMON_CLOCK_SERVICE_H
diff --git a/libs/common_time/common_time_config_service.cpp b/libs/common_time/common_time_config_service.cpp
deleted file mode 100644
index 9585618..0000000
--- a/libs/common_time/common_time_config_service.cpp
+++ /dev/null
@@ -1,112 +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.
- */
-
-#include <utils/String8.h>
-
-#include "common_time_config_service.h"
-#include "common_time_server.h"
-
-namespace android {
-
-sp<CommonTimeConfigService> CommonTimeConfigService::instantiate(
-        CommonTimeServer& timeServer) {
-    sp<CommonTimeConfigService> ctcs = new CommonTimeConfigService(timeServer);
-    if (ctcs == NULL)
-        return NULL;
-
-    defaultServiceManager()->addService(ICommonTimeConfig::kServiceName, ctcs);
-    return ctcs;
-}
-
-status_t CommonTimeConfigService::dump(int fd, const Vector<String16>& args) {
-    return mTimeServer.dumpConfigInterface(fd, args);
-}
-
-status_t CommonTimeConfigService::getMasterElectionPriority(uint8_t *priority) {
-    return mTimeServer.getMasterElectionPriority(priority);
-}
-
-status_t CommonTimeConfigService::setMasterElectionPriority(uint8_t priority) {
-    return mTimeServer.setMasterElectionPriority(priority);
-}
-
-status_t CommonTimeConfigService::getMasterElectionEndpoint(
-        struct sockaddr_storage *addr) {
-    return mTimeServer.getMasterElectionEndpoint(addr);
-}
-
-status_t CommonTimeConfigService::setMasterElectionEndpoint(
-        const struct sockaddr_storage *addr) {
-    return mTimeServer.setMasterElectionEndpoint(addr);
-}
-
-status_t CommonTimeConfigService::getMasterElectionGroupId(uint64_t *id) {
-    return mTimeServer.getMasterElectionGroupId(id);
-}
-
-status_t CommonTimeConfigService::setMasterElectionGroupId(uint64_t id) {
-    return mTimeServer.setMasterElectionGroupId(id);
-}
-
-status_t CommonTimeConfigService::getInterfaceBinding(String16& ifaceName) {
-    String8 tmp;
-    status_t ret = mTimeServer.getInterfaceBinding(tmp);
-    ifaceName = String16(tmp);
-    return ret;
-}
-
-status_t CommonTimeConfigService::setInterfaceBinding(const String16& ifaceName) {
-    String8 tmp(ifaceName);
-    return mTimeServer.setInterfaceBinding(tmp);
-}
-
-status_t CommonTimeConfigService::getMasterAnnounceInterval(int *interval) {
-    return mTimeServer.getMasterAnnounceInterval(interval);
-}
-
-status_t CommonTimeConfigService::setMasterAnnounceInterval(int interval) {
-    return mTimeServer.setMasterAnnounceInterval(interval);
-}
-
-status_t CommonTimeConfigService::getClientSyncInterval(int *interval) {
-    return mTimeServer.getClientSyncInterval(interval);
-}
-
-status_t CommonTimeConfigService::setClientSyncInterval(int interval) {
-    return mTimeServer.setClientSyncInterval(interval);
-}
-
-status_t CommonTimeConfigService::getPanicThreshold(int *threshold) {
-    return mTimeServer.getPanicThreshold(threshold);
-}
-
-status_t CommonTimeConfigService::setPanicThreshold(int threshold) {
-    return mTimeServer.setPanicThreshold(threshold);
-}
-
-status_t CommonTimeConfigService::getAutoDisable(bool *autoDisable) {
-    return mTimeServer.getAutoDisable(autoDisable);
-}
-
-status_t CommonTimeConfigService::setAutoDisable(bool autoDisable) {
-    return mTimeServer.setAutoDisable(autoDisable);
-}
-
-status_t CommonTimeConfigService::forceNetworklessMasterMode() {
-    return mTimeServer.forceNetworklessMasterMode();
-}
-
-}; // namespace android
diff --git a/libs/common_time/common_time_config_service.h b/libs/common_time/common_time_config_service.h
deleted file mode 100644
index 23abb1a..0000000
--- a/libs/common_time/common_time_config_service.h
+++ /dev/null
@@ -1,60 +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.
- */
-
-#ifndef ANDROID_COMMON_TIME_CONFIG_SERVICE_H
-#define ANDROID_COMMON_TIME_CONFIG_SERVICE_H
-
-#include <sys/socket.h>
-#include <common_time/ICommonTimeConfig.h>
-
-namespace android {
-
-class String16;
-class CommonTimeServer;
-
-class CommonTimeConfigService : public BnCommonTimeConfig {
-  public:
-    static sp<CommonTimeConfigService> instantiate(CommonTimeServer& timeServer);
-
-    virtual status_t dump(int fd, const Vector<String16>& args);
-
-    virtual status_t getMasterElectionPriority(uint8_t *priority);
-    virtual status_t setMasterElectionPriority(uint8_t priority);
-    virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr);
-    virtual status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr);
-    virtual status_t getMasterElectionGroupId(uint64_t *id);
-    virtual status_t setMasterElectionGroupId(uint64_t id);
-    virtual status_t getInterfaceBinding(String16& ifaceName);
-    virtual status_t setInterfaceBinding(const String16& ifaceName);
-    virtual status_t getMasterAnnounceInterval(int *interval);
-    virtual status_t setMasterAnnounceInterval(int interval);
-    virtual status_t getClientSyncInterval(int *interval);
-    virtual status_t setClientSyncInterval(int interval);
-    virtual status_t getPanicThreshold(int *threshold);
-    virtual status_t setPanicThreshold(int threshold);
-    virtual status_t getAutoDisable(bool *autoDisable);
-    virtual status_t setAutoDisable(bool autoDisable);
-    virtual status_t forceNetworklessMasterMode();
-
-  private:
-    explicit CommonTimeConfigService(CommonTimeServer& timeServer)
-        : mTimeServer(timeServer) { }
-    CommonTimeServer& mTimeServer;
-
-};
-
-};  // namespace android
-
-#endif  // ANDROID_COMMON_TIME_CONFIG_SERVICE_H
diff --git a/libs/common_time/common_time_server.cpp b/libs/common_time/common_time_server.cpp
deleted file mode 100644
index b1495ef..0000000
--- a/libs/common_time/common_time_server.cpp
+++ /dev/null
@@ -1,1507 +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.
- */
-
-/*
- * A service that exchanges time synchronization information between
- * a master that defines a timeline and clients that follow the timeline.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <arpa/inet.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <linux/if_ether.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <netinet/ip.h>
-#include <poll.h>
-#include <stdio.h>
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <common_time/local_clock.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <utils/Timers.h>
-
-#include "common_clock_service.h"
-#include "common_time_config_service.h"
-#include "common_time_server.h"
-#include "common_time_server_packets.h"
-#include "clock_recovery.h"
-#include "common_clock.h"
-
-#define MAX_INT ((int)0x7FFFFFFF)
-
-namespace android {
-
-const char*    CommonTimeServer::kDefaultMasterElectionAddr = "255.255.255.255";
-const uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8886;
-const uint64_t CommonTimeServer::kDefaultSyncGroupID = 1;
-const uint8_t  CommonTimeServer::kDefaultMasterPriority = 1;
-const uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
-const uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
-const uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
-const bool     CommonTimeServer::kDefaultAutoDisable = true;
-const int      CommonTimeServer::kSetupRetryTimeoutMs = 30000;
-const int64_t  CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
-const uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
-
-// timeout value representing an infinite timeout
-const int CommonTimeServer::kInfiniteTimeout = -1;
-
-/*** Initial state constants ***/
-
-// number of WhoIsMaster attempts sent before giving up
-const int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
-
-// timeout used when waiting for a response to a WhoIsMaster request
-const int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
-
-/*** Client state constants ***/
-
-// number of sync requests that can fail before a client assumes its master
-// is dead
-const int CommonTimeServer::kClient_NumSyncRequestRetries = 10;
-
-/*** Master state constants ***/
-
-/*** Ronin state constants ***/
-
-// number of WhoIsMaster attempts sent before declaring ourselves master
-const int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;
-
-// timeout used when waiting for a response to a WhoIsMaster request
-const int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
-
-/*** WaitForElection state constants ***/
-
-// how long do we wait for an announcement from a master before
-// trying another election?
-const int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;
-
-CommonTimeServer::CommonTimeServer()
-    : Thread(false)
-    , mState(ICommonClock::STATE_INITIAL)
-    , mClockRecovery(&mLocalClock, &mCommonClock)
-    , mSocket(-1)
-    , mLastPacketRxLocalTime(0)
-    , mTimelineID(ICommonClock::kInvalidTimelineID)
-    , mClockSynced(false)
-    , mCommonClockHasClients(false)
-    , mStateChangeLog("Recent State Change Events", 30)
-    , mElectionLog("Recent Master Election Traffic", 30)
-    , mBadPktLog("Recent Bad Packet RX Info", 8)
-    , mInitial_WhoIsMasterRequestTimeouts(0)
-    , mClient_MasterDeviceID(0)
-    , mClient_MasterDevicePriority(0)
-    , mRonin_WhoIsMasterRequestTimeouts(0) {
-    // zero out sync stats
-    resetSyncStats();
-
-    // Setup the master election endpoint to use the default.
-    struct sockaddr_in* meep =
-        reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
-    memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
-    inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
-    meep->sin_family = AF_INET;
-    meep->sin_port   = htons(kDefaultMasterElectionPort);
-
-    // Zero out the master endpoint.
-    memset(&mMasterEP, 0, sizeof(mMasterEP));
-    mMasterEPValid    = false;
-    mBindIfaceValid   = false;
-    setForceLowPriority(false);
-
-    // Set all remaining configuration parameters to their defaults.
-    mDeviceID                 = 0;
-    mSyncGroupID              = kDefaultSyncGroupID;
-    mMasterPriority           = kDefaultMasterPriority;
-    mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
-    mSyncRequestIntervalMs    = kDefaultSyncRequestIntervalMs;
-    mPanicThresholdUsec       = kDefaultPanicThresholdUsec;
-    mAutoDisable              = kDefaultAutoDisable;
-
-    // Create the eventfd we will use to signal our thread to wake up when
-    // needed.
-    mWakeupThreadFD = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-
-    // seed the random number generator (used to generated timeline IDs)
-    srand48(static_cast<unsigned int>(systemTime()));
-}
-
-CommonTimeServer::~CommonTimeServer() {
-    shutdownThread();
-
-    // No need to grab the lock here.  We are in the destructor; if the the user
-    // has a thread in any of the APIs while the destructor is being called,
-    // there is a threading problem a the application level we cannot reasonably
-    // do anything about.
-    cleanupSocket_l();
-
-    if (mWakeupThreadFD >= 0) {
-        close(mWakeupThreadFD);
-        mWakeupThreadFD = -1;
-    }
-}
-
-bool CommonTimeServer::startServices() {
-    // start the ICommonClock service
-    mICommonClock = CommonClockService::instantiate(*this);
-    if (mICommonClock == NULL)
-        return false;
-
-    // start the ICommonTimeConfig service
-    mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
-    if (mICommonTimeConfig == NULL)
-        return false;
-
-    return true;
-}
-
-bool CommonTimeServer::threadLoop() {
-    // Register our service interfaces.
-    if (!startServices())
-        return false;
-
-    // Hold the lock while we are in the main thread loop.  It will release the
-    // lock when it blocks, and hold the lock at all other times.
-    mLock.lock();
-    runStateMachine_l();
-    mLock.unlock();
-
-    IPCThreadState::self()->stopProcess();
-    return false;
-}
-
-bool CommonTimeServer::runStateMachine_l() {
-    if (!mLocalClock.initCheck())
-        return false;
-
-    if (!mCommonClock.init(mLocalClock.getLocalFreq()))
-        return false;
-
-    // Enter the initial state.
-    becomeInitial("startup");
-
-    // run the state machine
-    while (!exitPending()) {
-        struct pollfd pfds[2];
-        int rc, timeout;
-        int eventCnt = 0;
-        int64_t wakeupTime;
-        uint32_t t1, t2;
-        bool needHandleTimeout = false;
-
-        // We are always interested in our wakeup FD.
-        pfds[eventCnt].fd      = mWakeupThreadFD;
-        pfds[eventCnt].events  = POLLIN;
-        pfds[eventCnt].revents = 0;
-        eventCnt++;
-
-        // If we have a valid socket, then we are interested in what it has to
-        // say as well.
-        if (mSocket >= 0) {
-            pfds[eventCnt].fd      = mSocket;
-            pfds[eventCnt].events  = POLLIN;
-            pfds[eventCnt].revents = 0;
-            eventCnt++;
-        }
-
-        t1 = static_cast<uint32_t>(mCurTimeout.msecTillTimeout());
-        t2 = static_cast<uint32_t>(mClockRecovery.applyRateLimitedSlew());
-        timeout = static_cast<int>(t1 < t2 ? t1 : t2);
-
-        // Note, we were holding mLock when this function was called.  We
-        // release it only while we are blocking and hold it at all other times.
-        mLock.unlock();
-        rc          = poll(pfds, eventCnt, timeout);
-        wakeupTime  = mLocalClock.getLocalTime();
-        mLock.lock();
-
-        // Is it time to shutdown?  If so, don't hesitate... just do it.
-        if (exitPending())
-            break;
-
-        // Did the poll fail?  This should never happen and is fatal if it does.
-        if (rc < 0) {
-            ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
-            return false;
-        }
-
-        if (rc == 0) {
-            needHandleTimeout = !mCurTimeout.msecTillTimeout();
-            if (needHandleTimeout)
-                mCurTimeout.setTimeout(kInfiniteTimeout);
-        }
-
-        // Were we woken up on purpose?  If so, clear the eventfd with a read.
-        if (pfds[0].revents)
-            clearPendingWakeupEvents_l();
-
-        // Is out bind address dirty?  If so, clean up our socket (if any).
-        // Alternatively, do we have an active socket but should be auto
-        // disabled?  If so, release the socket and enter the proper sync state.
-        bool droppedSocket = false;
-        if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
-            cleanupSocket_l();
-            mBindIfaceDirty = false;
-            droppedSocket = true;
-        }
-
-        // Do we not have a socket but should have one?  If so, try to set one
-        // up.
-        if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
-            if (setupSocket_l()) {
-                // Success!  We are now joining a new network (either coming
-                // from no network, or coming from a potentially different
-                // network).  Force our priority to be lower so that we defer to
-                // any other masters which may already be on the network we are
-                // joining.  Later, when we enter either the client or the
-                // master state, we will clear this flag and go back to our
-                // normal election priority.
-                setForceLowPriority(true);
-                switch (mState) {
-                    // If we were in initial (whether we had a immediately
-                    // before this network or not) we want to simply reset the
-                    // system and start again.  Forcing a transition from
-                    // INITIAL to INITIAL should do the job.
-                    case CommonClockService::STATE_INITIAL:
-                        becomeInitial("bound interface");
-                        break;
-
-                    // If we were in the master state, then either we were the
-                    // master in a no-network situation, or we were the master
-                    // of a different network and have moved to a new interface.
-                    // In either case, immediately transition to Ronin at low
-                    // priority.  If there is no one in the network we just
-                    // joined, we will become master soon enough.  If there is,
-                    // we want to be certain to defer master status to the
-                    // existing timeline currently running on the network.
-                    //
-                    case CommonClockService::STATE_MASTER:
-                        becomeRonin("leaving networkless mode");
-                        break;
-
-                    // If we were in any other state (CLIENT, RONIN, or
-                    // WAIT_FOR_ELECTION) then we must be moving from one
-                    // network to another.  We have lost our old master;
-                    // transition to RONIN in an attempt to find a new master.
-                    // If there are none out there, we will just assume
-                    // responsibility for the timeline we used to be a client
-                    // of.
-                    default:
-                        becomeRonin("bound interface");
-                        break;
-                }
-            } else {
-                // That's odd... we failed to set up our socket.  This could be
-                // due to some transient network change which will work itself
-                // out shortly; schedule a retry attempt in the near future.
-                mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
-            }
-
-            // One way or the other, we don't have any data to process at this
-            // point (since we just tried to bulid a new socket).  Loop back
-            // around and wait for the next thing to do.
-            continue;
-        } else if (droppedSocket) {
-            // We just lost our socket, and for whatever reason (either no
-            // config, or auto disable engaged) we are not supposed to rebuild
-            // one at this time.  We are not going to rebuild our socket until
-            // something about our config/auto-disabled status changes, so we
-            // are basically in network-less mode.  If we are already in either
-            // INITIAL or MASTER, just stay there until something changes.  If
-            // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
-            // then transition to either INITIAL or MASTER depending on whether
-            // or not our timeline is valid.
-            mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-                    "Entering networkless mode interface is %s, "
-                    "shouldAutoDisable = %s",
-                    mBindIfaceValid ? "valid" : "invalid",
-                    shouldAutoDisable() ? "true" : "false");
-            if ((mState != ICommonClock::STATE_INITIAL) &&
-                (mState != ICommonClock::STATE_MASTER)) {
-                if (mTimelineID == ICommonClock::kInvalidTimelineID)
-                    becomeInitial("network-less mode");
-                else
-                    becomeMaster("network-less mode");
-            }
-
-            continue;
-        }
-
-        // Time to handle the timeouts?
-        if (needHandleTimeout) {
-            if (!handleTimeout())
-                ALOGE("handleTimeout failed");
-            continue;
-        }
-
-        // Does our socket have data for us (assuming we still have one, we
-        // may have RXed a packet at the same time as a config change telling us
-        // to shut our socket down)?  If so, process its data.
-        if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
-            mLastPacketRxLocalTime = wakeupTime;
-            if (!handlePacket())
-                ALOGE("handlePacket failed");
-        }
-    }
-
-    cleanupSocket_l();
-    return true;
-}
-
-void CommonTimeServer::clearPendingWakeupEvents_l() {
-    int64_t tmp;
-    read(mWakeupThreadFD, &tmp, sizeof(tmp));
-}
-
-void CommonTimeServer::wakeupThread_l() {
-    int64_t tmp = 1;
-    write(mWakeupThreadFD, &tmp, sizeof(tmp));
-}
-
-void CommonTimeServer::cleanupSocket_l() {
-    if (mSocket >= 0) {
-        close(mSocket);
-        mSocket = -1;
-    }
-}
-
-void CommonTimeServer::shutdownThread() {
-    // Flag the work thread for shutdown.
-    this->requestExit();
-
-    // Signal the thread in case its sleeping.
-    mLock.lock();
-    wakeupThread_l();
-    mLock.unlock();
-
-    // Wait for the thread to exit.
-    this->join();
-}
-
-bool CommonTimeServer::setupSocket_l() {
-    int rc;
-    bool ret_val = false;
-    struct sockaddr_in* ipv4_addr = NULL;
-    char masterElectionEPStr[64];
-    const int one = 1;
-
-    // This should never be needed, but if we happened to have an old socket
-    // lying around, be sure to not leak it before proceeding.
-    cleanupSocket_l();
-
-    // If we don't have a valid endpoint to bind to, then how did we get here in
-    // the first place?  Regardless, we know that we are going to fail to bind,
-    // so don't even try.
-    if (!mBindIfaceValid)
-        return false;
-
-    sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
-                     sizeof(masterElectionEPStr));
-    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-                        "Building socket :: bind = %s master election = %s",
-                        mBindIface.string(), masterElectionEPStr);
-
-    // TODO: add proper support for IPv6.  Right now, we block IPv6 addresses at
-    // the configuration interface level.
-    if (AF_INET != mMasterElectionEP.ss_family) {
-        mStateChangeLog.log(ANDROID_LOG_WARN, LOG_TAG,
-                            "TODO: add proper IPv6 support");
-        goto bailout;
-    }
-
-    // open a UDP socket for the timeline serivce
-    mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-    if (mSocket < 0) {
-        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
-                            "Failed to create socket (errno = %d)", errno);
-        goto bailout;
-    }
-
-    // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
-    struct ifreq ifr;
-    memset(&ifr, 0, sizeof(ifr));
-    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
-    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
-    rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
-                    (void *)&ifr, sizeof(ifr));
-    if (rc) {
-        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
-                            "Failed to bind socket at to interface %s "
-                            "(errno = %d)", ifr.ifr_name, errno);
-        goto bailout;
-    }
-
-    // Bind our socket to INADDR_ANY and the master election port.  The
-    // interface binding we made using SO_BINDTODEVICE should limit us to
-    // traffic only on the interface we are interested in.  We need to bind to
-    // INADDR_ANY and the specific master election port in order to be able to
-    // receive both unicast traffic and master election multicast traffic with
-    // just a single socket.
-    struct sockaddr_in bindAddr;
-    ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
-    memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
-    bindAddr.sin_addr.s_addr = INADDR_ANY;
-    rc = bind(mSocket,
-              reinterpret_cast<const sockaddr *>(&bindAddr),
-              sizeof(bindAddr));
-    if (rc) {
-        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
-                            "Failed to bind socket to port %hu (errno = %d)",
-                            ntohs(bindAddr.sin_port), errno);
-        goto bailout;
-    }
-
-    if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
-        // If our master election endpoint is a multicast address, be sure to join
-        // the multicast group.
-        struct ip_mreq mreq;
-        mreq.imr_multiaddr = ipv4_addr->sin_addr;
-        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
-        rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                        &mreq, sizeof(mreq));
-        if (rc == -1) {
-            ALOGE("Failed to join multicast group at %s.  (errno = %d)",
-                 masterElectionEPStr, errno);
-            goto bailout;
-        }
-
-        // disable loopback of multicast packets
-        const int zero = 0;
-        rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
-                        &zero, sizeof(zero));
-        if (rc == -1) {
-            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
-                                "Failed to disable multicast loopback "
-                                "(errno = %d)", errno);
-            goto bailout;
-        }
-    } else
-    if (ntohl(ipv4_addr->sin_addr.s_addr) == 0xFFFFFFFF) {
-        // If the master election address is the broadcast address, then enable
-        // the broadcast socket option
-        rc = setsockopt(mSocket, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
-        if (rc == -1) {
-            mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
-                                "Failed to enable broadcast (errno = %d)",
-                                errno);
-            goto bailout;
-        }
-    } else {
-        // If the master election address is neither broadcast, nor multicast,
-        // then we are misconfigured.  The config API layer should prevent this
-        // from ever happening.
-        goto bailout;
-    }
-
-    // Set the TTL of sent packets to 1.  (Time protocol sync should never leave
-    // the local subnet)
-    rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
-    if (rc == -1) {
-        mStateChangeLog.log(ANDROID_LOG_ERROR, LOG_TAG,
-                            "Failed to set TTL to %d (errno = %d)", one, errno);
-        goto bailout;
-    }
-
-    // get the device's unique ID
-    if (!assignDeviceID())
-        goto bailout;
-
-    ret_val = true;
-
-bailout:
-    if (!ret_val)
-        cleanupSocket_l();
-    return ret_val;
-}
-
-// generate a unique device ID that can be used for arbitration
-bool CommonTimeServer::assignDeviceID() {
-    if (!mBindIfaceValid)
-        return false;
-
-    struct ifreq ifr;
-    memset(&ifr, 0, sizeof(ifr));
-    ifr.ifr_addr.sa_family = AF_INET;
-    strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
-
-    int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
-    if (rc) {
-        ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
-        return false;
-    }
-
-    if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
-        ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
-        return false;
-    }
-
-    mDeviceID = 0;
-    for (int i = 0; i < ETH_ALEN; i++) {
-        mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
-    }
-
-    return true;
-}
-
-// generate a new timeline ID
-void CommonTimeServer::assignTimelineID() {
-    do {
-        mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
-                    |  static_cast<uint64_t>(lrand48());
-    } while (mTimelineID == ICommonClock::kInvalidTimelineID);
-}
-
-// Select a preference between the device IDs of two potential masters.
-// Returns true if the first ID wins, or false if the second ID wins.
-bool CommonTimeServer::arbitrateMaster(
-        uint64_t deviceID1, uint8_t devicePrio1,
-        uint64_t deviceID2, uint8_t devicePrio2) {
-    return ((devicePrio1 >  devicePrio2) ||
-           ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
-}
-
-static void hexDumpToString(const uint8_t* src, size_t src_len,
-                            char* dst, size_t dst_len) {
-    size_t offset = 0;
-    size_t i;
-
-    for (i = 0; (i < src_len) && (offset < dst_len); ++i) {
-        int res;
-        if (0 == (i % 16)) {
-            res = snprintf(dst + offset, dst_len - offset, "\n%04zx :", i);
-            if (res < 0)
-                break;
-            offset += res;
-            if (offset >= dst_len)
-                break;
-        }
-
-        res = snprintf(dst + offset, dst_len - offset, " %02x", src[i]);
-        if (res < 0)
-            break;
-        offset += res;
-    }
-
-    dst[dst_len - 1] = 0;
-}
-
-bool CommonTimeServer::handlePacket() {
-    uint8_t buf[256];
-    struct sockaddr_storage srcAddr;
-    socklen_t srcAddrLen = sizeof(srcAddr);
-
-    ssize_t recvBytes = recvfrom(
-            mSocket, buf, sizeof(buf), 0,
-            reinterpret_cast<sockaddr *>(&srcAddr), &srcAddrLen);
-
-    if (recvBytes < 0) {
-        mBadPktLog.log(ANDROID_LOG_ERROR, LOG_TAG, "recvfrom failed (%s)",
-                       strerror(errno));
-        return false;
-    }
-
-    UniversalTimeServicePacket pkt;
-    if (pkt.deserializePacket(buf, recvBytes, mSyncGroupID) < 0) {
-        char hex[256];
-        char srcEPStr[64];
-
-        hexDumpToString(buf, static_cast<size_t>(recvBytes), hex, sizeof(hex));
-        sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
-
-        mBadPktLog.log("Failed to parse %d byte packet from %s.%s",
-                       recvBytes, srcEPStr, hex);
-        return false;
-    }
-
-    bool result;
-    switch (pkt.packetType) {
-        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
-            result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
-                                              srcAddr);
-            break;
-
-        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
-            result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
-                                               srcAddr);
-            break;
-
-        case TIME_PACKET_SYNC_REQUEST:
-            result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
-            break;
-
-        case TIME_PACKET_SYNC_RESPONSE:
-            result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
-            break;
-
-        case TIME_PACKET_MASTER_ANNOUNCEMENT:
-            result = handleMasterAnnouncement(&pkt.p.master_announcement,
-                                              srcAddr);
-            break;
-
-        default: {
-            char srcEPStr[64];
-            sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
-
-            mBadPktLog.log(ANDROID_LOG_WARN, LOG_TAG,
-                           "unknown packet type (%d) from %s",
-                           pkt.packetType, srcEPStr);
-
-            result = false;
-        } break;
-    }
-
-    return result;
-}
-
-bool CommonTimeServer::handleTimeout() {
-    // If we have no socket, then this must be a timeout to retry socket setup.
-    if (mSocket < 0)
-        return true;
-
-    switch (mState) {
-        case ICommonClock::STATE_INITIAL:
-            return handleTimeoutInitial();
-        case ICommonClock::STATE_CLIENT:
-            return handleTimeoutClient();
-        case ICommonClock::STATE_MASTER:
-            return handleTimeoutMaster();
-        case ICommonClock::STATE_RONIN:
-            return handleTimeoutRonin();
-        case ICommonClock::STATE_WAIT_FOR_ELECTION:
-            return handleTimeoutWaitForElection();
-    }
-
-    return false;
-}
-
-bool CommonTimeServer::handleTimeoutInitial() {
-    if (++mInitial_WhoIsMasterRequestTimeouts ==
-            kInitial_NumWhoIsMasterRetries) {
-        // none of our attempts to discover a master succeeded, so make
-        // this device the master
-        return becomeMaster("initial timeout");
-    } else {
-        // retry the WhoIsMaster request
-        return sendWhoIsMasterRequest();
-    }
-}
-
-bool CommonTimeServer::handleTimeoutClient() {
-    if (shouldPanicNotGettingGoodData())
-        return becomeInitial("timeout panic, no good data");
-
-    if (mClient_SyncRequestPending) {
-        mClient_SyncRequestPending = false;
-
-        if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
-            // a sync request has timed out, so retry
-            return sendSyncRequest();
-        } else {
-            // The master has failed to respond to a sync request for too many
-            // times in a row.  Assume the master is dead and start electing
-            // a new master.
-            return becomeRonin("master not responding");
-        }
-    } else {
-        // initiate the next sync request
-        return sendSyncRequest();
-    }
-}
-
-bool CommonTimeServer::handleTimeoutMaster() {
-    // send another announcement from the master
-    return sendMasterAnnouncement();
-}
-
-bool CommonTimeServer::handleTimeoutRonin() {
-    if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
-        // no other master is out there, so we won the election
-        return becomeMaster("no better masters detected");
-    } else {
-        return sendWhoIsMasterRequest();
-    }
-}
-
-bool CommonTimeServer::handleTimeoutWaitForElection() {
-    return becomeRonin("timeout waiting for election conclusion");
-}
-
-bool CommonTimeServer::handleWhoIsMasterRequest(
-        const WhoIsMasterRequestPacket* request,
-        const sockaddr_storage& srcAddr) {
-    // Skip our own messages which come back via broadcast loopback.
-    if (request->senderDeviceID == mDeviceID)
-        return true;
-
-    char srcEPStr[64];
-    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
-    mElectionLog.log("RXed WhoIs master request while in state %s.  "
-                     "src %s reqTID %016llx ourTID %016llx",
-                     stateToString(mState), srcEPStr,
-                     request->timelineID, mTimelineID);
-
-    if (mState == ICommonClock::STATE_MASTER) {
-        // is this request related to this master's timeline?
-        if (request->timelineID != ICommonClock::kInvalidTimelineID &&
-            request->timelineID != mTimelineID)
-            return true;
-
-        WhoIsMasterResponsePacket pkt;
-        pkt.initHeader(mTimelineID, mSyncGroupID);
-        pkt.deviceID = mDeviceID;
-        pkt.devicePriority = effectivePriority();
-
-        mElectionLog.log("TXing WhoIs master resp to %s while in state %s.  "
-                         "ourTID %016llx ourGID %016llx ourDID %016llx "
-                         "ourPrio %u",
-                         srcEPStr, stateToString(mState),
-                         mTimelineID, mSyncGroupID,
-                         pkt.deviceID, pkt.devicePriority);
-
-        uint8_t buf[256];
-        ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
-        if (bufSz < 0)
-            return false;
-
-        ssize_t sendBytes = sendto(
-                mSocket, buf, bufSz, 0,
-                reinterpret_cast<const sockaddr *>(&srcAddr),
-                sizeof(srcAddr));
-        if (sendBytes == -1) {
-            ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
-            return false;
-        }
-    } else if (mState == ICommonClock::STATE_RONIN) {
-        // if we hear a WhoIsMaster request from another device following
-        // the same timeline and that device wins arbitration, then we will stop
-        // trying to elect ourselves master and will instead wait for an
-        // announcement from the election winner
-        if (request->timelineID != mTimelineID)
-            return true;
-
-        if (arbitrateMaster(request->senderDeviceID,
-                            request->senderDevicePriority,
-                            mDeviceID,
-                            effectivePriority()))
-            return becomeWaitForElection("would lose election");
-
-        return true;
-    } else if (mState == ICommonClock::STATE_INITIAL) {
-        // If a group of devices booted simultaneously (e.g. after a power
-        // outage) and all of them are in the initial state and there is no
-        // master, then each device may time out and declare itself master at
-        // the same time.  To avoid this, listen for
-        // WhoIsMaster(InvalidTimeline) requests from peers.  If we would lose
-        // arbitration against that peer, reset our timeout count so that the
-        // peer has a chance to become master before we time out.
-        if (request->timelineID == ICommonClock::kInvalidTimelineID &&
-                arbitrateMaster(request->senderDeviceID,
-                                request->senderDevicePriority,
-                                mDeviceID,
-                                effectivePriority())) {
-            mInitial_WhoIsMasterRequestTimeouts = 0;
-        }
-    }
-
-    return true;
-}
-
-bool CommonTimeServer::handleWhoIsMasterResponse(
-        const WhoIsMasterResponsePacket* response,
-        const sockaddr_storage& srcAddr) {
-    // Skip our own messages which come back via broadcast loopback.
-    if (response->deviceID == mDeviceID)
-        return true;
-
-    char srcEPStr[64];
-    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
-    mElectionLog.log("RXed WhoIs master response while in state %s.  "
-                     "src %s respTID %016llx respDID %016llx respPrio %u "
-                     "ourTID %016llx",
-                     stateToString(mState), srcEPStr,
-                     response->timelineID,
-                     response->deviceID,
-                     static_cast<uint32_t>(response->devicePriority),
-                     mTimelineID);
-
-    if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
-        return becomeClient(srcAddr,
-                            response->deviceID,
-                            response->devicePriority,
-                            response->timelineID,
-                            "heard whois response");
-    } else if (mState == ICommonClock::STATE_CLIENT) {
-        // if we get multiple responses because there are multiple devices
-        // who believe that they are master, then follow the master that
-        // wins arbitration
-        if (arbitrateMaster(response->deviceID,
-                            response->devicePriority,
-                            mClient_MasterDeviceID,
-                            mClient_MasterDevicePriority)) {
-            return becomeClient(srcAddr,
-                                response->deviceID,
-                                response->devicePriority,
-                                response->timelineID,
-                                "heard whois response");
-        }
-    }
-
-    return true;
-}
-
-bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
-                                         const sockaddr_storage& srcAddr) {
-    SyncResponsePacket pkt;
-    pkt.initHeader(mTimelineID, mSyncGroupID);
-
-    if ((mState == ICommonClock::STATE_MASTER) &&
-        (mTimelineID == request->timelineID)) {
-        int64_t rxLocalTime = mLastPacketRxLocalTime;
-        int64_t rxCommonTime;
-
-        // If we are master on an actual network and have actual clients, then
-        // we are no longer low priority.
-        setForceLowPriority(false);
-
-        if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
-            return false;
-        }
-
-        int64_t txLocalTime = mLocalClock.getLocalTime();;
-        int64_t txCommonTime;
-        if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
-            return false;
-        }
-
-        pkt.nak = 0;
-        pkt.clientTxLocalTime  = request->clientTxLocalTime;
-        pkt.masterRxCommonTime = rxCommonTime;
-        pkt.masterTxCommonTime = txCommonTime;
-    } else {
-        pkt.nak = 1;
-        pkt.clientTxLocalTime  = 0;
-        pkt.masterRxCommonTime = 0;
-        pkt.masterTxCommonTime = 0;
-    }
-
-    uint8_t buf[256];
-    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
-    if (bufSz < 0)
-        return false;
-
-    ssize_t sendBytes = sendto(
-            mSocket, &buf, bufSz, 0,
-            reinterpret_cast<const sockaddr *>(&srcAddr),
-            sizeof(srcAddr));
-    if (sendBytes == -1) {
-        ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
-        return false;
-    }
-
-    return true;
-}
-
-bool CommonTimeServer::handleSyncResponse(
-        const SyncResponsePacket* response,
-        const sockaddr_storage& srcAddr) {
-    if (mState != ICommonClock::STATE_CLIENT)
-        return true;
-
-    assert(mMasterEPValid);
-    if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
-        char srcEP[64], expectedEP[64];
-        sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
-        sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
-        ALOGI("Dropping sync response from unexpected address."
-             " Expected %s Got %s", expectedEP, srcEP);
-        return true;
-    }
-
-    if (response->nak) {
-        // if our master is no longer accepting requests, then we need to find
-        // a new master
-        return becomeRonin("master NAK'ed");
-    }
-
-    mClient_SyncRequestPending = 0;
-    mClient_SyncRequestTimeouts = 0;
-    mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
-                               mLastPacketRxLocalTime);
-
-    bool result;
-    if (!(mClient_SyncRespsRXedFromCurMaster++)) {
-        // the first request/response exchange between a client and a master
-        // may take unusually long due to ARP, so discard it.
-        result = true;
-    } else {
-        int64_t clientTxLocalTime  = response->clientTxLocalTime;
-        int64_t clientRxLocalTime  = mLastPacketRxLocalTime;
-        int64_t masterTxCommonTime = response->masterTxCommonTime;
-        int64_t masterRxCommonTime = response->masterRxCommonTime;
-
-        int64_t rtt       = (clientRxLocalTime - clientTxLocalTime);
-        int64_t avgLocal  = (clientTxLocalTime + clientRxLocalTime) >> 1;
-        int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
-
-        // if the RTT of the packet is significantly larger than the panic
-        // threshold, we should simply discard it.  Its better to do nothing
-        // than to take cues from a packet like that.
-        int64_t rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
-        if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) * 
-                         kRTTDiscardPanicThreshMultiplier)) {
-            ALOGV("Dropping sync response with RTT of %" PRId64 " uSec", rttCommon);
-            mClient_ExpiredSyncRespsRXedFromCurMaster++;
-            if (shouldPanicNotGettingGoodData())
-                return becomeInitial("RX panic, no good data");
-            return true;
-        } else {
-            result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
-            mClient_LastGoodSyncRX = clientRxLocalTime;
-
-            if (result) {
-                // indicate to listeners that we've synced to the common timeline
-                notifyClockSync();
-            } else {
-                ALOGE("Panic!  Observed clock sync error is too high to tolerate,"
-                        " resetting state machine and starting over.");
-                notifyClockSyncLoss();
-                return becomeInitial("panic");
-            }
-        }
-    }
-
-    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
-    return result;
-}
-
-bool CommonTimeServer::handleMasterAnnouncement(
-        const MasterAnnouncementPacket* packet,
-        const sockaddr_storage& srcAddr) {
-    uint64_t newDeviceID   = packet->deviceID;
-    uint8_t  newDevicePrio = packet->devicePriority;
-    uint64_t newTimelineID = packet->timelineID;
-
-    // Skip our own messages which come back via broadcast loopback.
-    if (newDeviceID == mDeviceID)
-        return true;
-
-    char srcEPStr[64];
-    sockaddrToString(srcAddr, true, srcEPStr, sizeof(srcEPStr));
-    mElectionLog.log("RXed master announcement while in state %s.  "
-                     "src %s srcDevID %lld srcPrio %u srcTID %016llx",
-                     stateToString(mState), srcEPStr,
-                     newDeviceID, static_cast<uint32_t>(newDevicePrio),
-                     newTimelineID);
-
-    if (mState == ICommonClock::STATE_INITIAL ||
-        mState == ICommonClock::STATE_RONIN ||
-        mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
-        // if we aren't currently following a master, then start following
-        // this new master
-        return becomeClient(srcAddr,
-                            newDeviceID,
-                            newDevicePrio,
-                            newTimelineID,
-                            "heard master announcement");
-    } else if (mState == ICommonClock::STATE_CLIENT) {
-        // if the new master wins arbitration against our current master,
-        // then become a client of the new master
-        if (arbitrateMaster(newDeviceID,
-                            newDevicePrio,
-                            mClient_MasterDeviceID,
-                            mClient_MasterDevicePriority))
-            return becomeClient(srcAddr,
-                                newDeviceID,
-                                newDevicePrio,
-                                newTimelineID,
-                                "heard master announcement");
-    } else if (mState == ICommonClock::STATE_MASTER) {
-        // two masters are competing - if the new one wins arbitration, then
-        // cease acting as master
-        if (arbitrateMaster(newDeviceID, newDevicePrio,
-                            mDeviceID, effectivePriority()))
-            return becomeClient(srcAddr, newDeviceID,
-                                newDevicePrio, newTimelineID,
-                                "heard master announcement");
-    }
-
-    return true;
-}
-
-bool CommonTimeServer::sendWhoIsMasterRequest() {
-    assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
-
-    // If we have no socket, then we must be in the unconfigured initial state.
-    // Don't report any errors, just don't try to send the initial who-is-master
-    // query.  Eventually, our network will either become configured, or we will
-    // be forced into network-less master mode by higher level code.
-    if (mSocket < 0) {
-        assert(mState == ICommonClock::STATE_INITIAL);
-        return true;
-    }
-
-    bool ret = false;
-    WhoIsMasterRequestPacket pkt;
-    pkt.initHeader(mSyncGroupID);
-    pkt.senderDeviceID = mDeviceID;
-    pkt.senderDevicePriority = effectivePriority();
-
-    uint8_t buf[256];
-    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
-    if (bufSz >= 0) {
-        char dstEPStr[64];
-        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
-        mElectionLog.log("TXing WhoIs master request to %s while in state %s.  "
-                         "ourTID %016llx ourGID %016llx ourDID %016llx "
-                         "ourPrio %u",
-                         dstEPStr, stateToString(mState),
-                         mTimelineID, mSyncGroupID,
-                         pkt.senderDeviceID, pkt.senderDevicePriority);
-
-        ssize_t sendBytes = sendto(
-                mSocket, buf, bufSz, 0,
-                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
-                sizeof(mMasterElectionEP));
-        if (sendBytes < 0)
-            ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
-        ret = true;
-    }
-
-    if (mState == ICommonClock::STATE_INITIAL) {
-        mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
-    } else {
-        mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
-    }
-
-    return ret;
-}
-
-bool CommonTimeServer::sendSyncRequest() {
-    // If we are sending sync requests, then we must be in the client state and
-    // we must have a socket (when we have no network, we are only supposed to
-    // be in INITIAL or MASTER)
-    assert(mState == ICommonClock::STATE_CLIENT);
-    assert(mSocket >= 0);
-
-    bool ret = false;
-    SyncRequestPacket pkt;
-    pkt.initHeader(mTimelineID, mSyncGroupID);
-    pkt.clientTxLocalTime = mLocalClock.getLocalTime();
-
-    if (!mClient_FirstSyncTX)
-        mClient_FirstSyncTX = pkt.clientTxLocalTime;
-
-    mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
-
-    uint8_t buf[256];
-    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
-    if (bufSz >= 0) {
-        ssize_t sendBytes = sendto(
-                mSocket, buf, bufSz, 0,
-                reinterpret_cast<const sockaddr *>(&mMasterEP),
-                sizeof(mMasterEP));
-        if (sendBytes < 0)
-            ALOGE("SyncRequest sendto failed (errno %d)", errno);
-        ret = true;
-    }
-
-    mClient_SyncsSentToCurMaster++;
-    mCurTimeout.setTimeout(mSyncRequestIntervalMs);
-    mClient_SyncRequestPending = true;
-
-    return ret;
-}
-
-bool CommonTimeServer::sendMasterAnnouncement() {
-    bool ret = false;
-    assert(mState == ICommonClock::STATE_MASTER);
-
-    // If we are being asked to send a master announcement, but we have no
-    // socket, we must be in network-less master mode.  Don't bother to send the
-    // announcement, and don't bother to schedule a timeout.  When the network
-    // comes up, the work thread will get poked and start the process of
-    // figuring out who the current master should be.
-    if (mSocket < 0) {
-        mCurTimeout.setTimeout(kInfiniteTimeout);
-        return true;
-    }
-
-    MasterAnnouncementPacket pkt;
-    pkt.initHeader(mTimelineID, mSyncGroupID);
-    pkt.deviceID = mDeviceID;
-    pkt.devicePriority = effectivePriority();
-
-    uint8_t buf[256];
-    ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
-    if (bufSz >= 0) {
-        char dstEPStr[64];
-        sockaddrToString(mMasterElectionEP, true, dstEPStr, sizeof(dstEPStr));
-        mElectionLog.log("TXing Master announcement to %s while in state %s.  "
-                         "ourTID %016llx ourGID %016llx ourDID %016llx "
-                         "ourPrio %u",
-                         dstEPStr, stateToString(mState),
-                         mTimelineID, mSyncGroupID,
-                         pkt.deviceID, pkt.devicePriority);
-
-        ssize_t sendBytes = sendto(
-                mSocket, buf, bufSz, 0,
-                reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
-                sizeof(mMasterElectionEP));
-        if (sendBytes < 0)
-            ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
-        ret = true;
-    }
-
-    mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
-    return ret;
-}
-
-bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
-                                    uint64_t masterDeviceID,
-                                    uint8_t  masterDevicePriority,
-                                    uint64_t timelineID,
-                                    const char* cause) {
-    char newEPStr[64], oldEPStr[64];
-    sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
-    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
-
-    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-            "%s --> CLIENT (%s) :%s"
-            " OldMaster: %02x-%014llx::%016llx::%s"
-            " NewMaster: %02x-%014llx::%016llx::%s",
-            stateToString(mState), cause,
-            (mTimelineID != timelineID) ? " (new timeline)" : "",
-            mClient_MasterDevicePriority, mClient_MasterDeviceID,
-            mTimelineID, oldEPStr,
-            masterDevicePriority, masterDeviceID,
-            timelineID, newEPStr);
-
-    if (mTimelineID != timelineID) {
-        // start following a new timeline
-        mTimelineID = timelineID;
-        mClockRecovery.reset(true, true);
-        notifyClockSyncLoss();
-    } else {
-        // start following a new master on the existing timeline
-        mClockRecovery.reset(false, true);
-    }
-
-    mMasterEP = masterEP;
-    mMasterEPValid = true;
-
-    // If we are on a real network as a client of a real master, then we should
-    // no longer force low priority.  If our master disappears, we should have
-    // the high priority bit set during the election to replace the master
-    // because this group was a real group and not a singleton created in
-    // networkless mode.
-    setForceLowPriority(false);
-
-    mClient_MasterDeviceID = masterDeviceID;
-    mClient_MasterDevicePriority = masterDevicePriority;
-    resetSyncStats();
-
-    setState(ICommonClock::STATE_CLIENT);
-
-    // add some jitter to when the various clients send their requests
-    // in order to reduce the likelihood that a group of clients overload
-    // the master after receiving a master announcement
-    usleep((lrand48() % 100) * 1000);
-
-    return sendSyncRequest();
-}
-
-bool CommonTimeServer::becomeMaster(const char* cause) {
-    uint64_t oldTimelineID = mTimelineID;
-    if (mTimelineID == ICommonClock::kInvalidTimelineID) {
-        // this device has not been following any existing timeline,
-        // so it will create a new timeline and declare itself master
-        assert(!mCommonClock.isValid());
-
-        // set the common time basis
-        mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
-
-        // assign an arbitrary timeline iD
-        assignTimelineID();
-
-        // notify listeners that we've created a common timeline
-        notifyClockSync();
-    }
-
-    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-            "%s --> MASTER (%s) : %s timeline %016llx",
-            stateToString(mState), cause,
-            (oldTimelineID == mTimelineID) ? "taking ownership of"
-                                           : "creating new",
-            mTimelineID);
-
-    memset(&mMasterEP, 0, sizeof(mMasterEP));
-    mMasterEPValid = false;
-    mClient_MasterDevicePriority = effectivePriority();
-    mClient_MasterDeviceID = mDeviceID;
-    mClockRecovery.reset(false, true);
-    resetSyncStats();
-
-    setState(ICommonClock::STATE_MASTER);
-    return sendMasterAnnouncement();
-}
-
-bool CommonTimeServer::becomeRonin(const char* cause) {
-    // If we were the client of a given timeline, but had never received even a
-    // single time sync packet, then we transition back to Initial instead of
-    // Ronin.  If we transition to Ronin and end up becoming the new Master, we
-    // will be unable to service requests for other clients because we never
-    // actually knew what time it was.  By going to initial, we ensure that
-    // other clients who know what time it is, but would lose master arbitration
-    // in the Ronin case, will step up and become the proper new master of the
-    // old timeline.
-
-    char oldEPStr[64];
-    sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
-    memset(&mMasterEP, 0, sizeof(mMasterEP));
-    mMasterEPValid = false;
-
-    if (mCommonClock.isValid()) {
-        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-             "%s --> RONIN (%s) : lost track of previously valid timeline "
-             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
-             stateToString(mState), cause,
-             mClient_MasterDevicePriority, mClient_MasterDeviceID,
-             mTimelineID, oldEPStr,
-             mClient_SyncsSentToCurMaster,
-             mClient_SyncRespsRXedFromCurMaster,
-             mClient_ExpiredSyncRespsRXedFromCurMaster);
-
-        mRonin_WhoIsMasterRequestTimeouts = 0;
-        setState(ICommonClock::STATE_RONIN);
-        return sendWhoIsMasterRequest();
-    } else {
-        mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-             "%s --> INITIAL (%s) : never synced timeline "
-             "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
-             stateToString(mState), cause,
-             mClient_MasterDevicePriority, mClient_MasterDeviceID,
-             mTimelineID, oldEPStr,
-             mClient_SyncsSentToCurMaster,
-             mClient_SyncRespsRXedFromCurMaster,
-             mClient_ExpiredSyncRespsRXedFromCurMaster);
-
-        return becomeInitial("ronin, no timeline");
-    }
-}
-
-bool CommonTimeServer::becomeWaitForElection(const char* cause) {
-    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-         "%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
-         " waiting %d mSec for completion.",
-         stateToString(mState), cause, kWaitForElection_TimeoutMs);
-
-    setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
-    mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
-    return true;
-}
-
-bool CommonTimeServer::becomeInitial(const char* cause) {
-    mStateChangeLog.log(ANDROID_LOG_INFO, LOG_TAG,
-                        "Entering INITIAL (%s), total reset.",
-                        cause);
-
-    setState(ICommonClock::STATE_INITIAL);
-
-    // reset clock recovery
-    mClockRecovery.reset(true, true);
-
-    // reset internal state bookkeeping.
-    mCurTimeout.setTimeout(kInfiniteTimeout);
-    memset(&mMasterEP, 0, sizeof(mMasterEP));
-    mMasterEPValid = false;
-    mLastPacketRxLocalTime = 0;
-    mTimelineID = ICommonClock::kInvalidTimelineID;
-    mClockSynced = false;
-    mInitial_WhoIsMasterRequestTimeouts = 0;
-    mClient_MasterDeviceID = 0;
-    mClient_MasterDevicePriority = 0;
-    mRonin_WhoIsMasterRequestTimeouts = 0;
-    resetSyncStats();
-
-    // send the first request to discover the master
-    return sendWhoIsMasterRequest();
-}
-
-void CommonTimeServer::notifyClockSync() {
-    if (!mClockSynced) {
-        mClockSynced = true;
-        mICommonClock->notifyOnTimelineChanged(mTimelineID);
-    }
-}
-
-void CommonTimeServer::notifyClockSyncLoss() {
-    if (mClockSynced) {
-        mClockSynced = false;
-        mICommonClock->notifyOnTimelineChanged(
-                ICommonClock::kInvalidTimelineID);
-    }
-}
-
-void CommonTimeServer::setState(ICommonClock::State s) {
-    mState = s;
-}
-
-const char* CommonTimeServer::stateToString(ICommonClock::State s) {
-    switch(s) {
-        case ICommonClock::STATE_INITIAL:
-            return "INITIAL";
-        case ICommonClock::STATE_CLIENT:
-            return "CLIENT";
-        case ICommonClock::STATE_MASTER:
-            return "MASTER";
-        case ICommonClock::STATE_RONIN:
-            return "RONIN";
-        case ICommonClock::STATE_WAIT_FOR_ELECTION:
-            return "WAIT_FOR_ELECTION";
-        default:
-            return "unknown";
-    }
-}
-
-void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
-                                        bool addrValid,
-                                        char* buf, size_t bufLen) {
-    if (!bufLen || !buf)
-        return;
-
-    if (addrValid) {
-        switch (addr.ss_family) {
-            case AF_INET: {
-                const struct sockaddr_in* sa =
-                    reinterpret_cast<const struct sockaddr_in*>(&addr);
-                unsigned long a = ntohl(sa->sin_addr.s_addr);
-                uint16_t      p = ntohs(sa->sin_port);
-                snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
-                        ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
-                        ((a >>  8) & 0xFF),  (a        & 0xFF), p);
-            } break;
-
-            case AF_INET6: {
-                const struct sockaddr_in6* sa =
-                    reinterpret_cast<const struct sockaddr_in6*>(&addr);
-                const uint8_t* a = sa->sin6_addr.s6_addr;
-                uint16_t       p = ntohs(sa->sin6_port);
-                snprintf(buf, bufLen,
-                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
-                        "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
-                        a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
-                        a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
-                        p);
-            } break;
-
-            default:
-                snprintf(buf, bufLen,
-                         "<unknown sockaddr family %d>", addr.ss_family);
-                break;
-        }
-    } else {
-        snprintf(buf, bufLen, "<none>");
-    }
-
-    buf[bufLen - 1] = 0;
-}
-
-bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
-                                     const sockaddr_storage& a2,
-                                     bool matchAddressOnly) {
-    if (a1.ss_family != a2.ss_family)
-        return false;
-
-    switch (a1.ss_family) {
-        case AF_INET: {
-            const struct sockaddr_in* sa1 =
-                reinterpret_cast<const struct sockaddr_in*>(&a1);
-            const struct sockaddr_in* sa2 =
-                reinterpret_cast<const struct sockaddr_in*>(&a2);
-
-            if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
-                return false;
-
-            return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
-        } break;
-
-        case AF_INET6: {
-            const struct sockaddr_in6* sa1 =
-                reinterpret_cast<const struct sockaddr_in6*>(&a1);
-            const struct sockaddr_in6* sa2 =
-                reinterpret_cast<const struct sockaddr_in6*>(&a2);
-
-            if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
-                return false;
-
-            return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
-        } break;
-
-        // Huh?  We don't deal in non-IPv[46] addresses.  Not sure how we got
-        // here, but we don't know how to comapre these addresses and simply
-        // default to a no-match decision.
-        default: return false;
-    }
-}
-
-bool CommonTimeServer::shouldPanicNotGettingGoodData() {
-    if (mClient_FirstSyncTX) {
-        int64_t now = mLocalClock.getLocalTime();
-        int64_t delta = now - (mClient_LastGoodSyncRX
-                             ? mClient_LastGoodSyncRX
-                             : mClient_FirstSyncTX);
-        int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
-
-        if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
-            return true;
-    }
-
-    return false;
-}
-
-void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
-    txTimes[wrPtr] = txTime;
-    rxTimes[wrPtr] = 0;
-    wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
-    if (!wrPtr)
-        logFull = true;
-}
-
-void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
-    if (!logFull && !wrPtr)
-        return;
-
-    uint32_t i = logFull ? wrPtr : 0;
-    do {
-        if (txTimes[i] == txTime) {
-            rxTimes[i] = rxTime;
-            break;
-        }
-        i = (i + 1) % RTT_LOG_SIZE;
-    } while (i != wrPtr);
-}
-
-}  // namespace android
diff --git a/libs/common_time/common_time_server.h b/libs/common_time/common_time_server.h
deleted file mode 100644
index 6e18050..0000000
--- a/libs/common_time/common_time_server.h
+++ /dev/null
@@ -1,324 +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.
- */
-
-#ifndef ANDROID_COMMON_TIME_SERVER_H
-#define ANDROID_COMMON_TIME_SERVER_H
-
-#include <arpa/inet.h>
-#include <stdint.h>
-#include <sys/socket.h>
-
-#include <common_time/ICommonClock.h>
-#include <common_time/local_clock.h>
-#include <utils/String8.h>
-
-#include "clock_recovery.h"
-#include "common_clock.h"
-#include "common_time_server_packets.h"
-#include "utils.h"
-
-#define RTT_LOG_SIZE 30
-
-namespace android {
-
-class CommonClockService;
-class CommonTimeConfigService;
-
-/***** time service implementation *****/
-
-class CommonTimeServer : public Thread {
-  public:
-    CommonTimeServer();
-    ~CommonTimeServer();
-
-    bool startServices();
-
-    // Common Clock API methods
-    CommonClock&        getCommonClock()        { return mCommonClock; }
-    LocalClock&         getLocalClock()         { return mLocalClock; }
-    uint64_t            getTimelineID();
-    int32_t             getEstimatedError();
-    ICommonClock::State getState();
-    status_t            getMasterAddr(struct sockaddr_storage* addr);
-    status_t            isCommonTimeValid(bool* valid, uint32_t* timelineID);
-
-    // Config API methods
-    status_t getMasterElectionPriority(uint8_t *priority);
-    status_t setMasterElectionPriority(uint8_t priority);
-    status_t getMasterElectionEndpoint(struct sockaddr_storage *addr);
-    status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr);
-    status_t getMasterElectionGroupId(uint64_t *id);
-    status_t setMasterElectionGroupId(uint64_t id);
-    status_t getInterfaceBinding(String8& ifaceName);
-    status_t setInterfaceBinding(const String8& ifaceName);
-    status_t getMasterAnnounceInterval(int *interval);
-    status_t setMasterAnnounceInterval(int interval);
-    status_t getClientSyncInterval(int *interval);
-    status_t setClientSyncInterval(int interval);
-    status_t getPanicThreshold(int *threshold);
-    status_t setPanicThreshold(int threshold);
-    status_t getAutoDisable(bool *autoDisable);
-    status_t setAutoDisable(bool autoDisable);
-    status_t forceNetworklessMasterMode();
-
-    // Method used by the CommonClockService to notify the core service about
-    // changes in the number of active common clock clients.
-    void reevaluateAutoDisableState(bool commonClockHasClients);
-
-    status_t dumpClockInterface(int fd, const Vector<String16>& args,
-                                size_t activeClients);
-    status_t dumpConfigInterface(int fd, const Vector<String16>& args);
-
-  private:
-    class PacketRTTLog {
-      public:
-        PacketRTTLog() {
-            resetLog();
-        }
-
-        void resetLog() {
-            wrPtr = 0;
-            logFull = 0;
-        }
-
-        void logTX(int64_t txTime);
-        void logRX(int64_t txTime, int64_t rxTime);
-        void dumpLog(int fd, const CommonClock& cclk);
-
-      private:
-        uint32_t wrPtr;
-        bool logFull;
-        int64_t txTimes[RTT_LOG_SIZE];
-        int64_t rxTimes[RTT_LOG_SIZE];
-    };
-
-    bool threadLoop();
-
-    bool runStateMachine_l();
-    bool setupSocket_l();
-
-    void assignTimelineID();
-    bool assignDeviceID();
-
-    static bool arbitrateMaster(uint64_t deviceID1, uint8_t devicePrio1,
-                                uint64_t deviceID2, uint8_t devicePrio2);
-
-    bool handlePacket();
-    bool handleWhoIsMasterRequest (const WhoIsMasterRequestPacket* request,
-                                   const sockaddr_storage& srcAddr);
-    bool handleWhoIsMasterResponse(const WhoIsMasterResponsePacket* response,
-                                   const sockaddr_storage& srcAddr);
-    bool handleSyncRequest        (const SyncRequestPacket* request,
-                                   const sockaddr_storage& srcAddr);
-    bool handleSyncResponse       (const SyncResponsePacket* response,
-                                   const sockaddr_storage& srcAddr);
-    bool handleMasterAnnouncement (const MasterAnnouncementPacket* packet,
-                                   const sockaddr_storage& srcAddr);
-
-    bool handleTimeout();
-    bool handleTimeoutInitial();
-    bool handleTimeoutClient();
-    bool handleTimeoutMaster();
-    bool handleTimeoutRonin();
-    bool handleTimeoutWaitForElection();
-
-    bool sendWhoIsMasterRequest();
-    bool sendSyncRequest();
-    bool sendMasterAnnouncement();
-
-    bool becomeClient(const sockaddr_storage& masterAddr,
-                      uint64_t masterDeviceID,
-                      uint8_t  masterDevicePriority,
-                      uint64_t timelineID,
-                      const char* cause);
-    bool becomeMaster(const char* cause);
-    bool becomeRonin(const char* cause);
-    bool becomeWaitForElection(const char* cause);
-    bool becomeInitial(const char* cause);
-
-    void notifyClockSync();
-    void notifyClockSyncLoss();
-
-    ICommonClock::State mState;
-    void setState(ICommonClock::State s);
-
-    void clearPendingWakeupEvents_l();
-    void wakeupThread_l();
-    void cleanupSocket_l();
-    void shutdownThread();
-
-    inline uint8_t effectivePriority() const {
-        return (mMasterPriority & 0x7F) |
-               (mForceLowPriority ? 0x00 : 0x80);
-    }
-
-    inline bool shouldAutoDisable() const {
-        return (mAutoDisable && !mCommonClockHasClients);
-    }
-
-    inline void resetSyncStats() {
-        mClient_SyncRequestPending = false;
-        mClient_SyncRequestTimeouts = 0;
-        mClient_SyncsSentToCurMaster = 0;
-        mClient_SyncRespsRXedFromCurMaster = 0;
-        mClient_ExpiredSyncRespsRXedFromCurMaster = 0;
-        mClient_FirstSyncTX = 0;
-        mClient_LastGoodSyncRX = 0;
-        mClient_PacketRTTLog.resetLog();
-    }
-
-    bool shouldPanicNotGettingGoodData();
-
-    // Helper to keep track of the state machine's current timeout
-    Timeout mCurTimeout;
-
-    // common clock, local clock abstraction, and clock recovery loop
-    CommonClock mCommonClock;
-    LocalClock mLocalClock;
-    ClockRecoveryLoop mClockRecovery;
-
-    // implementation of ICommonClock
-    sp<CommonClockService> mICommonClock;
-
-    // implementation of ICommonTimeConfig
-    sp<CommonTimeConfigService> mICommonTimeConfig;
-
-    // UDP socket for the time sync protocol
-    int mSocket;
-
-    // eventfd used to wakeup the work thread in response to configuration
-    // changes.
-    int mWakeupThreadFD;
-
-    // timestamp captured when a packet is received
-    int64_t mLastPacketRxLocalTime;
-
-    // ID of the timeline that this device is following
-    uint64_t mTimelineID;
-
-    // flag for whether the clock has been synced to a timeline
-    bool mClockSynced;
-
-    // flag used to indicate that clients should be considered to be lower
-    // priority than all of their peers during elections.  This flag is set and
-    // cleared by the state machine.  It is set when the client joins a new
-    // network.  If the client had been a master in the old network (or an
-    // isolated master with no network connectivity) it should defer to any
-    // masters which may already be on the network.  It will be cleared whenever
-    // the state machine transitions to the master state.
-    bool mForceLowPriority;
-    inline void setForceLowPriority(bool val) {
-        mForceLowPriority = val;
-        if (mState == ICommonClock::STATE_MASTER)
-            mClient_MasterDevicePriority = effectivePriority();
-    }
-
-    // Lock to synchronize access to internal state and configuration.
-    Mutex mLock;
-
-    // Flag updated by the common clock service to indicate that it does or does
-    // not currently have registered clients.  When the the auto disable flag is
-    // cleared on the common time service, the service will participate in
-    // network synchronization whenever it has a valid network interface to bind
-    // to.  When the auto disable flag is set on the common time service, it
-    // will only participate in network synchronization when it has both a valid
-    // interface AND currently active common clock clients.
-    bool mCommonClockHasClients;
-
-    // Internal logs used for dumpsys.
-    LogRing                 mStateChangeLog;
-    LogRing                 mElectionLog;
-    LogRing                 mBadPktLog;
-
-    // Configuration info
-    struct sockaddr_storage mMasterElectionEP;          // Endpoint over which we conduct master election
-    String8                 mBindIface;                 // Endpoint for the service to bind to.
-    bool                    mBindIfaceValid;            // whether or not the bind Iface is valid.
-    bool                    mBindIfaceDirty;            // whether or not the bind Iface is valid.
-    struct sockaddr_storage mMasterEP;                  // Endpoint of our current master (if any)
-    bool                    mMasterEPValid;
-    uint64_t                mDeviceID;                  // unique ID of this device
-    uint64_t                mSyncGroupID;               // synchronization group ID of this device.
-    uint8_t                 mMasterPriority;            // Priority of this device in master election.
-    uint32_t                mMasterAnnounceIntervalMs;
-    uint32_t                mSyncRequestIntervalMs;
-    uint32_t                mPanicThresholdUsec;
-    bool                    mAutoDisable;
-
-    // Config defaults.
-    static const char*      kDefaultMasterElectionAddr;
-    static const uint16_t   kDefaultMasterElectionPort;
-    static const uint64_t   kDefaultSyncGroupID;
-    static const uint8_t    kDefaultMasterPriority;
-    static const uint32_t   kDefaultMasterAnnounceIntervalMs;
-    static const uint32_t   kDefaultSyncRequestIntervalMs;
-    static const uint32_t   kDefaultPanicThresholdUsec;
-    static const bool       kDefaultAutoDisable;
-
-    // Priority mask and shift fields.
-    static const uint64_t kDeviceIDMask;
-    static const uint8_t  kDevicePriorityMask;
-    static const uint8_t  kDevicePriorityHiLowBit;
-    static const uint32_t kDevicePriorityShift;
-
-    // Unconfgurable constants
-    static const int      kSetupRetryTimeoutMs;
-    static const int64_t  kNoGoodDataPanicThresholdUsec;
-    static const uint32_t kRTTDiscardPanicThreshMultiplier;
-
-    /*** status while in the Initial state ***/
-    int mInitial_WhoIsMasterRequestTimeouts;
-    static const int kInitial_NumWhoIsMasterRetries;
-    static const int kInitial_WhoIsMasterTimeoutMs;
-
-    /*** status while in the Client state ***/
-    uint64_t mClient_MasterDeviceID;
-    uint8_t mClient_MasterDevicePriority;
-    bool mClient_SyncRequestPending;
-    int mClient_SyncRequestTimeouts;
-    uint32_t mClient_SyncsSentToCurMaster;
-    uint32_t mClient_SyncRespsRXedFromCurMaster;
-    uint32_t mClient_ExpiredSyncRespsRXedFromCurMaster;
-    int64_t mClient_FirstSyncTX;
-    int64_t mClient_LastGoodSyncRX;
-    PacketRTTLog mClient_PacketRTTLog;
-    static const int kClient_NumSyncRequestRetries;
-
-
-    /*** status while in the Master state ***/
-    static const uint32_t kDefaultMaster_AnnouncementIntervalMs;
-
-    /*** status while in the Ronin state ***/
-    int mRonin_WhoIsMasterRequestTimeouts;
-    static const int kRonin_NumWhoIsMasterRetries;
-    static const int kRonin_WhoIsMasterTimeoutMs;
-
-    /*** status while in the WaitForElection state ***/
-    static const int kWaitForElection_TimeoutMs;
-
-    static const int kInfiniteTimeout;
-
-    static const char* stateToString(ICommonClock::State s);
-    static void sockaddrToString(const sockaddr_storage& addr, bool addrValid,
-                                 char* buf, size_t bufLen);
-    static bool sockaddrMatch(const sockaddr_storage& a1,
-                              const sockaddr_storage& a2,
-                              bool matchAddressOnly);
-};
-
-}  // namespace android
-
-#endif  // ANDROID_COMMON_TIME_SERVER_H
diff --git a/libs/common_time/common_time_server_api.cpp b/libs/common_time/common_time_server_api.cpp
deleted file mode 100644
index 60e6567..0000000
--- a/libs/common_time/common_time_server_api.cpp
+++ /dev/null
@@ -1,440 +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.
- */
-
-/*
- * A service that exchanges time synchronization information between
- * a master that defines a timeline and clients that follow the timeline.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/IPCThreadState.h>
-
-#include "common_time_server.h"
-
-#include <inttypes.h>
-
-namespace android {
-
-//
-// Clock API
-//
-uint64_t CommonTimeServer::getTimelineID() {
-    AutoMutex _lock(&mLock);
-    return mTimelineID;
-}
-
-ICommonClock::State CommonTimeServer::getState() {
-    AutoMutex _lock(&mLock);
-    return mState;
-}
-
-status_t CommonTimeServer::getMasterAddr(struct sockaddr_storage* addr) {
-    AutoMutex _lock(&mLock);
-    if (mMasterEPValid) {
-        memcpy(addr, &mMasterEP, sizeof(*addr));
-        return OK;
-    }
-
-    return UNKNOWN_ERROR;
-}
-
-int32_t CommonTimeServer::getEstimatedError() {
-    AutoMutex _lock(&mLock);
-
-    if (ICommonClock::STATE_MASTER == mState)
-        return 0;
-
-    if (!mClockSynced)
-        return ICommonClock::kErrorEstimateUnknown;
-
-    return mClockRecovery.getLastErrorEstimate();
-}
-
-status_t CommonTimeServer::isCommonTimeValid(bool* valid,
-                                             uint32_t* timelineID) {
-    AutoMutex _lock(&mLock);
-    *valid = mCommonClock.isValid();
-    *timelineID = mTimelineID;
-    return OK;
-}
-
-//
-// Config API
-//
-status_t CommonTimeServer::getMasterElectionPriority(uint8_t *priority) {
-    AutoMutex _lock(&mLock);
-    *priority = mMasterPriority;
-    return OK;
-}
-
-status_t CommonTimeServer::setMasterElectionPriority(uint8_t priority) {
-    AutoMutex _lock(&mLock);
-
-    if (priority > 0x7F)
-        return BAD_VALUE;
-
-    mMasterPriority = priority;
-    return OK;
-}
-
-status_t CommonTimeServer::getMasterElectionEndpoint(
-        struct sockaddr_storage *addr) {
-    AutoMutex _lock(&mLock);
-    memcpy(addr, &mMasterElectionEP, sizeof(*addr));
-    return OK;
-}
-
-status_t CommonTimeServer::setMasterElectionEndpoint(
-        const struct sockaddr_storage *addr) {
-    AutoMutex _lock(&mLock);
-
-    if (!addr)
-        return BAD_VALUE;
-
-    // TODO: add proper support for IPv6
-    if (addr->ss_family != AF_INET)
-        return BAD_VALUE;
-
-    // Only multicast and broadcast endpoints with explicit ports are allowed.
-    uint16_t ipv4Port = ntohs(
-        reinterpret_cast<const struct sockaddr_in*>(addr)->sin_port);
-    if (!ipv4Port)
-        return BAD_VALUE;
-
-    uint32_t ipv4Addr = ntohl(
-        reinterpret_cast<const struct sockaddr_in*>(addr)->sin_addr.s_addr);
-    if ((ipv4Addr != 0xFFFFFFFF) && (0xE0000000 != (ipv4Addr & 0xF0000000)))
-        return BAD_VALUE;
-
-    memcpy(&mMasterElectionEP, addr, sizeof(mMasterElectionEP));
-
-    // Force a rebind in order to change election enpoints.
-    mBindIfaceDirty = true;
-    wakeupThread_l();
-    return OK;
-}
-
-status_t CommonTimeServer::getMasterElectionGroupId(uint64_t *id) {
-    AutoMutex _lock(&mLock);
-    *id = mSyncGroupID;
-    return OK;
-}
-
-status_t CommonTimeServer::setMasterElectionGroupId(uint64_t id) {
-    AutoMutex _lock(&mLock);
-    mSyncGroupID = id;
-    return OK;
-}
-
-status_t CommonTimeServer::getInterfaceBinding(String8& ifaceName) {
-    AutoMutex _lock(&mLock);
-    if (!mBindIfaceValid)
-        return INVALID_OPERATION;
-    ifaceName = mBindIface;
-    return OK;
-}
-
-status_t CommonTimeServer::setInterfaceBinding(const String8& ifaceName) {
-    AutoMutex _lock(&mLock);
-
-    mBindIfaceDirty = true;
-    if (ifaceName.size()) {
-        mBindIfaceValid = true;
-        mBindIface = ifaceName;
-    } else {
-        mBindIfaceValid = false;
-        mBindIface.clear();
-    }
-
-    wakeupThread_l();
-    return OK;
-}
-
-status_t CommonTimeServer::getMasterAnnounceInterval(int *interval) {
-    AutoMutex _lock(&mLock);
-    *interval = mMasterAnnounceIntervalMs;
-    return OK;
-}
-
-status_t CommonTimeServer::setMasterAnnounceInterval(int interval) {
-    AutoMutex _lock(&mLock);
-
-    if (interval > (6 *3600000)) // Max interval is once every 6 hrs
-        return BAD_VALUE;
-
-    if (interval < 500) // Min interval is once per 0.5 seconds
-        return BAD_VALUE;
-
-    mMasterAnnounceIntervalMs = interval;
-    if (ICommonClock::STATE_MASTER == mState) {
-        int pendingTimeout = mCurTimeout.msecTillTimeout();
-        if ((kInfiniteTimeout == pendingTimeout) ||
-            (pendingTimeout > interval)) {
-            mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
-            wakeupThread_l();
-        }
-    }
-
-    return OK;
-}
-
-status_t CommonTimeServer::getClientSyncInterval(int *interval) {
-    AutoMutex _lock(&mLock);
-    *interval = mSyncRequestIntervalMs;
-    return OK;
-}
-
-status_t CommonTimeServer::setClientSyncInterval(int interval) {
-    AutoMutex _lock(&mLock);
-
-    if (interval > (3600000)) // Max interval is once every 60 min
-        return BAD_VALUE;
-
-    if (interval < 250) // Min interval is once per 0.25 seconds
-        return BAD_VALUE;
-
-    mSyncRequestIntervalMs = interval;
-    if (ICommonClock::STATE_CLIENT == mState) {
-        int pendingTimeout = mCurTimeout.msecTillTimeout();
-        if ((kInfiniteTimeout == pendingTimeout) ||
-            (pendingTimeout > interval)) {
-            mCurTimeout.setTimeout(mSyncRequestIntervalMs);
-            wakeupThread_l();
-        }
-    }
-
-    return OK;
-}
-
-status_t CommonTimeServer::getPanicThreshold(int *threshold) {
-    AutoMutex _lock(&mLock);
-    *threshold = mPanicThresholdUsec;
-    return OK;
-}
-
-status_t CommonTimeServer::setPanicThreshold(int threshold) {
-    AutoMutex _lock(&mLock);
-
-    if (threshold < 1000) // Min threshold is 1mSec
-        return BAD_VALUE;
-
-    mPanicThresholdUsec = threshold;
-    return OK;
-}
-
-status_t CommonTimeServer::getAutoDisable(bool *autoDisable) {
-    AutoMutex _lock(&mLock);
-    *autoDisable = mAutoDisable;
-    return OK;
-}
-
-status_t CommonTimeServer::setAutoDisable(bool autoDisable) {
-    AutoMutex _lock(&mLock);
-    mAutoDisable = autoDisable;
-    wakeupThread_l();
-    return OK;
-}
-
-status_t CommonTimeServer::forceNetworklessMasterMode() {
-    AutoMutex _lock(&mLock);
-
-    // Can't force networkless master mode if we are currently bound to a
-    // network.
-    if (mSocket >= 0)
-        return INVALID_OPERATION;
-
-    becomeMaster("force networkless");
-
-    return OK;
-}
-
-void CommonTimeServer::reevaluateAutoDisableState(bool commonClockHasClients) {
-    AutoMutex _lock(&mLock);
-    bool needWakeup = (mAutoDisable && mMasterEPValid &&
-                      (commonClockHasClients != mCommonClockHasClients));
-
-    mCommonClockHasClients = commonClockHasClients;
-
-    if (needWakeup) {
-        ALOGI("Waking up service, auto-disable is engaged and service now has%s"
-             " clients", mCommonClockHasClients ? "" : " no");
-        wakeupThread_l();
-    }
-}
-
-#define dump_printf(a, b...) do {                 \
-    int res;                                      \
-    res = snprintf(buffer, sizeof(buffer), a, b); \
-    buffer[sizeof(buffer) - 1] = 0;               \
-    if (res > 0)                                  \
-        write(fd, buffer, res);                   \
-} while (0)
-#define checked_percentage(a, b) ((0 == (b)) ? 0.0f : ((100.0f * (a)) / (b)))
-
-status_t CommonTimeServer::dumpClockInterface(int fd,
-                                              const Vector<String16>& /* args */,
-                                              size_t activeClients) {
-    AutoMutex _lock(&mLock);
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        snprintf(buffer, SIZE, "Permission Denial: "
-                 "can't dump CommonClockService from pid=%d, uid=%d\n",
-                 IPCThreadState::self()->getCallingPid(),
-                 IPCThreadState::self()->getCallingUid());
-        write(fd, buffer, strlen(buffer));
-    } else {
-        int64_t commonTime;
-        int64_t localTime;
-        bool    synced;
-        char maStr[64];
-
-        localTime  = mLocalClock.getLocalTime();
-        synced     = (OK == mCommonClock.localToCommon(localTime, &commonTime));
-        sockaddrToString(mMasterEP, mMasterEPValid, maStr, sizeof(maStr));
-
-        dump_printf("Common Clock Service Status\nLocal time     : %" PRId64 "\n",
-                    localTime);
-
-        if (synced)
-            dump_printf("Common time    : %" PRId64 "\n", commonTime);
-        else
-            dump_printf("Common time    : %s\n", "not synced");
-
-        dump_printf("Timeline ID    : %016" PRIu64 "\n", mTimelineID);
-        dump_printf("State          : %s\n", stateToString(mState));
-        dump_printf("Master Addr    : %s\n", maStr);
-
-
-        if (synced) {
-            int32_t est = (ICommonClock::STATE_MASTER != mState)
-                        ? mClockRecovery.getLastErrorEstimate()
-                        : 0;
-            dump_printf("Error Est.     : %.3f msec\n",
-                        static_cast<float>(est) / 1000.0);
-        } else {
-            dump_printf("Error Est.     : %s\n", "unknown");
-        }
-
-        dump_printf("Syncs TXes     : %u\n", mClient_SyncsSentToCurMaster);
-        dump_printf("Syncs RXes     : %u (%.2f%%)\n",
-                    mClient_SyncRespsRXedFromCurMaster,
-                    checked_percentage(
-                        mClient_SyncRespsRXedFromCurMaster,
-                        mClient_SyncsSentToCurMaster));
-        dump_printf("RXs Expired    : %u (%.2f%%)\n",
-                    mClient_ExpiredSyncRespsRXedFromCurMaster,
-                    checked_percentage(
-                        mClient_ExpiredSyncRespsRXedFromCurMaster,
-                        mClient_SyncsSentToCurMaster));
-
-        if (!mClient_LastGoodSyncRX) {
-            dump_printf("Last Good RX   : %s\n", "unknown");
-        } else {
-            int64_t localDelta, usecDelta;
-            localDelta = localTime - mClient_LastGoodSyncRX;
-            usecDelta  = mCommonClock.localDurationToCommonDuration(localDelta);
-            dump_printf("Last Good RX   : %" PRId64 " uSec ago\n", usecDelta);
-        }
-
-        dump_printf("Active Clients : %zu\n", activeClients);
-        mClient_PacketRTTLog.dumpLog(fd, mCommonClock);
-        mStateChangeLog.dumpLog(fd);
-        mElectionLog.dumpLog(fd);
-        mBadPktLog.dumpLog(fd);
-    }
-
-    return NO_ERROR;
-}
-
-status_t CommonTimeServer::dumpConfigInterface(int fd,
-                                               const Vector<String16>& /* args */) {
-    AutoMutex _lock(&mLock);
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        snprintf(buffer, SIZE, "Permission Denial: "
-                 "can't dump CommonTimeConfigService from pid=%d, uid=%d\n",
-                 IPCThreadState::self()->getCallingPid(),
-                 IPCThreadState::self()->getCallingUid());
-        write(fd, buffer, strlen(buffer));
-    } else {
-        char meStr[64];
-
-        sockaddrToString(mMasterElectionEP, true, meStr, sizeof(meStr));
-
-        dump_printf("Common Time Config Service Status\n"
-                    "Bound Interface           : %s\n",
-                    mBindIfaceValid ? mBindIface.string() : "<unbound>");
-        dump_printf("Master Election Endpoint  : %s\n", meStr);
-        dump_printf("Master Election Group ID  : %016" PRIu64 "\n", mSyncGroupID);
-        dump_printf("Master Announce Interval  : %d mSec\n",
-                    mMasterAnnounceIntervalMs);
-        dump_printf("Client Sync Interval      : %d mSec\n",
-                    mSyncRequestIntervalMs);
-        dump_printf("Panic Threshold           : %d uSec\n",
-                    mPanicThresholdUsec);
-        dump_printf("Base ME Prio              : 0x%02x\n",
-                    static_cast<uint32_t>(mMasterPriority));
-        dump_printf("Effective ME Prio         : 0x%02x\n",
-                    static_cast<uint32_t>(effectivePriority()));
-        dump_printf("Auto Disable Allowed      : %s\n",
-                    mAutoDisable ? "yes" : "no");
-        dump_printf("Auto Disable Engaged      : %s\n",
-                    shouldAutoDisable() ? "yes" : "no");
-    }
-
-    return NO_ERROR;
-}
-
-void CommonTimeServer::PacketRTTLog::dumpLog(int fd, const CommonClock& cclk) {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    uint32_t avail = !logFull ? wrPtr : RTT_LOG_SIZE;
-
-    if (!avail)
-        return;
-
-    dump_printf("\nPacket Log (%d entries)\n", avail);
-
-    uint32_t ndx = 0;
-    uint32_t i = logFull ? wrPtr : 0;
-    do {
-        if (rxTimes[i]) {
-            int64_t delta = rxTimes[i] - txTimes[i];
-            int64_t deltaUsec = cclk.localDurationToCommonDuration(delta);
-            dump_printf("pkt[%2d] : localTX %12" PRId64 " localRX %12" PRId64 " "
-                        "(%.3f msec RTT)\n",
-                        ndx, txTimes[i], rxTimes[i],
-                        static_cast<float>(deltaUsec) / 1000.0);
-        } else {
-            dump_printf("pkt[%2d] : localTX %12" PRId64 " localRX never\n",
-                        ndx, txTimes[i]);
-        }
-        i = (i + 1) % RTT_LOG_SIZE;
-        ndx++;
-    } while (i != wrPtr);
-}
-
-#undef dump_printf
-#undef checked_percentage
-
-}  // namespace android
diff --git a/libs/common_time/common_time_server_packets.cpp b/libs/common_time/common_time_server_packets.cpp
deleted file mode 100644
index c7c893d..0000000
--- a/libs/common_time/common_time_server_packets.cpp
+++ /dev/null
@@ -1,293 +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.
- */
-
-/*
- * A service that exchanges time synchronization information between
- * a master that defines a timeline and clients that follow the timeline.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <arpa/inet.h>
-#include <stdint.h>
-
-#include "common_time_server_packets.h"
-
-namespace android {
-
-const uint32_t TimeServicePacketHeader::kMagic =
-    (static_cast<uint32_t>('c') << 24) |
-    (static_cast<uint32_t>('c') << 16) |
-    (static_cast<uint32_t>('l') <<  8) |
-     static_cast<uint32_t>('k');
-
-const uint16_t TimeServicePacketHeader::kCurVersion = 1;
-
-#define SERIALIZE_FIELD(field_name, type, converter)        \
-    do {                                                    \
-        if ((offset + sizeof(field_name)) > length)         \
-            return -1;                                      \
-        *((type*)(data + offset)) = converter(field_name);  \
-        offset += sizeof(field_name);                       \
-    } while (0)
-#define SERIALIZE_INT16(field_name) SERIALIZE_FIELD(field_name, int16_t, htons)
-#define SERIALIZE_INT32(field_name) SERIALIZE_FIELD(field_name, int32_t, htonl)
-#define SERIALIZE_INT64(field_name) SERIALIZE_FIELD(field_name, int64_t, htonq)
-
-#define DESERIALIZE_FIELD(field_name, type, converter)       \
-    do {                                                     \
-        if ((offset + sizeof(field_name)) > length)          \
-            return -1;                                       \
-        (field_name) = converter(*((type*)(data + offset))); \
-        offset += sizeof(field_name);                        \
-    } while (0)
-#define DESERIALIZE_INT16(field_name) DESERIALIZE_FIELD(field_name, int16_t, ntohs)
-#define DESERIALIZE_INT32(field_name) DESERIALIZE_FIELD(field_name, int32_t, ntohl)
-#define DESERIALIZE_INT64(field_name) DESERIALIZE_FIELD(field_name, int64_t, ntohq)
-
-#define kDevicePriorityShift 56
-#define kDeviceIDMask ((static_cast<uint64_t>(1) << kDevicePriorityShift) - 1)
-
-inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
-    return (devID & kDeviceIDMask) |
-           (static_cast<uint64_t>(prio) << kDevicePriorityShift);
-}
-
-inline uint64_t unpackDeviceID(uint64_t packed) {
-    return (packed & kDeviceIDMask);
-}
-
-inline uint8_t unpackDevicePriority(uint64_t packed) {
-    return static_cast<uint8_t>(packed >> kDevicePriorityShift);
-}
-
-ssize_t TimeServicePacketHeader::serializeHeader(uint8_t* data,
-                                                 uint32_t length) {
-    ssize_t offset = 0;
-    int16_t pktType = static_cast<int16_t>(packetType);
-    SERIALIZE_INT32(magic);
-    SERIALIZE_INT16(version);
-    SERIALIZE_INT16(pktType);
-    SERIALIZE_INT64(timelineID);
-    SERIALIZE_INT64(syncGroupID);
-    return offset;
-}
-
-ssize_t TimeServicePacketHeader::deserializeHeader(const uint8_t* data,
-                                                   uint32_t length) {
-    ssize_t offset = 0;
-    int16_t tmp;
-    DESERIALIZE_INT32(magic);
-    DESERIALIZE_INT16(version);
-    DESERIALIZE_INT16(tmp);
-    DESERIALIZE_INT64(timelineID);
-    DESERIALIZE_INT64(syncGroupID);
-    packetType = static_cast<TimeServicePacketType>(tmp);
-    return offset;
-}
-
-ssize_t TimeServicePacketHeader::serializePacket(uint8_t* data,
-                                                 uint32_t length) {
-    ssize_t ret, tmp;
-
-    ret = serializeHeader(data, length);
-    if (ret < 0)
-        return ret;
-
-    data += ret;
-    length -= ret;
-
-    switch (packetType) {
-        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
-            tmp =((WhoIsMasterRequestPacket*)(this))->serializePacket(data,
-                                                                      length);
-            break;
-        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
-            tmp =((WhoIsMasterResponsePacket*)(this))->serializePacket(data,
-                                                                       length);
-            break;
-        case TIME_PACKET_SYNC_REQUEST:
-            tmp =((SyncRequestPacket*)(this))->serializePacket(data, length);
-            break;
-        case TIME_PACKET_SYNC_RESPONSE:
-            tmp =((SyncResponsePacket*)(this))->serializePacket(data, length);
-            break;
-        case TIME_PACKET_MASTER_ANNOUNCEMENT:
-            tmp =((MasterAnnouncementPacket*)(this))->serializePacket(data,
-                                                                      length);
-            break;
-        default:
-            return -1;
-    }
-
-    if (tmp < 0)
-        return tmp;
-
-    return ret + tmp;
-}
-
-ssize_t UniversalTimeServicePacket::deserializePacket(
-        const uint8_t* data,
-        uint32_t length,
-        uint64_t expectedSyncGroupID) {
-    ssize_t ret;
-    TimeServicePacketHeader* header;
-    if (length < 8)
-        return -1;
-
-    packetType = ntohs(*((uint16_t*)(data + 6)));
-    switch (packetType) {
-        case TIME_PACKET_WHO_IS_MASTER_REQUEST:
-            ret = p.who_is_master_request.deserializePacket(data, length);
-            header = &p.who_is_master_request;
-            break;
-        case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
-            ret = p.who_is_master_response.deserializePacket(data, length);
-            header = &p.who_is_master_response;
-            break;
-        case TIME_PACKET_SYNC_REQUEST:
-            ret = p.sync_request.deserializePacket(data, length);
-            header = &p.sync_request;
-            break;
-        case TIME_PACKET_SYNC_RESPONSE:
-            ret = p.sync_response.deserializePacket(data, length);
-            header = &p.sync_response;
-            break;
-        case TIME_PACKET_MASTER_ANNOUNCEMENT:
-            ret = p.master_announcement.deserializePacket(data, length);
-            header = &p.master_announcement;
-            break;
-        default:
-            return -1;
-    }
-
-    if ((ret >= 0) && !header->checkPacket(expectedSyncGroupID))
-        ret = -1;
-
-    return ret;
-}
-
-ssize_t WhoIsMasterRequestPacket::serializePacket(uint8_t* data,
-                                                  uint32_t length) {
-    ssize_t offset = serializeHeader(data, length);
-    if (offset > 0) {
-        uint64_t packed = packDeviceID(senderDeviceID, senderDevicePriority);
-        SERIALIZE_INT64(packed);
-    }
-    return offset;
-}
-
-ssize_t WhoIsMasterRequestPacket::deserializePacket(const uint8_t* data,
-                                                    uint32_t length) {
-    ssize_t offset = deserializeHeader(data, length);
-    if (offset > 0) {
-        uint64_t packed;
-        DESERIALIZE_INT64(packed);
-        senderDeviceID       = unpackDeviceID(packed);
-        senderDevicePriority = unpackDevicePriority(packed);
-    }
-    return offset;
-}
-
-ssize_t WhoIsMasterResponsePacket::serializePacket(uint8_t* data,
-                                                   uint32_t length) {
-    ssize_t offset = serializeHeader(data, length);
-    if (offset > 0) {
-        uint64_t packed = packDeviceID(deviceID, devicePriority);
-        SERIALIZE_INT64(packed);
-    }
-    return offset;
-}
-
-ssize_t WhoIsMasterResponsePacket::deserializePacket(const uint8_t* data,
-                                                     uint32_t length) {
-    ssize_t offset = deserializeHeader(data, length);
-    if (offset > 0) {
-        uint64_t packed;
-        DESERIALIZE_INT64(packed);
-        deviceID       = unpackDeviceID(packed);
-        devicePriority = unpackDevicePriority(packed);
-    }
-    return offset;
-}
-
-ssize_t SyncRequestPacket::serializePacket(uint8_t* data,
-                                           uint32_t length) {
-    ssize_t offset = serializeHeader(data, length);
-    if (offset > 0) {
-        SERIALIZE_INT64(clientTxLocalTime);
-    }
-    return offset;
-}
-
-ssize_t SyncRequestPacket::deserializePacket(const uint8_t* data,
-                                             uint32_t length) {
-    ssize_t offset = deserializeHeader(data, length);
-    if (offset > 0) {
-        DESERIALIZE_INT64(clientTxLocalTime);
-    }
-    return offset;
-}
-
-ssize_t SyncResponsePacket::serializePacket(uint8_t* data,
-                                            uint32_t length) {
-    ssize_t offset = serializeHeader(data, length);
-    if (offset > 0) {
-        SERIALIZE_INT64(clientTxLocalTime);
-        SERIALIZE_INT64(masterRxCommonTime);
-        SERIALIZE_INT64(masterTxCommonTime);
-        SERIALIZE_INT32(nak);
-    }
-    return offset;
-}
-
-ssize_t SyncResponsePacket::deserializePacket(const uint8_t* data,
-                                              uint32_t length) {
-    ssize_t offset = deserializeHeader(data, length);
-    if (offset > 0) {
-        DESERIALIZE_INT64(clientTxLocalTime);
-        DESERIALIZE_INT64(masterRxCommonTime);
-        DESERIALIZE_INT64(masterTxCommonTime);
-        DESERIALIZE_INT32(nak);
-    }
-    return offset;
-}
-
-ssize_t MasterAnnouncementPacket::serializePacket(uint8_t* data,
-                                                  uint32_t length) {
-    ssize_t offset = serializeHeader(data, length);
-    if (offset > 0) {
-        uint64_t packed = packDeviceID(deviceID, devicePriority);
-        SERIALIZE_INT64(packed);
-    }
-    return offset;
-}
-
-ssize_t MasterAnnouncementPacket::deserializePacket(const uint8_t* data,
-                                                    uint32_t length) {
-    ssize_t offset = deserializeHeader(data, length);
-    if (offset > 0) {
-        uint64_t packed;
-        DESERIALIZE_INT64(packed);
-        deviceID       = unpackDeviceID(packed);
-        devicePriority = unpackDevicePriority(packed);
-    }
-    return offset;
-}
-
-}  // namespace android
-
diff --git a/libs/common_time/common_time_server_packets.h b/libs/common_time/common_time_server_packets.h
deleted file mode 100644
index 57ba8a2..0000000
--- a/libs/common_time/common_time_server_packets.h
+++ /dev/null
@@ -1,189 +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.
- */
-
-#ifndef ANDROID_COMMON_TIME_SERVER_PACKETS_H
-#define ANDROID_COMMON_TIME_SERVER_PACKETS_H
-
-#include <stdint.h>
-#include <common_time/ICommonClock.h>
-
-namespace android {
-
-/***** time sync protocol packets *****/
-
-enum TimeServicePacketType {
-    TIME_PACKET_WHO_IS_MASTER_REQUEST = 1,
-    TIME_PACKET_WHO_IS_MASTER_RESPONSE,
-    TIME_PACKET_SYNC_REQUEST,
-    TIME_PACKET_SYNC_RESPONSE,
-    TIME_PACKET_MASTER_ANNOUNCEMENT,
-};
-
-class TimeServicePacketHeader {
-  public:
-    friend class UniversalTimeServicePacket;
-    // magic number identifying the protocol
-    uint32_t magic;
-
-    // protocol version of the packet
-    uint16_t version;
-
-    // type of the packet
-    TimeServicePacketType packetType;
-
-    // the timeline ID
-    uint64_t timelineID;
-
-    // synchronization group this packet belongs to (used to operate multiple
-    // synchronization domains which all use the same master election endpoint)
-    uint64_t syncGroupID;
-
-    ssize_t serializePacket(uint8_t* data, uint32_t length);
-
-  protected:
-    void initHeader(TimeServicePacketType type,
-                    const uint64_t tlID,
-                    const uint64_t groupID) {
-        magic              = kMagic;
-        version            = kCurVersion;
-        packetType         = type;
-        timelineID         = tlID;
-        syncGroupID        = groupID;
-    }
-
-    bool checkPacket(uint64_t expectedSyncGroupID) const {
-        return ((magic       == kMagic) &&
-                (version     == kCurVersion) &&
-                (!expectedSyncGroupID || (syncGroupID == expectedSyncGroupID)));
-    }
-
-    ssize_t serializeHeader(uint8_t* data, uint32_t length);
-    ssize_t deserializeHeader(const uint8_t* data, uint32_t length);
-
-  private:
-    static const uint32_t kMagic;
-    static const uint16_t kCurVersion;
-};
-
-// packet querying for a suitable master
-class WhoIsMasterRequestPacket : public TimeServicePacketHeader {
-  public:
-    uint64_t senderDeviceID;
-    uint8_t senderDevicePriority;
-
-    void initHeader(const uint64_t groupID) {
-        TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_REQUEST,
-                                            ICommonClock::kInvalidTimelineID,
-                                            groupID);
-    }
-
-    ssize_t serializePacket(uint8_t* data, uint32_t length);
-    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
-};
-
-// response to a WhoIsMaster request
-class WhoIsMasterResponsePacket : public TimeServicePacketHeader {
-  public:
-    uint64_t deviceID;
-    uint8_t devicePriority;
-
-    void initHeader(const uint64_t tlID, const uint64_t groupID) {
-        TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_RESPONSE,
-                                            tlID, groupID);
-    }
-
-    ssize_t serializePacket(uint8_t* data, uint32_t length);
-    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
-};
-
-// packet sent by a client requesting correspondence between local
-// and common time
-class SyncRequestPacket : public TimeServicePacketHeader {
-  public:
-    // local time when this request was transmitted
-    int64_t clientTxLocalTime;
-
-    void initHeader(const uint64_t tlID, const uint64_t groupID) {
-        TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_REQUEST,
-                                            tlID, groupID);
-    }
-
-    ssize_t serializePacket(uint8_t* data, uint32_t length);
-    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
-};
-
-// response to a sync request sent by the master
-class SyncResponsePacket : public TimeServicePacketHeader {
-  public:
-    // local time when this request was transmitted by the client
-    int64_t clientTxLocalTime;
-
-    // common time when the master received the request
-    int64_t masterRxCommonTime;
-
-    // common time when the master transmitted the response
-    int64_t masterTxCommonTime;
-
-    // flag that is set if the recipient of the sync request is not acting
-    // as a master for the requested timeline
-    uint32_t nak;
-
-    void initHeader(const uint64_t tlID, const uint64_t groupID) {
-        TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_RESPONSE,
-                                            tlID, groupID);
-    }
-
-    ssize_t serializePacket(uint8_t* data, uint32_t length);
-    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
-};
-
-// announcement of the master's presence
-class MasterAnnouncementPacket : public TimeServicePacketHeader {
-  public:
-    // the master's device ID
-    uint64_t deviceID;
-    uint8_t devicePriority;
-
-    void initHeader(const uint64_t tlID, const uint64_t groupID) {
-        TimeServicePacketHeader::initHeader(TIME_PACKET_MASTER_ANNOUNCEMENT,
-                                            tlID, groupID);
-    }
-
-    ssize_t serializePacket(uint8_t* data, uint32_t length);
-    ssize_t deserializePacket(const uint8_t* data, uint32_t length);
-};
-
-class UniversalTimeServicePacket {
-  public:
-    uint16_t packetType;
-    union {
-        WhoIsMasterRequestPacket  who_is_master_request;
-        WhoIsMasterResponsePacket who_is_master_response;
-        SyncRequestPacket         sync_request;
-        SyncResponsePacket        sync_response;
-        MasterAnnouncementPacket  master_announcement;
-    } p;
-
-    ssize_t deserializePacket(const uint8_t* data,
-                              uint32_t       length,
-                              uint64_t       expectedSyncGroupID);
-};
-
-};  // namespace android
-
-#endif  // ANDROID_COMMON_TIME_SERVER_PACKETS_H
-
-
diff --git a/libs/common_time/diag_thread.cpp b/libs/common_time/diag_thread.cpp
deleted file mode 100644
index 4cb9551..0000000
--- a/libs/common_time/diag_thread.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <fcntl.h>
-#include <linux/in.h>
-#include <linux/tcp.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utils/Errors.h>
-#include <utils/misc.h>
-
-#include <common_time/local_clock.h>
-
-#include "common_clock.h"
-#include "diag_thread.h"
-
-#define kMaxEvents 16
-#define kListenPort 9876
-
-static bool setNonblocking(int fd) {
-    int flags = fcntl(fd, F_GETFL);
-    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
-        ALOGE("Failed to set socket (%d) to non-blocking mode (errno %d)",
-             fd, errno);
-        return false;
-    }
-
-    return true;
-}
-
-static bool setNodelay(int fd) {
-    int tmp = 1;
-    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof(tmp)) < 0) {
-        ALOGE("Failed to set socket (%d) to no-delay mode (errno %d)",
-             fd, errno);
-        return false;
-    }
-
-    return true;
-}
-
-namespace android {
-
-DiagThread::DiagThread(CommonClock* common_clock, LocalClock* local_clock) {
-    common_clock_ = common_clock;
-    local_clock_ = local_clock;
-    listen_fd_ = -1;
-    data_fd_ = -1;
-    kernel_logID_basis_known_ = false;
-    discipline_log_ID_ = 0;
-}
-
-DiagThread::~DiagThread() {
-}
-
-status_t DiagThread::startWorkThread() {
-    status_t res;
-    stopWorkThread();
-    res = run("Diag");
-
-    if (res != OK)
-        ALOGE("Failed to start work thread (res = %d)", res);
-
-    return res;
-}
-
-void DiagThread::stopWorkThread() {
-    status_t res;
-    res = requestExitAndWait(); // block until thread exit.
-    if (res != OK)
-        ALOGE("Failed to stop work thread (res = %d)", res);
-}
-
-bool DiagThread::openListenSocket() {
-    bool ret = false;
-    int flags;
-    cleanupListenSocket();
-
-    if ((listen_fd_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
-        ALOGE("Socket failed.");
-        goto bailout;
-    }
-
-    // Set non-blocking operation
-    if (!setNonblocking(listen_fd_))
-        goto bailout;
-
-    struct sockaddr_in addr;
-    memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    addr.sin_addr.s_addr = INADDR_ANY;
-    addr.sin_port = htons(kListenPort);
-
-    if (bind(listen_fd_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
-        ALOGE("Bind failed.");
-        goto bailout;
-    }
-
-    if (listen(listen_fd_, 1) < 0) {
-        ALOGE("Listen failed.");
-        goto bailout;
-    }
-
-    ret = true;
-bailout:
-    if (!ret)
-        cleanupListenSocket();
-
-    return ret;
-}
-
-void DiagThread::cleanupListenSocket() {
-    if (listen_fd_ >= 0) {
-        int res;
-
-        struct linger l;
-        l.l_onoff  = 1;
-        l.l_linger = 0;
-
-        setsockopt(listen_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
-        shutdown(listen_fd_, SHUT_RDWR);
-        close(listen_fd_);
-        listen_fd_ = -1;
-    }
-}
-
-void DiagThread::cleanupDataSocket() {
-    if (data_fd_ >= 0) {
-        int res;
-
-        struct linger l;
-        l.l_onoff  = 1;
-        l.l_linger = 0;
-
-        setsockopt(data_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
-        shutdown(data_fd_, SHUT_RDWR);
-        close(data_fd_);
-        data_fd_ = -1;
-    }
-}
-
-void DiagThread::resetLogIDs() {
-    // Drain and discard all of the events from the kernel
-    struct local_time_debug_event events[kMaxEvents];
-    while(local_clock_->getDebugLog(events, kMaxEvents) > 0)
-        ;
-
-    {
-        Mutex::Autolock lock(&discipline_log_lock_);
-        discipline_log_.clear();
-        discipline_log_ID_ = 0;
-    }
-
-    kernel_logID_basis_known_ = false;
-}
-
-void DiagThread::pushDisciplineEvent(int64_t observed_local_time,
-                                     int64_t observed_common_time,
-                                     int64_t nominal_common_time,
-                                     int32_t total_correction,
-                                     int32_t rtt) {
-    Mutex::Autolock lock(&discipline_log_lock_);
-
-    DisciplineEventRecord evt;
-
-    evt.event_id = discipline_log_ID_++;
-
-    evt.action_local_time = local_clock_->getLocalTime();
-    common_clock_->localToCommon(evt.action_local_time,
-            &evt.action_common_time);
-
-    evt.observed_local_time  = observed_local_time;
-    evt.observed_common_time = observed_common_time;
-    evt.nominal_common_time  = nominal_common_time;
-    evt.total_correction     = total_correction;
-    evt.rtt                  = rtt;
-
-    discipline_log_.push_back(evt);
-    while (discipline_log_.size() > kMaxDisciplineLogSize)
-        discipline_log_.erase(discipline_log_.begin());
-}
-
-bool DiagThread::threadLoop() {
-    struct pollfd poll_fds[1];
-
-    if (!openListenSocket()) {
-        ALOGE("Failed to open listen socket");
-        goto bailout;
-    }
-
-    while (!exitPending()) {
-        memset(&poll_fds, 0, sizeof(poll_fds));
-
-        if (data_fd_ < 0) {
-            poll_fds[0].fd     = listen_fd_;
-            poll_fds[0].events = POLLIN;
-        } else {
-            poll_fds[0].fd     = data_fd_;
-            poll_fds[0].events = POLLRDHUP | POLLIN;
-        }
-
-        int poll_res = poll(poll_fds, NELEM(poll_fds), 50);
-        if (poll_res < 0) {
-            ALOGE("Fatal error (%d,%d) while waiting on events",
-                 poll_res, errno);
-            goto bailout;
-        }
-
-        if (exitPending())
-            break;
-
-        if (poll_fds[0].revents) {
-            if (poll_fds[0].fd == listen_fd_) {
-                data_fd_ = accept(listen_fd_, NULL, NULL);
-
-                if (data_fd_ < 0) {
-                    ALOGW("Failed accept on socket %d with err %d",
-                         listen_fd_, errno);
-                } else {
-                    if (!setNonblocking(data_fd_))
-                        cleanupDataSocket();
-                    if (!setNodelay(data_fd_))
-                        cleanupDataSocket();
-                }
-            } else
-                if (poll_fds[0].fd == data_fd_) {
-                    if (poll_fds[0].revents & POLLRDHUP) {
-                        // Connection hung up; time to clean up.
-                        cleanupDataSocket();
-                    } else
-                        if (poll_fds[0].revents & POLLIN) {
-                            uint8_t cmd;
-                            if (read(data_fd_, &cmd, sizeof(cmd)) > 0) {
-                                switch(cmd) {
-                                    case 'r':
-                                    case 'R':
-                                        resetLogIDs();
-                                        break;
-                                }
-                            }
-                        }
-                }
-        }
-
-        struct local_time_debug_event events[kMaxEvents];
-        int amt = local_clock_->getDebugLog(events, kMaxEvents);
-
-        if (amt > 0) {
-            for (int i = 0; i < amt; i++) {
-                struct local_time_debug_event& e = events[i];
-
-                if (!kernel_logID_basis_known_) {
-                    kernel_logID_basis_ = e.local_timesync_event_id;
-                    kernel_logID_basis_known_ = true;
-                }
-
-                char buf[1024];
-                int64_t common_time;
-                status_t res = common_clock_->localToCommon(e.local_time,
-                                                            &common_time);
-                snprintf(buf, sizeof(buf), "E,%lld,%lld,%lld,%d\n",
-                         e.local_timesync_event_id - kernel_logID_basis_,
-                         e.local_time,
-                         common_time,
-                         (OK == res) ? 1 : 0);
-                buf[sizeof(buf) - 1] = 0;
-
-                if (data_fd_ >= 0)
-                    write(data_fd_, buf, strlen(buf));
-            }
-        }
-
-        { // scope for autolock pattern
-            Mutex::Autolock lock(&discipline_log_lock_);
-
-            while (discipline_log_.size() > 0) {
-                char buf[1024];
-                DisciplineEventRecord& e = *discipline_log_.begin();
-                snprintf(buf, sizeof(buf),
-                         "D,%lld,%lld,%lld,%lld,%lld,%lld,%d,%d\n",
-                         e.event_id,
-                         e.action_local_time,
-                         e.action_common_time,
-                         e.observed_local_time,
-                         e.observed_common_time,
-                         e.nominal_common_time,
-                         e.total_correction,
-                         e.rtt);
-                buf[sizeof(buf) - 1] = 0;
-
-                if (data_fd_ >= 0)
-                    write(data_fd_, buf, strlen(buf));
-
-                discipline_log_.erase(discipline_log_.begin());
-            }
-        }
-    }
-
-bailout:
-    cleanupDataSocket();
-    cleanupListenSocket();
-    return false;
-}
-
-}  // namespace android
diff --git a/libs/common_time/diag_thread.h b/libs/common_time/diag_thread.h
deleted file mode 100644
index c630e0d..0000000
--- a/libs/common_time/diag_thread.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef __DIAG_THREAD_H__
-#define __DIAG_THREAD_H__
-
-#include <utils/List.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class CommonClock;
-class LocalClock;
-
-class DiagThread : public Thread {
-  public:
-    DiagThread(CommonClock* common_clock, LocalClock* local_clock);
-    ~DiagThread();
-
-    status_t      startWorkThread();
-    void          stopWorkThread();
-    virtual bool  threadLoop();
-
-    void pushDisciplineEvent(int64_t observed_local_time,
-                             int64_t observed_common_time,
-                             int64_t nominal_common_time,
-                             int32_t total_correction,
-                             int32_t rtt);
-
-  private:
-    typedef struct {
-        int64_t event_id;
-        int64_t action_local_time;
-        int64_t action_common_time;
-        int64_t observed_local_time;
-        int64_t observed_common_time;
-        int64_t nominal_common_time;
-        int32_t total_correction;
-        int32_t rtt;
-    } DisciplineEventRecord;
-
-    bool            openListenSocket();
-    void            cleanupListenSocket();
-    void            cleanupDataSocket();
-    void            resetLogIDs();
-
-    CommonClock*    common_clock_;
-    LocalClock*     local_clock_;
-    int             listen_fd_;
-    int             data_fd_;
-
-    int64_t         kernel_logID_basis_;
-    bool            kernel_logID_basis_known_;
-
-    static const size_t         kMaxDisciplineLogSize = 16;
-    Mutex                       discipline_log_lock_;
-    List<DisciplineEventRecord> discipline_log_;
-    int64_t                     discipline_log_ID_;
-};
-
-}  // namespace android
-
-#endif  //__ DIAG_THREAD_H__
diff --git a/libs/common_time/main.cpp b/libs/common_time/main.cpp
deleted file mode 100644
index ac52c85..0000000
--- a/libs/common_time/main.cpp
+++ /dev/null
@@ -1,43 +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.
- */
-
-/*
- * A service that exchanges time synchronization information between
- * a master that defines a timeline and clients that follow the timeline.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-
-#include "common_time_server.h"
-
-int main() {
-    using namespace android;
-
-    sp<CommonTimeServer> service = new CommonTimeServer();
-    if (service == NULL)
-        return 1;
-
-    ProcessState::self()->startThreadPool();
-    service->run("CommonTimeServer", ANDROID_PRIORITY_NORMAL);
-
-    IPCThreadState::self()->joinThreadPool();
-    return 0;
-}
-
diff --git a/libs/common_time/utils.cpp b/libs/common_time/utils.cpp
deleted file mode 100644
index ddcdfe7..0000000
--- a/libs/common_time/utils.cpp
+++ /dev/null
@@ -1,164 +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.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include "utils.h"
-
-namespace android {
-
-void Timeout::setTimeout(int msec) {
-    if (msec < 0) {
-        mSystemEndTime = 0;
-        return;
-    }
-
-    mSystemEndTime = systemTime() + (static_cast<nsecs_t>(msec) * 1000000);
-}
-
-int Timeout::msecTillTimeout(nsecs_t nowTime) {
-    if (!mSystemEndTime) {
-        return -1;
-    }
-
-    if (mSystemEndTime < nowTime) {
-        return 0;
-    }
-
-    nsecs_t delta = mSystemEndTime - nowTime;
-    delta += 999999;
-    delta /= 1000000;
-    if (delta > 0x7FFFFFFF) {
-        return 0x7FFFFFFF;
-    }
-
-    return static_cast<int>(delta);
-}
-
-LogRing::LogRing(const char* header, size_t entries)
-    : mSize(entries)
-    , mWr(0)
-    , mIsFull(false)
-    , mHeader(header) {
-    mRingBuffer = new Entry[mSize];
-    if (NULL == mRingBuffer)
-        ALOGE("Failed to allocate log ring with %zu entries.", mSize);
-}
-
-LogRing::~LogRing() {
-    if (NULL != mRingBuffer)
-        delete[] mRingBuffer;
-}
-
-void LogRing::log(int prio, const char* tag, const char* fmt, ...) {
-    va_list argp;
-    va_start(argp, fmt);
-    internalLog(prio, tag, fmt, argp);
-    va_end(argp);
-}
-
-void LogRing::log(const char* fmt, ...) {
-    va_list argp;
-    va_start(argp, fmt);
-    internalLog(0, NULL, fmt, argp);
-    va_end(argp);
-}
-
-void LogRing::internalLog(int prio,
-                          const char* tag,
-                          const char* fmt,
-                          va_list argp) {
-    if (NULL != mRingBuffer) {
-        Mutex::Autolock lock(&mLock);
-        String8 s(String8::formatV(fmt, argp));
-        Entry* last = NULL;
-
-        if (mIsFull || mWr)
-            last = &(mRingBuffer[(mWr + mSize - 1) % mSize]);
-
-
-        if ((NULL != last) && !last->s.compare(s)) {
-            gettimeofday(&(last->last_ts), NULL);
-            ++last->count;
-        } else {
-            gettimeofday(&mRingBuffer[mWr].first_ts, NULL);
-            mRingBuffer[mWr].last_ts = mRingBuffer[mWr].first_ts;
-            mRingBuffer[mWr].count = 1;
-            mRingBuffer[mWr].s.setTo(s);
-
-            mWr = (mWr + 1) % mSize;
-            if (!mWr)
-                mIsFull = true;
-        }
-    }
-
-    if (NULL != tag)
-        LOG_PRI_VA(prio, tag, fmt, argp);
-}
-
-void LogRing::dumpLog(int fd) {
-    if (NULL == mRingBuffer)
-        return;
-
-    Mutex::Autolock lock(&mLock);
-
-    if (!mWr && !mIsFull)
-        return;
-
-    char buf[1024];
-    int res;
-    size_t start = mIsFull ? mWr : 0;
-    size_t count = mIsFull ? mSize : mWr;
-    static const char* kTimeFmt = "%a %b %d %Y %H:%M:%S";
-
-    res = snprintf(buf, sizeof(buf), "\n%s\n", mHeader);
-    if (res > 0)
-        write(fd, buf, res);
-
-    for (size_t i = 0; i < count; ++i) {
-        struct tm t;
-        char timebuf[64];
-        char repbuf[96];
-        size_t ndx = (start + i) % mSize;
-
-        if (1 != mRingBuffer[ndx].count) {
-            localtime_r(&mRingBuffer[ndx].last_ts.tv_sec, &t);
-            strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
-            snprintf(repbuf, sizeof(repbuf),
-                    " (repeated %d times, last was %s.%03ld)",
-                     mRingBuffer[ndx].count,
-                     timebuf,
-                     mRingBuffer[ndx].last_ts.tv_usec / 1000);
-            repbuf[sizeof(repbuf) - 1] = 0;
-        } else {
-            repbuf[0] = 0;
-        }
-
-        localtime_r(&mRingBuffer[ndx].first_ts.tv_sec, &t);
-        strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
-        res = snprintf(buf, sizeof(buf), "[%2zu] %s.%03ld :: %s%s\n",
-                       i, timebuf,
-                       mRingBuffer[ndx].first_ts.tv_usec / 1000,
-                       mRingBuffer[ndx].s.string(),
-                       repbuf);
-
-        if (res > 0)
-            write(fd, buf, res);
-    }
-}
-
-}  // namespace android
diff --git a/libs/common_time/utils.h b/libs/common_time/utils.h
deleted file mode 100644
index c28cf0a..0000000
--- a/libs/common_time/utils.h
+++ /dev/null
@@ -1,83 +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.
- */
-
-#ifndef __UTILS_H__
-#define __UTILS_H__
-
-#include <stdint.h>
-#include <unistd.h>
-
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-class Timeout {
-  public:
-    Timeout() : mSystemEndTime(0) { }
-
-    // Set a timeout which should occur msec milliseconds from now.
-    // Negative values will cancel any current timeout;
-    void setTimeout(int msec);
-
-    // Return the number of milliseconds until the timeout occurs, or -1 if
-    // no timeout is scheduled.
-    int msecTillTimeout(nsecs_t nowTime);
-    int msecTillTimeout() { return msecTillTimeout(systemTime()); }
-
-  private:
-    // The systemTime() at which the timeout will be complete, or 0 if no
-    // timeout is currently scheduled.
-    nsecs_t mSystemEndTime;
-};
-
-class LogRing {
-  public:
-    LogRing(const char* header, size_t entries);
-    ~LogRing();
-
-    // Send a log message to logcat as well as storing it in the ring buffer.
-    void log(int prio, const char* tag, const char* fmt, ...);
-
-    // Add a log message the ring buffer, do not send the message to logcat.
-    void log(const char* fmt, ...);
-
-    // Dump the log to an fd (dumpsys style)
-    void dumpLog(int fd);
-
-  private:
-    class Entry {
-      public:
-        uint32_t count;
-        struct timeval first_ts;
-        struct timeval last_ts;
-        String8 s;
-    };
-
-    Mutex  mLock;
-    Entry* mRingBuffer;
-    size_t mSize;
-    size_t mWr;
-    bool   mIsFull;
-    const char* mHeader;
-
-    void internalLog(int prio, const char* tag, const char* fmt, va_list va);
-};
-
-}  // namespace android
-
-#endif  // __UTILS_H__
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
new file mode 100644
index 0000000..3b25787
--- /dev/null
+++ b/media/lib/signer/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2018 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.
+//
+
+java_sdk_library {
+    name: "com.android.mediadrm.signer",
+    srcs: ["java/**/*.java"],
+    api_packages: ["com.android.mediadrm.signer"],
+}
diff --git a/media/lib/signer/Android.mk b/media/lib/signer/Android.mk
deleted file mode 100644
index 69ca4d2..0000000
--- a/media/lib/signer/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-LOCAL_PATH := $(call my-dir)
-
-# the mediadrm signer library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= com.android.mediadrm.signer
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-# ====  com.android.mediadrm.signer.xml lib def  ========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.android.mediadrm.signer.xml
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
diff --git a/media/lib/signer/api/current.txt b/media/lib/signer/api/current.txt
new file mode 100644
index 0000000..4aa912d
--- /dev/null
+++ b/media/lib/signer/api/current.txt
@@ -0,0 +1,21 @@
+package com.android.mediadrm.signer {
+
+  public final class MediaDrmSigner {
+    method public static com.android.mediadrm.signer.MediaDrmSigner.CertificateRequest getCertificateRequest(android.media.MediaDrm, int, java.lang.String);
+    method public static com.android.mediadrm.signer.MediaDrmSigner.Certificate provideCertificateResponse(android.media.MediaDrm, byte[]) throws android.media.DeniedByServerException;
+    method public static byte[] signRSA(android.media.MediaDrm, byte[], java.lang.String, byte[], byte[]);
+    field public static final int CERTIFICATE_TYPE_X509 = 1; // 0x1
+  }
+
+  public static final class MediaDrmSigner.Certificate {
+    method public byte[] getContent();
+    method public byte[] getWrappedPrivateKey();
+  }
+
+  public static final class MediaDrmSigner.CertificateRequest {
+    method public byte[] getData();
+    method public java.lang.String getDefaultUrl();
+  }
+
+}
+
diff --git a/media/lib/signer/api/removed.txt b/media/lib/signer/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/removed.txt
diff --git a/media/lib/signer/api/system-current.txt b/media/lib/signer/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/system-current.txt
diff --git a/media/lib/signer/api/system-removed.txt b/media/lib/signer/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/system-removed.txt
diff --git a/media/lib/signer/api/test-current.txt b/media/lib/signer/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/test-current.txt
diff --git a/media/lib/signer/api/test-removed.txt b/media/lib/signer/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/test-removed.txt
diff --git a/media/lib/signer/com.android.mediadrm.signer.xml b/media/lib/signer/com.android.mediadrm.signer.xml
deleted file mode 100644
index fd3a115..0000000
--- a/media/lib/signer/com.android.mediadrm.signer.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<permissions>
-    <library name="com.android.mediadrm.signer"
-            file="/system/framework/com.android.mediadrm.signer.jar" />
-</permissions>
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
deleted file mode 100644
index 5cebfa5..0000000
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ /dev/null
@@ -1,364 +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 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.INetworkManagementEventObserver;
-import android.net.InterfaceConfiguration;
-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.internal.util.DumpUtils;
-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 final Object mLock = new Object();
-    private INetworkManagementService mNetMgr;
-    private CommonTimeConfig mCTConfig;
-    private String mCurIface;
-    private Handler mReconnectHandler = new Handler();
-    private Handler mNoInterfaceHandler = new Handler();
-    private boolean mDetectedAtStartup = false;
-    private byte mEffectivePrio = BASE_SERVER_PRIO;
-
-    /*
-     * Callback handler implementations.
-     */
-    private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() {
-        @Override
-        public void interfaceStatusChanged(String iface, boolean up) {
-            reevaluateServiceState();
-        }
-        @Override
-        public void interfaceLinkStateChanged(String iface, boolean up) {
-            reevaluateServiceState();
-        }
-        @Override
-        public void interfaceAdded(String iface) {
-            reevaluateServiceState();
-        }
-        @Override
-        public void interfaceRemoved(String iface) {
-            reevaluateServiceState();
-        }
-    };
-
-    private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            reevaluateServiceState();
-        }
-    };
-
-    private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener =
-            () -> scheduleTimeConfigReconnect();
-
-    private Runnable mReconnectRunnable = () -> connectToTimeConfig();
-
-    private Runnable mNoInterfaceRunnable = () -> 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 (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) 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);
-            }
-        }
-    }
-}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 60f201f..7caa4d7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -690,7 +690,6 @@
         WindowManagerService wm = null;
         SerialService serial = null;
         NetworkTimeUpdateService networkTimeUpdater = null;
-        CommonTimeManagementService commonTimeMgmtService = null;
         InputManagerService inputManager = null;
         TelephonyRegistry telephonyRegistry = null;
         ConsumerIrService consumerIr = null;
@@ -1383,15 +1382,6 @@
                 traceEnd();
             }
 
-            traceBeginAndSlog("StartCommonTimeManagementService");
-            try {
-                commonTimeMgmtService = new CommonTimeManagementService(context);
-                ServiceManager.addService("commontime_management", commonTimeMgmtService);
-            } catch (Throwable e) {
-                reportWtf("starting CommonTimeManagementService service", e);
-            }
-            traceEnd();
-
             if (!disableNetwork) {
                 traceBeginAndSlog("CertBlacklister");
                 try {
@@ -1667,7 +1657,6 @@
         final LocationManagerService locationF = location;
         final CountryDetectorService countryDetectorF = countryDetector;
         final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
-        final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
         final InputManagerService inputManagerF = inputManager;
         final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
         final MediaRouterService mediaRouterF = mediaRouter;
@@ -1813,15 +1802,6 @@
                 reportWtf("Notifying NetworkTimeService running", e);
             }
             traceEnd();
-            traceBeginAndSlog("MakeCommonTimeManagementServiceReady");
-            try {
-                if (commonTimeMgmtServiceF != null) {
-                    commonTimeMgmtServiceF.systemRunning();
-                }
-            } catch (Throwable e) {
-                reportWtf("Notifying CommonTimeManagementService running", e);
-            }
-            traceEnd();
             traceBeginAndSlog("MakeInputManagerServiceReady");
             try {
                 // TODO(BT) Pass parameter to input manager
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index 2f52c0a..dfb6e2c 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -77,6 +77,11 @@
             result = 31 * result + featureType;
             return result;
         }
+
+        @Override
+        public String toString() {
+            return "{s=" + slotId + ", f=" + featureType + "}";
+        }
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index e0297ca..3fd1d04 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -823,6 +823,16 @@
     boolean isResolvingImsBinding();
 
     /**
+    *  @return true if the ImsService to bind to for the slot id specified was set, false otherwise.
+    */
+    boolean setImsService(int slotId, boolean isCarrierImsService, String packageName);
+
+    /**
+    * @return the package name of the carrier/device ImsService associated with this slot.
+    */
+    String getImsService(int slotId, boolean isCarrierImsService);
+
+    /**
      * Set the network selection mode to automatic.
      *
      * @param subId the id of the subscription to update.
