Merge "Opportunistic typo fix"
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/config/generate-preloaded-classes.sh b/config/generate-preloaded-classes.sh
index e36e148..0ad3a02 100755
--- a/config/generate-preloaded-classes.sh
+++ b/config/generate-preloaded-classes.sh
@@ -36,4 +36,4 @@
extra_classes_files=("$@")
# Disable locale to enable lexicographical sorting
-LC_ALL=C sort "$input" "${extra_classes_files[@]}" | uniq | grep -f "$blacklist" -v -F -x
+LC_ALL=C sort "$input" "${extra_classes_files[@]}" | uniq | grep -f "$blacklist" -v -F -x | grep -v "\$NoPreloadHolder"
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/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b110ccf..29d7dee 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3664,6 +3664,7 @@
* @param device Bluetooth device connected/disconnected
* @param state new connection state (BluetoothProfile.STATE_xxx)
* @param profile profile for the A2DP device
+ * @param a2dpVolume New volume for the connecting device. Does nothing if disconnecting.
* (either {@link android.bluetooth.BluetoothProfile.A2DP} or
* {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
* @param suppressNoisyIntent if true the
@@ -3673,12 +3674,13 @@
* {@hide}
*/
public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- BluetoothDevice device, int state, int profile, boolean suppressNoisyIntent) {
+ BluetoothDevice device, int state, int profile,
+ boolean suppressNoisyIntent, int a2dpVolume) {
final IAudioService service = getService();
int delay = 0;
try {
delay = service.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(device,
- state, profile, suppressNoisyIntent);
+ state, profile, suppressNoisyIntent, a2dpVolume);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 07b6bbd..d757b81 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -206,7 +206,7 @@
oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);
int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(in BluetoothDevice device,
- int state, int profile, boolean suppressNoisyIntent);
+ int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
// WARNING: read warning at top of file, it is recommended to add new methods at the end
}
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/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2fbd58b..5491f77 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3476,7 +3476,7 @@
queueMsgUnderWakeLock(mAudioHandler,
MSG_SET_A2DP_SINK_CONNECTION_STATE,
state,
- 0 /* arg2 unused */,
+ -1,
btDevice,
delay);
}
@@ -4162,22 +4162,22 @@
public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
{
return setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- device, state, profile, false /* suppressNoisyIntent */);
+ device, state, profile, false /* suppressNoisyIntent */, -1 /* a2dpVolume */);
}
public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice device,
- int state, int profile, boolean suppressNoisyIntent)
+ int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)
{
if (mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE, device)) {
return 0;
}
return setBluetoothA2dpDeviceConnectionStateInt(
- device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE);
+ device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume);
}
public int setBluetoothA2dpDeviceConnectionStateInt(
BluetoothDevice device, int state, int profile, boolean suppressNoisyIntent,
- int musicDevice)
+ int musicDevice, int a2dpVolume)
{
int delay;
if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) {
@@ -4195,7 +4195,7 @@
(profile == BluetoothProfile.A2DP ?
MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
state,
- 0 /* arg2 unused */,
+ a2dpVolume,
device,
delay);
}
@@ -4693,41 +4693,41 @@
}
}
- /** Handles internal volume messages in separate volume thread. */
- private class AudioHandler extends Handler {
+ private void setDeviceVolume(VolumeStreamState streamState, int device) {
- private void setDeviceVolume(VolumeStreamState streamState, int device) {
+ synchronized (VolumeStreamState.class) {
+ // Apply volume
+ streamState.applyDeviceVolume_syncVSS(device);
- synchronized (VolumeStreamState.class) {
- // Apply volume
- streamState.applyDeviceVolume_syncVSS(device);
-
- // Apply change to all streams using this one as alias
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- if (streamType != streamState.mStreamType &&
- mStreamVolumeAlias[streamType] == streamState.mStreamType) {
- // Make sure volume is also maxed out on A2DP device for aliased stream
- // that may have a different device selected
- int streamDevice = getDeviceForStream(streamType);
- if ((device != streamDevice) && mAvrcpAbsVolSupported &&
- ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
- mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
- }
- mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
+ // Apply change to all streams using this one as alias
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+ if (streamType != streamState.mStreamType &&
+ mStreamVolumeAlias[streamType] == streamState.mStreamType) {
+ // Make sure volume is also maxed out on A2DP device for aliased stream
+ // that may have a different device selected
+ int streamDevice = getDeviceForStream(streamType);
+ if ((device != streamDevice) && mAvrcpAbsVolSupported &&
+ ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
+ mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
}
+ mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
}
}
- // Post a persist volume msg
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- device,
- 0,
- streamState,
- PERSIST_DELAY);
-
}
+ // Post a persist volume msg
+ sendMsg(mAudioHandler,
+ MSG_PERSIST_VOLUME,
+ SENDMSG_QUEUE,
+ device,
+ 0,
+ streamState,
+ PERSIST_DELAY);
+
+ }
+
+ /** Handles internal volume messages in separate volume thread. */
+ private class AudioHandler extends Handler {
private void setAllVolumes(VolumeStreamState streamState) {
@@ -5074,7 +5074,7 @@
break;
case MSG_SET_A2DP_SINK_CONNECTION_STATE:
- onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1, msg.arg2);
mAudioEventWakeLock.release();
break;
@@ -5312,7 +5312,7 @@
return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
- private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state)
+ private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state, int a2dpVolume)
{
if (DEBUG_DEVICES) {
Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice+"state=" + state);
@@ -5363,6 +5363,14 @@
makeA2dpDeviceUnavailableNow(mDockAddress);
}
}
+ if (a2dpVolume != -1) {
+ VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
+ // Convert index to internal representation in VolumeStreamState
+ a2dpVolume = a2dpVolume * 10;
+ streamState.setIndex(a2dpVolume, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ "onSetA2dpSinkConnectionState");
+ setDeviceVolume(streamState, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
+ }
makeA2dpDeviceAvailable(address, btDevice.getName(),
"onSetA2dpSinkConnectionState");
synchronized (mCurAudioRoutes) {
@@ -5432,7 +5440,7 @@
// consistent with audio policy manager state
setBluetoothA2dpDeviceConnectionStateInt(
btDevice, BluetoothA2dp.STATE_DISCONNECTED, BluetoothProfile.A2DP,
- false /* suppressNoisyIntent */, musicDevice);
+ false /* suppressNoisyIntent */, musicDevice, -1 /* a2dpVolume */);
}
}
}
@@ -5442,6 +5450,9 @@
// address is not used for now, but may be used when multiple a2dp devices are supported
synchronized (mA2dpAvrcpLock) {
mAvrcpAbsVolSupported = support;
+ sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
+ mStreamStates[AudioSystem.STREAM_MUSIC], 0);
}
}
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.