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 java.util.List; 26fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 27fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn/** 28fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Helper for monitoring the current importance of applications. 29fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * @hide 30fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn */ 31fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackbornpublic class AppImportanceMonitor { 32fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final Context mContext; 33fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 34fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final SparseArray<AppEntry> mApps = new SparseArray<>(); 35fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 36fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn static class AppEntry { 37fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final int uid; 38fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final SparseArray<Integer> procs = new SparseArray<>(1); 39fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 40fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 41fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn AppEntry(int _uid) { 42fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn uid = _uid; 43fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 44fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 45fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 46fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 47fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 48fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 49fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 50fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 51fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 52fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onProcessStateChanged(int pid, int uid, int procState) { 53fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn synchronized (mApps) { 54fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(pid, uid, 55fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager.RunningAppProcessInfo.procStateToImportance(procState), 56fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn true); 57fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 58fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 59fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 60fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 61fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onProcessDied(int pid, int uid) { 62fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn synchronized (mApps) { 63fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(pid, uid, 64fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, true); 65fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 66fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 67fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn }; 68fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 69fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn static final int MSG_UPDATE = 1; 70fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 71fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn final Handler mHandler; 72fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 73fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public AppImportanceMonitor(Context context, Looper looper) { 74fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mContext = context; 75fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mHandler = new Handler(looper) { 76fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn @Override 77fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void handleMessage(Message msg) { 78fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn switch (msg.what) { 79fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn case MSG_UPDATE: 80fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn onImportanceChanged(msg.arg1, msg.arg2&0xffff, msg.arg2>>16); 81fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn break; 82fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn default: 83fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn super.handleMessage(msg); 84fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 85fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 86fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn }; 87fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); 88fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn try { 89fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManagerNative.getDefault().registerProcessObserver(mProcessObserver); 90fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } catch (RemoteException e) { 91fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 92fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn List<ActivityManager.RunningAppProcessInfo> apps = am.getRunningAppProcesses(); 93fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (apps != null) { 94fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn for (int i=0; i<apps.size(); i++) { 95fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ActivityManager.RunningAppProcessInfo app = apps.get(i); 96fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(app.uid, app.pid, app.importance, false); 97fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 98fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 99fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 100fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 101fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public int getImportance(int uid) { 102fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn AppEntry ent = mApps.get(uid); 103fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (ent == null) { 104fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn return ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 105fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 106fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn return ent.importance; 107fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 108fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 109fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn /** 110fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn * Report when an app's importance changed. Called on looper given to constructor. 111fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn */ 112fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public void onImportanceChanged(int uid, int importance, int oldImportance) { 113fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 114fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 115fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn void updateImportanceLocked(int uid, int pid, int importance, boolean repChange) { 116fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn AppEntry ent = mApps.get(uid); 117fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (ent == null) { 118fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent = new AppEntry(uid); 119fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mApps.put(uid, ent); 120fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 121fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (importance >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE) { 122fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent.procs.remove(pid); 123fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } else { 124fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent.procs.put(pid, importance); 125fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 126fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn updateImportanceLocked(ent, repChange); 127fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 128fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 129fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn void updateImportanceLocked(AppEntry ent, boolean repChange) { 130fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int appImp = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 131fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn for (int i=0; i<ent.procs.size(); i++) { 132fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int procImp = ent.procs.valueAt(i); 133fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (procImp < appImp) { 134fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn appImp = procImp; 135fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 136fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 137fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (appImp != ent.importance) { 138fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn int impCode = appImp | (ent.importance<<16); 139fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn ent.importance = appImp; 140fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (appImp >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE) { 141fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mApps.remove(ent.uid); 142fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 143fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (repChange) { 144fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mHandler.obtainMessage(MSG_UPDATE, ent.uid, impCode).sendToTarget(); 145fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 146fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 147fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn } 148fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn} 149