Loading services/core/java/com/android/server/attention/AttentionManagerService.java +57 −34 Original line number Original line Diff line number Diff line Loading @@ -104,8 +104,7 @@ public class AttentionManagerService extends SystemService { @Override @Override public void onSwitchUser(int userId) { public void onSwitchUser(int userId) { cancelAndUnbindLocked(peekUserStateLocked(userId), cancelAndUnbindLocked(peekUserStateLocked(userId)); AttentionService.ATTENTION_FAILURE_UNKNOWN); } } /** Resolves and sets up the attention service if it had not been done yet. */ /** Resolves and sets up the attention service if it had not been done yet. */ Loading Loading @@ -152,7 +151,8 @@ public class AttentionManagerService extends SystemService { } } synchronized (mLock) { synchronized (mLock) { unbindAfterTimeoutLocked(); final long now = SystemClock.uptimeMillis(); freeIfInactiveLocked(); final UserState userState = getOrCreateCurrentUserStateLocked(); final UserState userState = getOrCreateCurrentUserStateLocked(); // lazily start the service, which should be very lightweight to start // lazily start the service, which should be very lightweight to start Loading @@ -172,7 +172,7 @@ public class AttentionManagerService extends SystemService { try { try { // throttle frequent requests // throttle frequent requests final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache; final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache; if (attentionCheckCache != null && SystemClock.uptimeMillis() if (attentionCheckCache != null && now < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) { < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) { callback.onSuccess(requestCode, attentionCheckCache.mResult, callback.onSuccess(requestCode, attentionCheckCache.mResult, attentionCheckCache.mTimestamp); attentionCheckCache.mTimestamp); Loading @@ -190,6 +190,7 @@ public class AttentionManagerService extends SystemService { userState.mAttentionCheckCache = new AttentionCheckCache( userState.mAttentionCheckCache = new AttentionCheckCache( SystemClock.uptimeMillis(), result, SystemClock.uptimeMillis(), result, timestamp); timestamp); userState.mCurrentAttentionCheckIsFulfilled = true; } } StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, result); result); Loading @@ -198,6 +199,7 @@ public class AttentionManagerService extends SystemService { @Override @Override public void onFailure(int requestCode, int error) { public void onFailure(int requestCode, int error) { callback.onFailure(requestCode, error); callback.onFailure(requestCode, error); userState.mCurrentAttentionCheckIsFulfilled = true; StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, error); error); } } Loading @@ -214,7 +216,10 @@ public class AttentionManagerService extends SystemService { /** Cancels the specified attention check. */ /** Cancels the specified attention check. */ public void cancelAttentionCheck(int requestCode) { public void cancelAttentionCheck(int requestCode) { synchronized (mLock) { synchronized (mLock) { final UserState userState = getOrCreateCurrentUserStateLocked(); final UserState userState = peekCurrentUserStateLocked(); if (userState == null) { return; } if (userState.mService == null) { if (userState.mService == null) { if (userState.mPendingAttentionCheck != null if (userState.mPendingAttentionCheck != null && userState.mPendingAttentionCheck.mRequestCode == requestCode) { && userState.mPendingAttentionCheck.mRequestCode == requestCode) { Loading @@ -231,8 +236,12 @@ public class AttentionManagerService extends SystemService { } } @GuardedBy("mLock") @GuardedBy("mLock") private void unbindAfterTimeoutLocked() { private void freeIfInactiveLocked() { mAttentionHandler.sendEmptyMessageDelayed(AttentionHandler.CONNECTION_EXPIRED, // If we are called here, it means someone used the API again - reset the timer then. mAttentionHandler.removeMessages(AttentionHandler.CHECK_CONNECTION_EXPIRATION); // Schedule resources cleanup if no one calls the API again. mAttentionHandler.sendEmptyMessageDelayed(AttentionHandler.CHECK_CONNECTION_EXPIRATION, CONNECTION_TTL_MILLIS); CONNECTION_TTL_MILLIS); } } Loading @@ -259,12 +268,14 @@ public class AttentionManagerService extends SystemService { } } @GuardedBy("mLock") @GuardedBy("mLock") UserState peekCurrentUserStateLocked() { @Nullable private UserState peekCurrentUserStateLocked() { return peekUserStateLocked(ActivityManager.getCurrentUser()); return peekUserStateLocked(ActivityManager.getCurrentUser()); } } @GuardedBy("mLock") @GuardedBy("mLock") UserState peekUserStateLocked(int userId) { @Nullable private UserState peekUserStateLocked(int userId) { return mUserStates.get(userId); return mUserStates.get(userId); } } Loading Loading @@ -401,6 +412,8 @@ public class AttentionManagerService extends SystemService { @GuardedBy("mLock") @GuardedBy("mLock") int mCurrentAttentionCheckRequestCode; int mCurrentAttentionCheckRequestCode; @GuardedBy("mLock") @GuardedBy("mLock") boolean mCurrentAttentionCheckIsFulfilled; @GuardedBy("mLock") PendingAttentionCheck mPendingAttentionCheck; PendingAttentionCheck mPendingAttentionCheck; @GuardedBy("mLock") @GuardedBy("mLock") Loading Loading @@ -496,7 +509,7 @@ public class AttentionManagerService extends SystemService { } } private class AttentionHandler extends Handler { private class AttentionHandler extends Handler { private static final int CONNECTION_EXPIRED = 1; private static final int CHECK_CONNECTION_EXPIRATION = 1; private static final int ATTENTION_CHECK_TIMEOUT = 2; private static final int ATTENTION_CHECK_TIMEOUT = 2; AttentionHandler() { AttentionHandler() { Loading @@ -506,20 +519,27 @@ public class AttentionManagerService extends SystemService { public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { switch (msg.what) { // Do not occupy resources when not in use - unbind proactively. // Do not occupy resources when not in use - unbind proactively. case CONNECTION_EXPIRED: { case CHECK_CONNECTION_EXPIRATION: { for (int i = 0; i < mUserStates.size(); i++) { for (int i = 0; i < mUserStates.size(); i++) { cancelAndUnbindLocked(mUserStates.valueAt(i), cancelAndUnbindLocked(mUserStates.valueAt(i)); AttentionService.ATTENTION_FAILURE_UNKNOWN); } } } } break; break; // Callee is no longer interested in the attention check result - cancel. // Callee is no longer interested in the attention check result - cancel. case ATTENTION_CHECK_TIMEOUT: { case ATTENTION_CHECK_TIMEOUT: { cancelAndUnbindLocked(peekCurrentUserStateLocked(), synchronized (mLock) { final UserState userState = peekCurrentUserStateLocked(); if (userState != null) { // If not called back already. if (!userState.mCurrentAttentionCheckIsFulfilled) { cancel(userState, AttentionService.ATTENTION_FAILURE_TIMED_OUT); AttentionService.ATTENTION_FAILURE_TIMED_OUT); } } } } } break; break; default: default: Loading @@ -528,10 +548,7 @@ public class AttentionManagerService extends SystemService { } } } } @GuardedBy("mLock") private void cancel(UserState userState, @AttentionFailureCodes int failureCode) { private void cancelAndUnbindLocked(UserState userState, @AttentionFailureCodes int failureCode) { synchronized (mLock) { if (userState != null && userState.mService != null) { if (userState != null && userState.mService != null) { try { try { userState.mService.cancelAttentionCheck( userState.mService.cancelAttentionCheck( Loading @@ -543,12 +560,19 @@ public class AttentionManagerService extends SystemService { if (userState.mPendingAttentionCheck != null) { if (userState.mPendingAttentionCheck != null) { userState.mPendingAttentionCheck.cancel(failureCode); userState.mPendingAttentionCheck.cancel(failureCode); } } } } @GuardedBy("mLock") private void cancelAndUnbindLocked(UserState userState) { synchronized (mLock) { cancel(userState, AttentionService.ATTENTION_FAILURE_UNKNOWN); mContext.unbindService(userState.mConnection); mContext.unbindService(userState.mConnection); userState.mConnection.cleanupService(); userState.mConnection.cleanupService(); mUserStates.remove(userState.mUserId); mUserStates.remove(userState.mUserId); } } } } } /** /** * Unbinds and stops the service when the screen off intent is received. * Unbinds and stops the service when the screen off intent is received. Loading @@ -558,8 +582,7 @@ public class AttentionManagerService extends SystemService { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { cancelAndUnbindLocked(peekCurrentUserStateLocked(), cancelAndUnbindLocked(peekCurrentUserStateLocked()); AttentionService.ATTENTION_FAILURE_UNKNOWN); } } } } } } Loading Loading
services/core/java/com/android/server/attention/AttentionManagerService.java +57 −34 Original line number Original line Diff line number Diff line Loading @@ -104,8 +104,7 @@ public class AttentionManagerService extends SystemService { @Override @Override public void onSwitchUser(int userId) { public void onSwitchUser(int userId) { cancelAndUnbindLocked(peekUserStateLocked(userId), cancelAndUnbindLocked(peekUserStateLocked(userId)); AttentionService.ATTENTION_FAILURE_UNKNOWN); } } /** Resolves and sets up the attention service if it had not been done yet. */ /** Resolves and sets up the attention service if it had not been done yet. */ Loading Loading @@ -152,7 +151,8 @@ public class AttentionManagerService extends SystemService { } } synchronized (mLock) { synchronized (mLock) { unbindAfterTimeoutLocked(); final long now = SystemClock.uptimeMillis(); freeIfInactiveLocked(); final UserState userState = getOrCreateCurrentUserStateLocked(); final UserState userState = getOrCreateCurrentUserStateLocked(); // lazily start the service, which should be very lightweight to start // lazily start the service, which should be very lightweight to start Loading @@ -172,7 +172,7 @@ public class AttentionManagerService extends SystemService { try { try { // throttle frequent requests // throttle frequent requests final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache; final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache; if (attentionCheckCache != null && SystemClock.uptimeMillis() if (attentionCheckCache != null && now < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) { < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) { callback.onSuccess(requestCode, attentionCheckCache.mResult, callback.onSuccess(requestCode, attentionCheckCache.mResult, attentionCheckCache.mTimestamp); attentionCheckCache.mTimestamp); Loading @@ -190,6 +190,7 @@ public class AttentionManagerService extends SystemService { userState.mAttentionCheckCache = new AttentionCheckCache( userState.mAttentionCheckCache = new AttentionCheckCache( SystemClock.uptimeMillis(), result, SystemClock.uptimeMillis(), result, timestamp); timestamp); userState.mCurrentAttentionCheckIsFulfilled = true; } } StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, result); result); Loading @@ -198,6 +199,7 @@ public class AttentionManagerService extends SystemService { @Override @Override public void onFailure(int requestCode, int error) { public void onFailure(int requestCode, int error) { callback.onFailure(requestCode, error); callback.onFailure(requestCode, error); userState.mCurrentAttentionCheckIsFulfilled = true; StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED, error); error); } } Loading @@ -214,7 +216,10 @@ public class AttentionManagerService extends SystemService { /** Cancels the specified attention check. */ /** Cancels the specified attention check. */ public void cancelAttentionCheck(int requestCode) { public void cancelAttentionCheck(int requestCode) { synchronized (mLock) { synchronized (mLock) { final UserState userState = getOrCreateCurrentUserStateLocked(); final UserState userState = peekCurrentUserStateLocked(); if (userState == null) { return; } if (userState.mService == null) { if (userState.mService == null) { if (userState.mPendingAttentionCheck != null if (userState.mPendingAttentionCheck != null && userState.mPendingAttentionCheck.mRequestCode == requestCode) { && userState.mPendingAttentionCheck.mRequestCode == requestCode) { Loading @@ -231,8 +236,12 @@ public class AttentionManagerService extends SystemService { } } @GuardedBy("mLock") @GuardedBy("mLock") private void unbindAfterTimeoutLocked() { private void freeIfInactiveLocked() { mAttentionHandler.sendEmptyMessageDelayed(AttentionHandler.CONNECTION_EXPIRED, // If we are called here, it means someone used the API again - reset the timer then. mAttentionHandler.removeMessages(AttentionHandler.CHECK_CONNECTION_EXPIRATION); // Schedule resources cleanup if no one calls the API again. mAttentionHandler.sendEmptyMessageDelayed(AttentionHandler.CHECK_CONNECTION_EXPIRATION, CONNECTION_TTL_MILLIS); CONNECTION_TTL_MILLIS); } } Loading @@ -259,12 +268,14 @@ public class AttentionManagerService extends SystemService { } } @GuardedBy("mLock") @GuardedBy("mLock") UserState peekCurrentUserStateLocked() { @Nullable private UserState peekCurrentUserStateLocked() { return peekUserStateLocked(ActivityManager.getCurrentUser()); return peekUserStateLocked(ActivityManager.getCurrentUser()); } } @GuardedBy("mLock") @GuardedBy("mLock") UserState peekUserStateLocked(int userId) { @Nullable private UserState peekUserStateLocked(int userId) { return mUserStates.get(userId); return mUserStates.get(userId); } } Loading Loading @@ -401,6 +412,8 @@ public class AttentionManagerService extends SystemService { @GuardedBy("mLock") @GuardedBy("mLock") int mCurrentAttentionCheckRequestCode; int mCurrentAttentionCheckRequestCode; @GuardedBy("mLock") @GuardedBy("mLock") boolean mCurrentAttentionCheckIsFulfilled; @GuardedBy("mLock") PendingAttentionCheck mPendingAttentionCheck; PendingAttentionCheck mPendingAttentionCheck; @GuardedBy("mLock") @GuardedBy("mLock") Loading Loading @@ -496,7 +509,7 @@ public class AttentionManagerService extends SystemService { } } private class AttentionHandler extends Handler { private class AttentionHandler extends Handler { private static final int CONNECTION_EXPIRED = 1; private static final int CHECK_CONNECTION_EXPIRATION = 1; private static final int ATTENTION_CHECK_TIMEOUT = 2; private static final int ATTENTION_CHECK_TIMEOUT = 2; AttentionHandler() { AttentionHandler() { Loading @@ -506,20 +519,27 @@ public class AttentionManagerService extends SystemService { public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { switch (msg.what) { // Do not occupy resources when not in use - unbind proactively. // Do not occupy resources when not in use - unbind proactively. case CONNECTION_EXPIRED: { case CHECK_CONNECTION_EXPIRATION: { for (int i = 0; i < mUserStates.size(); i++) { for (int i = 0; i < mUserStates.size(); i++) { cancelAndUnbindLocked(mUserStates.valueAt(i), cancelAndUnbindLocked(mUserStates.valueAt(i)); AttentionService.ATTENTION_FAILURE_UNKNOWN); } } } } break; break; // Callee is no longer interested in the attention check result - cancel. // Callee is no longer interested in the attention check result - cancel. case ATTENTION_CHECK_TIMEOUT: { case ATTENTION_CHECK_TIMEOUT: { cancelAndUnbindLocked(peekCurrentUserStateLocked(), synchronized (mLock) { final UserState userState = peekCurrentUserStateLocked(); if (userState != null) { // If not called back already. if (!userState.mCurrentAttentionCheckIsFulfilled) { cancel(userState, AttentionService.ATTENTION_FAILURE_TIMED_OUT); AttentionService.ATTENTION_FAILURE_TIMED_OUT); } } } } } break; break; default: default: Loading @@ -528,10 +548,7 @@ public class AttentionManagerService extends SystemService { } } } } @GuardedBy("mLock") private void cancel(UserState userState, @AttentionFailureCodes int failureCode) { private void cancelAndUnbindLocked(UserState userState, @AttentionFailureCodes int failureCode) { synchronized (mLock) { if (userState != null && userState.mService != null) { if (userState != null && userState.mService != null) { try { try { userState.mService.cancelAttentionCheck( userState.mService.cancelAttentionCheck( Loading @@ -543,12 +560,19 @@ public class AttentionManagerService extends SystemService { if (userState.mPendingAttentionCheck != null) { if (userState.mPendingAttentionCheck != null) { userState.mPendingAttentionCheck.cancel(failureCode); userState.mPendingAttentionCheck.cancel(failureCode); } } } } @GuardedBy("mLock") private void cancelAndUnbindLocked(UserState userState) { synchronized (mLock) { cancel(userState, AttentionService.ATTENTION_FAILURE_UNKNOWN); mContext.unbindService(userState.mConnection); mContext.unbindService(userState.mConnection); userState.mConnection.cleanupService(); userState.mConnection.cleanupService(); mUserStates.remove(userState.mUserId); mUserStates.remove(userState.mUserId); } } } } } /** /** * Unbinds and stops the service when the screen off intent is received. * Unbinds and stops the service when the screen off intent is received. Loading @@ -558,8 +582,7 @@ public class AttentionManagerService extends SystemService { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { cancelAndUnbindLocked(peekCurrentUserStateLocked(), cancelAndUnbindLocked(peekCurrentUserStateLocked()); AttentionService.ATTENTION_FAILURE_UNKNOWN); } } } } } } Loading