ForegroundUtils.java revision da772582c17e3f5ffe36e4cab3e1ede3cba32060
138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri/* 238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * Copyright (C) 2014 The Android Open Source Project 338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * 438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * Licensed under the Apache License, Version 2.0 (the "License"); 538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * you may not use this file except in compliance with the License. 638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * You may obtain a copy of the License at 738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * 838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * http://www.apache.org/licenses/LICENSE-2.0 938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * 1038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * Unless required by applicable law or agreed to in writing, software 1138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * distributed under the License is distributed on an "AS IS" BASIS, 1238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * See the License for the specific language governing permissions and 1438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * limitations under the License. 1538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri */ 1638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieripackage com.android.nfc; 1738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 1838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport java.util.ArrayList; 1938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport java.util.List; 2038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 2138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport android.app.ActivityManagerNative; 2238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport android.app.IActivityManager; 2338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport android.app.IProcessObserver; 2438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport android.os.RemoteException; 2538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport android.util.Log; 2638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieriimport android.util.SparseArray; 2738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 2838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieripublic class ForegroundUtils extends IProcessObserver.Stub { 2938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private final String TAG = "ForegroundUtils"; 3038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private final IActivityManager mIActivityManager; 3138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 3238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private final Object mLock = new Object(); 3338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private final SparseArray<Boolean> mForegroundUids = new SparseArray<Boolean>(1); 3438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private final SparseArray<List<Callback>> mBackgroundCallbacks = 3538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri new SparseArray<List<Callback>>(); 3638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 3738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private static class Singleton { 3838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private static final ForegroundUtils INSTANCE = new ForegroundUtils(); 3938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 4038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 4138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri private ForegroundUtils() { 4238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri mIActivityManager = ActivityManagerNative.getDefault(); 4338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri try { 4438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri mIActivityManager.registerProcessObserver(this); 4538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } catch (RemoteException e) { 4638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri // Should not happen! 4738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri Log.e(TAG, "ForegroundUtils: could not get IActivityManager"); 4838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 4938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 5038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 5138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public interface Callback { 5238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri void onUidToBackground(int uid); 5338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 5438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 5538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public static ForegroundUtils getInstance() { 5638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri return Singleton.INSTANCE; 5738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 5838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 5938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri /** 6038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * Checks whether the specified UID has any activities running in the foreground, 61f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri * and if it does, registers a callback for when that UID no longer has any foreground 6238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * activities. This is done atomically, so callers can be ensured that they will 6338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * get a callback if this method returns true. 64f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri * 6538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * @param callback Callback to be called 6638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * @param uid The UID to be checked 6738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * @return true when the UID has an Activity in the foreground and the callback 6838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * , false otherwise 6938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri */ 7038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public boolean registerUidToBackgroundCallback(Callback callback, int uid) { 71f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri synchronized (mLock) { 7238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri if (!isInForegroundLocked(uid)) { 7338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri return false; 7438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 7538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri // This uid is in the foreground; register callback for when it moves 7638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri // into the background. 7738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri List<Callback> callbacks = mBackgroundCallbacks.get(uid); 7838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri if (callbacks == null) { 7938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri callbacks = new ArrayList<Callback>(); 8038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri mBackgroundCallbacks.put(uid, callbacks); 81f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 82f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri callbacks.add(callback); 8338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri return true; 8438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 8538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 8638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 8738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri /** 88f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri * @param uid The UID to be checked 8938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri * @return whether the UID has any activities running in the foreground 9038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri */ 9138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public boolean isInForeground(int uid) { 9238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri synchronized (mLock) { 9338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri return isInForegroundLocked(uid); 9438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 9538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 9638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 97f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri boolean isInForegroundLocked(int uid) { 98f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri Boolean inForeground = mForegroundUids.get(uid); 99f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri return inForeground != null ? inForeground.booleanValue() : false; 100f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 101f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri 102f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri void handleUidToBackground(int uid) { 103f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri ArrayList<Callback> pendingCallbacks = null; 104f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri synchronized (mLock) { 105f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri List<Callback> callbacks = mBackgroundCallbacks.get(uid); 106f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri if (callbacks != null) { 107f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri pendingCallbacks = new ArrayList<Callback>(callbacks); 108f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri // Only call them once 109f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri mBackgroundCallbacks.remove(uid); 110f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 111f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 112f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri // Release lock for callbacks 113f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri if (pendingCallbacks != null) { 114f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri for (Callback callback : pendingCallbacks) { 115f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri callback.onUidToBackground(uid); 11638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 11738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 11838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 11938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 12038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri @Override 12138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public void onForegroundActivitiesChanged(int pid, int uid, 12238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri boolean foregroundActivities) throws RemoteException { 12338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri synchronized (mLock) { 12438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri mForegroundUids.put(uid, foregroundActivities); 12538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 12638da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri if (!foregroundActivities) { 12738da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri handleUidToBackground(uid); 12838da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri } 129f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 13038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 131f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri 132f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri @Override 13338da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public void onProcessDied(int pid, int uid) throws RemoteException { 13438da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri synchronized (mLock) { 13538da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri mForegroundUids.remove(uid); 136f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 137f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri handleUidToBackground(uid); 138f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 13938da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri 14038da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri @Override 14138da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri public void onProcessStateChanged(int pid, int uid, int procState) 14238da5c9cb636387539daaf5688c2a3badee32447Luca Barbieri throws RemoteException { 143f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri // Don't care 144f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri } 145f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri} 146f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri