summaryrefslogtreecommitdiff
path: root/core/java/android/os/CommonClock.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/os/CommonClock.java')
-rw-r--r--core/java/android/os/CommonClock.java405
1 files changed, 0 insertions, 405 deletions
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
deleted file mode 100644
index 2ecf317c2d09..000000000000
--- 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;
-}