1fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn/* 2fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Copyright (C) 2014 The Android Open Source Project 3fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * 4fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * you may not use this file except in compliance with the License. 6fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * You may obtain a copy of the License at 7fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * 8fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * 10fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * See the License for the specific language governing permissions and 14fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * limitations under the License. 15fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn */ 16fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 17fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornpackage android.app; 18fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 19fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.content.Context; 20fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.os.Handler; 21fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.os.Looper; 22fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.os.Message; 23fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.os.RemoteException; 24fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.util.SparseArray; 25fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport android.util.SparseIntArray; 26fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 27fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornimport java.util.List; 28fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 29fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn/** 30fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Helper for monitoring the current importance of applications. 31fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * @hide 32fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn */ 33fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornpublic class AppImportanceMonitor { 34fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final Context mContext; 35fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 36fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final SparseArray<AppEntry> mApps = new SparseArray<>(); 37fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 38fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn static class AppEntry { 39fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final int uid; 40fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final SparseArray<Integer> procs = new SparseArray<>(1); 41fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 42fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 43fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn AppEntry(int _uid) { 44fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn uid = _uid; 45fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 46fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 47fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 48fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 49fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 50fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 51fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 52fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 53fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 54fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onProcessStateChanged(int pid, int uid, int procState) { 55fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn synchronized (mApps) { 56fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(pid, uid, 57fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager.RunningAppProcessInfo.procStateToImportance(procState), 58fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn true); 59fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 60fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 61fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 62fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 63fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onProcessDied(int pid, int uid) { 64fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn synchronized (mApps) { 65fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(pid, uid, 66fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, true); 67fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 68fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 69fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn }; 70fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 71fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn static final int MSG_UPDATE = 1; 72fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 73fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final Handler mHandler; 74fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 75fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public AppImportanceMonitor(Context context, Looper looper) { 76fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mContext = context; 77fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mHandler = new Handler(looper) { 78fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 79fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void handleMessage(Message msg) { 80fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn switch (msg.what) { 81fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn case MSG_UPDATE: 82fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn onImportanceChanged(msg.arg1, msg.arg2&0xffff, msg.arg2>>16); 83fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn break; 84fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn default: 85fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn super.handleMessage(msg); 86fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 87fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 88fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn }; 89fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); 90fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn try { 91fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManagerNative.getDefault().registerProcessObserver(mProcessObserver); 92fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } catch (RemoteException e) { 93fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 94fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn List<ActivityManager.RunningAppProcessInfo> apps = am.getRunningAppProcesses(); 95fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (apps != null) { 96fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn for (int i=0; i<apps.size(); i++) { 97fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager.RunningAppProcessInfo app = apps.get(i); 98fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(app.uid, app.pid, app.importance, false); 99fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 100fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 101fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 102fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 103fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public int getImportance(int uid) { 104fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn AppEntry ent = mApps.get(uid); 105fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (ent == null) { 106fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn return ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 107fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 108fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn return ent.importance; 109fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 110fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 111fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn /** 112fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Report when an app's importance changed. Called on looper given to constructor. 113fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn */ 114fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onImportanceChanged(int uid, int importance, int oldImportance) { 115fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 116fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 117fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn void updateImportanceLocked(int uid, int pid, int importance, boolean repChange) { 118fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn AppEntry ent = mApps.get(uid); 119fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (ent == null) { 120fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent = new AppEntry(uid); 121fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mApps.put(uid, ent); 122fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 123fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (importance >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE) { 124fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent.procs.remove(pid); 125fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } else { 126fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent.procs.put(pid, importance); 127fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 128fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(ent, repChange); 129fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 130fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 131fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn void updateImportanceLocked(AppEntry ent, boolean repChange) { 132fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int appImp = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 133fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn for (int i=0; i<ent.procs.size(); i++) { 134fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int procImp = ent.procs.valueAt(i); 135fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (procImp < appImp) { 136fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn appImp = procImp; 137fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 138fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 139fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (appImp != ent.importance) { 140fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int impCode = appImp | (ent.importance<<16); 141fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent.importance = appImp; 142fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (appImp >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE) { 143fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mApps.remove(ent.uid); 144fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 145fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (repChange) { 146fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mHandler.obtainMessage(MSG_UPDATE, ent.uid, impCode).sendToTarget(); 147fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 148fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 149fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 150fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn} 151