下面列出了android.os.IBinder#unlinkToDeath ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void remove(IBinder binder) {
synchronized (mRecords) {
final int recordCount = mRecords.size();
for (int i = 0; i < recordCount; i++) {
Record r = mRecords.get(i);
if (r.binder == binder) {
if (DBG) {
log("remove: binder=" + binder + " r.callingPackage " + r.callingPackage
+ " r.callback " + r.callback);
}
if (r.deathRecipient != null) {
try {
binder.unlinkToDeath(r.deathRecipient, 0);
} catch (NoSuchElementException e) {
if (VDBG) log("UnlinkToDeath NoSuchElementException sending to r="
+ r + " e=" + e);
}
}
mRecords.remove(i);
return;
}
}
}
}
@Override
public void disconnect(IBinder binder) throws RemoteException {
if (!verifyCaller("disconnect")) throw new RemoteException("Not authorized");
if (connectedClients.containsKey(binder)) {
Answers.getInstance().logCustom(new CustomEvent("Connection Request Withdrawn")
.putCustomAttribute("Application", getCallerName()));
Log.d("SightService", "CLIENT DISCONNECTS FROM PUMP");
binder.unlinkToDeath(connectedClients.get(binder), 0);
connectedClients.remove(binder);
if (connectedClients.size() == 0 && connectionThread != null) {
disconnectTimer = new Timer();
disconnectTimer.schedule(new TimerTask() {
@Override
public void run() {
SightService.this.disconnect(false);
}
}, DISCONNECT_DELAY);
}
}
}
public boolean removeObserverLocked(IContentObserver observer) {
int size = mChildren.size();
for (int i = 0; i < size; i++) {
boolean empty = mChildren.get(i).removeObserverLocked(observer);
if (empty) {
mChildren.remove(i);
i--;
size--;
}
}
IBinder observerBinder = observer.asBinder();
size = mObservers.size();
for (int i = 0; i < size; i++) {
ObserverEntry entry = mObservers.get(i);
if (entry.observer.asBinder() == observerBinder) {
mObservers.remove(i);
// We no longer need to listen for death notifications. Remove it.
observerBinder.unlinkToDeath(entry, 0);
break;
}
}
if (mChildren.size() == 0 && mObservers.size() == 0) {
return true;
}
return false;
}
public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
if (device != null) {
device.destroyLocked(true);
appToken.unlinkToDeath(device, 0);
}
// Return the display device that was removed without actually sending the
// event indicating that it was removed. The caller will handle it.
return device;
}
public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
ClientDeathRecipient r = mBleApps.get(token);
if (r == null && enable) {
ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
try {
token.linkToDeath(deathRec, 0);
} catch (RemoteException ex) {
throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
}
mBleApps.put(token, deathRec);
if (DBG) {
Slog.d(TAG, "Registered for death of " + packageName);
}
} else if (!enable && r != null) {
// Unregister death recipient as the app goes away.
token.unlinkToDeath(r, 0);
mBleApps.remove(token);
if (DBG) {
Slog.d(TAG, "Unregistered for death of " + packageName);
}
}
int appCount = mBleApps.size();
if (DBG) {
Slog.d(TAG, appCount + " registered Ble Apps");
}
if (appCount == 0 && mEnable) {
disableBleScanMode();
}
if (appCount == 0 && !mEnableExternal) {
sendBrEdrDownCallback();
}
return appCount;
}
public boolean unpin(String pkg, IBinder token) {
synchronized (mLock) {
token.unlinkToDeath(mDeathRecipient, 0);
mListeners.remove(token);
}
return !hasPinOrListener();
}
public boolean removeObserverLocked(IContentObserver observer) {
int size = mChildren.size();
for (int i = 0; i < size; i++) {
boolean empty = mChildren.get(i).removeObserverLocked(observer);
if (empty) {
mChildren.remove(i);
i--;
size--;
}
}
IBinder observerBinder = observer.asBinder();
size = mObservers.size();
for (int i = 0; i < size; i++) {
ObserverEntry entry = mObservers.get(i);
if (entry.observer.asBinder() == observerBinder) {
mObservers.remove(i);
// We no longer need to listen for death notifications. Remove it.
observerBinder.unlinkToDeath(entry, 0);
break;
}
}
if (mChildren.size() == 0 && mObservers.size() == 0) {
return true;
}
return false;
}
private void unlinkDeathRecipientLocked(IMediaProjectionWatcherCallback callback) {
final IBinder token = callback.asBinder();
IBinder.DeathRecipient deathRecipient = mDeathEaters.remove(token);
if (deathRecipient != null) {
token.unlinkToDeath(deathRecipient, 0);
}
}
@Override
public void removeSessionTokensListener(ISessionTokensListener listener,
String packageName) throws RemoteException {
if (!USE_MEDIA2_APIS) {
return;
}
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
verifySessionsRequest2(UserHandle.getUserId(uid), packageName, pid, uid);
synchronized (mLock) {
IBinder listenerBinder = listener.asBinder();
for (SessionTokensListenerRecord record : mSessionTokensListeners) {
if (listenerBinder.equals(record.mListener.asBinder())) {
try {
listenerBinder.unlinkToDeath(record, 0);
} catch (NoSuchElementException e) {
}
mSessionTokensListeners.remove(record);
break;
}
}
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
public void removeListener(@NonNull TListener listener) {
Preconditions.checkNotNull(listener, "Attempted to remove a 'null' listener.");
IBinder binder = listener.asBinder();
LinkedListener linkedListener;
synchronized (mListenerMap) {
linkedListener = mListenerMap.remove(binder);
if (mListenerMap.isEmpty()) {
tryUnregister();
}
}
if (linkedListener != null) {
binder.unlinkToDeath(linkedListener, 0 /* flags */);
}
}
void release() {
final IBinder srcRef = mSourceRef;
final AudioFocusDeathHandler deathHdlr = mDeathHandler;
try {
if (srcRef != null && deathHdlr != null) {
srcRef.unlinkToDeath(deathHdlr, 0);
}
} catch (java.util.NoSuchElementException e) { }
mDeathHandler = null;
mFocusDispatcher = null;
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
*
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
*
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
private static void linkBinderDied(final IBinder binder) {
IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
binder.unlinkToDeath(this, 0);
}
};
try {
binder.linkToDeath(deathRecipient, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
*
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
*
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
*
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
/**
* Called when the client side {@link IBinder} for this {@link CustomTabsSessionToken} is dead.
* Can also be used to clean up {@link DeathRecipient} instances allocated for the given token.
*
* @param sessionToken The session token for which the {@link DeathRecipient} call has been
* received.
* @return Whether the clean up was successful. Multiple calls with two tokens holdings the
* same binder will return false.
*/
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
synchronized (mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient =
mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
mDeathRecipientMap.remove(binder);
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
final void completeRemoveProvider(IContentProvider provider) {
IBinder jBinder = provider.asBinder();
String remoteProviderName = null;
synchronized(mProviderMap) {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc == null) {
// Either no release is needed (so we shouldn't be here) or the
// provider was already released.
if (localLOGV) Slog.v(TAG, "completeRemoveProvider: release not needed");
return;
}
if (prc.count != 0) {
// There was a race! Some other client managed to acquire
// the provider before the removal was completed.
// Abort the removal. We will do it later.
if (localLOGV) Slog.v(TAG, "completeRemoveProvider: lost the race, "
+ "provider still in use");
return;
}
mProviderRefCountMap.remove(jBinder);
Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
while (iter.hasNext()) {
ProviderClientRecord pr = iter.next();
IBinder myBinder = pr.mProvider.asBinder();
if (myBinder == jBinder) {
iter.remove();
if (pr.mLocalProvider == null) {
myBinder.unlinkToDeath(pr, 0);
if (remoteProviderName == null) {
remoteProviderName = pr.mName;
}
}
}
}
}
if (remoteProviderName != null) {
try {
if (localLOGV) {
Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
+ "removeContentProvider(" + remoteProviderName + ")");
}
ActivityManagerNative.getDefault().removeContentProvider(
getApplicationThread(), remoteProviderName);
} catch (RemoteException e) {
//do nothing content provider object is dead any way
}
}
}