summaryrefslogtreecommitdiffstats
path: root/services/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com')
-rw-r--r--services/java/com/android/server/am/ActiveServices.java2
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java98
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java2
-rw-r--r--services/java/com/android/server/am/BroadcastQueue.java2
-rw-r--r--services/java/com/android/server/am/CompatModePackages.java2
-rw-r--r--services/java/com/android/server/am/ProcessList.java2
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java39
-rw-r--r--services/java/com/android/server/am/ProcessTracker.java235
-rw-r--r--services/java/com/android/server/wm/DisplayContent.java6
-rw-r--r--services/java/com/android/server/wm/PointerEventDispatcher.java90
-rw-r--r--services/java/com/android/server/wm/StackTapDetector.java104
-rw-r--r--services/java/com/android/server/wm/StackTapPointerEventListener.java87
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java34
13 files changed, 501 insertions, 202 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index a5d64b2..912c465 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -1015,7 +1015,7 @@ public final class ActiveServices {
Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
if (app != null && app.thread != null) {
try {
- app.addPackage(r.appInfo.packageName);
+ app.addPackage(r.appInfo.packageName, mAm.mProcessTracker);
realStartServiceLocked(r, app);
return null;
} catch (RemoteException e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 38fe5e6..2124095 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -817,10 +817,10 @@ public final class ActivityManagerService extends ActivityManagerNative
int mNumNonCachedProcs = 0;
/**
- * Keep track of the number of cached procs, to balance oom adj
+ * Keep track of the number of cached hidden procs, to balance oom adj
* distribution between those and empty procs.
*/
- int mNumCachedProcs = 0;
+ int mNumCachedHiddenProcs = 0;
/**
* Keep track of the number of service processes we last found, to
@@ -2151,7 +2151,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// come up (we have a pid but not yet its thread), so keep it.
if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
// If this is a new package in the process, add the package to the list
- app.addPackage(info.packageName);
+ app.addPackage(info.packageName, mProcessTracker);
return app;
}
@@ -2206,7 +2206,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
} else {
// If this is a new package in the process, add the package to the list
- app.addPackage(info.packageName);
+ app.addPackage(info.packageName, mProcessTracker);
}
// If the system is not ready yet, then hold off on starting this
@@ -3039,10 +3039,8 @@ public final class ActivityManagerService extends ActivityManagerNative
proc = p;
break;
}
- for (String str : p.pkgList) {
- if (str.equals(packageName)) {
- proc = p;
- }
+ if (p.pkgList.containsKey(packageName)) {
+ proc = p;
}
}
}
@@ -4014,7 +4012,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (userId != UserHandle.USER_ALL && app.userId != userId) {
continue;
}
- if (!app.pkgList.contains(packageName)) {
+ if (!app.pkgList.containsKey(packageName)) {
continue;
}
}
@@ -6220,7 +6218,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (proc.userId != tr.userId) {
continue;
}
- if (!proc.pkgList.contains(pkg)) {
+ if (!proc.pkgList.containsKey(pkg)) {
continue;
}
procs.add(proc);
@@ -6577,7 +6575,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_MU)
Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
app.pubProviders.put(cpi.name, cpr);
- app.addPackage(cpi.applicationInfo.packageName);
+ app.addPackage(cpi.applicationInfo.packageName, mProcessTracker);
ensurePackageDexOpt(cpi.applicationInfo.packageName);
}
}
@@ -7316,7 +7314,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ps = stats.getProcessStatsLocked(info.uid, proc);
}
return new ProcessRecord(ps, thread, info, proc, uid,
- mProcessTracker.getStateLocked(info.processName, info.uid));
+ mProcessTracker.getProcessStateLocked(info.packageName, uid, proc));
}
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
@@ -8895,7 +8893,8 @@ public final class ActivityManagerService extends ActivityManagerNative
int flags = process.info.flags;
IPackageManager pm = AppGlobals.getPackageManager();
sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
- for (String pkg : process.pkgList) {
+ for (int ip=0; ip<process.pkgList.size(); ip++) {
+ String pkg = process.pkgList.keyAt(ip);
sb.append("Package: ").append(pkg);
try {
PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
@@ -9630,7 +9629,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final int NA = procs.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord r = procs.valueAt(ia);
- if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
+ if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
if (!needSep) {
@@ -9653,7 +9652,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean printed = false;
for (int i=0; i<mIsolatedProcesses.size(); i++) {
ProcessRecord r = mIsolatedProcesses.valueAt(i);
- if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
+ if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
if (!printed) {
@@ -9685,7 +9684,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean printed = false;
for (int i=0; i<mPidsSelfLocked.size(); i++) {
ProcessRecord r = mPidsSelfLocked.valueAt(i);
- if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
+ if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
if (!printed) {
@@ -9708,7 +9707,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ProcessRecord r = mPidsSelfLocked.get(
mForegroundProcesses.valueAt(i).pid);
if (dumpPackage != null && (r == null
- || !r.pkgList.contains(dumpPackage))) {
+ || !r.pkgList.containsKey(dumpPackage))) {
continue;
}
if (!printed) {
@@ -9766,7 +9765,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int puid = uids.keyAt(i);
ProcessRecord r = mProcessNames.get(pname, puid);
if (dumpPackage != null && (r == null
- || !r.pkgList.contains(dumpPackage))) {
+ || !r.pkgList.containsKey(dumpPackage))) {
continue;
}
if (!printed) {
@@ -9797,7 +9796,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int puid = uids.keyAt(i);
ProcessRecord r = mProcessNames.get(pname, puid);
if (dumpPackage != null && (r == null
- || !r.pkgList.contains(dumpPackage))) {
+ || !r.pkgList.containsKey(dumpPackage))) {
continue;
}
if (!printed) {
@@ -9840,7 +9839,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
if (mHomeProcess != null && (dumpPackage == null
- || mHomeProcess.pkgList.contains(dumpPackage))) {
+ || mHomeProcess.pkgList.containsKey(dumpPackage))) {
if (needSep) {
pw.println();
needSep = false;
@@ -9848,7 +9847,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" mHomeProcess: " + mHomeProcess);
}
if (mPreviousProcess != null && (dumpPackage == null
- || mPreviousProcess.pkgList.contains(dumpPackage))) {
+ || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
if (needSep) {
pw.println();
needSep = false;
@@ -9862,7 +9861,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(sb);
}
if (mHeavyWeightProcess != null && (dumpPackage == null
- || mHeavyWeightProcess.pkgList.contains(dumpPackage))) {
+ || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
if (needSep) {
pw.println();
needSep = false;
@@ -9959,7 +9958,8 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
- + " mNumCachedProcs=" + mNumCachedProcs
+ + " (" + mLruProcesses.size() + " total)"
+ + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
+ " mNumServiceProcs=" + mNumServiceProcs
+ " mNewNumServiceProcs=" + mNewNumServiceProcs);
}
@@ -10463,7 +10463,7 @@ public final class ActivityManagerService extends ActivityManagerNative
= new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
for (int i=0; i<origList.size(); i++) {
ProcessRecord r = origList.get(i);
- if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
+ if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
@@ -11079,7 +11079,6 @@ public final class ActivityManagerService extends ActivityManagerNative
final void dumpProcessTracker(FileDescriptor fd, PrintWriter pw, String[] args) {
synchronized (this) {
- pw.println("Process Stats:");
mProcessTracker.dumpLocked(fd, pw, args);
}
}
@@ -11787,7 +11786,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ ") when registering receiver " + receiver);
}
if (callerApp.info.uid != Process.SYSTEM_UID &&
- !callerApp.pkgList.contains(callerPackage)) {
+ !callerApp.pkgList.containsKey(callerPackage)) {
throw new SecurityException("Given caller package " + callerPackage
+ " is not running in process " + callerApp);
}
@@ -13899,7 +13898,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
- int clientCachedAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
+ int clientCachedAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll, long now) {
app.cachedAdj = cachedAdj;
app.clientCachedAdj = clientCachedAdj;
app.emptyAdj = emptyAdj;
@@ -13936,9 +13935,10 @@ public final class ActivityManagerService extends ActivityManagerNative
TAG, "Set " + app.pid + " " + app.processName +
" adj " + app.curAdj + ": " + app.adjType);
app.setAdj = app.curAdj;
- if (app.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
- app.tracker.setState(mProcessList.adjToTrackedState(app.setAdj),
- SystemClock.uptimeMillis());
+ app.setAdjChanged = true;
+ if (!doingAll) {
+ app.setProcessTrackerState(TOP_APP, mProcessTracker.getMemFactor(),
+ now, mProcessList);
}
} else {
success = false;
@@ -13997,7 +13997,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mAdjSeq++;
boolean success = updateOomAdjLocked(app, app.cachedAdj, app.clientCachedAdj,
- app.emptyAdj, TOP_APP, false);
+ app.emptyAdj, TOP_APP, false, SystemClock.uptimeMillis());
final boolean nowCached = app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ
&& app.curAdj <= ProcessList.CACHED_APP_MAX_ADJ;
if (nowCached != wasCached) {
@@ -14011,7 +14011,8 @@ public final class ActivityManagerService extends ActivityManagerNative
final void updateOomAdjLocked() {
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
- final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
+ final long now = SystemClock.uptimeMillis();
+ final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
if (false) {
RuntimeException e = new RuntimeException();
@@ -14040,7 +14041,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// them.
int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
- ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
- int numEmptyProcs = mLruProcesses.size()- mNumNonCachedProcs - mNumCachedProcs;
+ int numEmptyProcs = mLruProcesses.size()- mNumNonCachedProcs - mNumCachedHiddenProcs;
if (numEmptyProcs > cachedProcessLimit) {
// If there are more empty processes than our limit on cached
// processes, then use the cached process limit for the factor.
@@ -14052,7 +14053,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
int emptyFactor = numEmptyProcs/numSlots;
if (emptyFactor < 1) emptyFactor = 1;
- int cachedFactor = (mNumCachedProcs > 0 ? mNumCachedProcs : 1)/numSlots;
+ int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
if (cachedFactor < 1) cachedFactor = 1;
int stepCached = 0;
int stepEmpty = 0;
@@ -14061,7 +14062,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int numTrimming = 0;
mNumNonCachedProcs = 0;
- mNumCachedProcs = 0;
+ mNumCachedHiddenProcs = 0;
// First update the OOM adjustment for each of the
// application processes based on their current state.
@@ -14071,16 +14072,20 @@ public final class ActivityManagerService extends ActivityManagerNative
int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
int curClientCachedAdj = curEmptyAdj;
+ boolean changed = false;
while (i > 0) {
i--;
ProcessRecord app = mLruProcesses.get(i);
//Slog.i(TAG, "OOM " + app + ": cur cached=" + curCachedAdj);
- updateOomAdjLocked(app, curCachedAdj, curClientCachedAdj, curEmptyAdj, TOP_APP, true);
+ app.setAdjChanged = false;
+ updateOomAdjLocked(app, curCachedAdj, curClientCachedAdj, curEmptyAdj, TOP_APP,
+ true, now);
+ changed |= app.setAdjChanged;
if (!app.killedBackground) {
if (app.curRawAdj == curCachedAdj && app.hasActivities) {
// This process was assigned as a cached process... step the
// cached level.
- mNumCachedProcs++;
+ mNumCachedHiddenProcs++;
if (curCachedAdj != nextCachedAdj) {
stepCached++;
if (stepCached >= cachedFactor) {
@@ -14188,6 +14193,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// are managing to keep around is less than half the maximum we desire;
// if we are keeping a good number around, we'll let them use whatever
// memory they want.
+ int memFactor = ProcessTracker.STATE_MEM_FACTOR_NORMAL_ADJ;
if (numCached <= ProcessList.TRIM_CACHED_APPS
&& numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
final int numCachedAndEmpty = numCached + numEmpty;
@@ -14201,10 +14207,13 @@ public final class ActivityManagerService extends ActivityManagerNative
int fgTrimLevel;
if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
+ memFactor = ProcessTracker.STATE_MEM_FACTOR_CRITIAL_ADJ;
} else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+ memFactor = ProcessTracker.STATE_MEM_FACTOR_LOW_ADJ;
} else {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+ memFactor = ProcessTracker.STATE_MEM_FACTOR_MODERATE_ADJ;
}
int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
for (i=0; i<N; i++) {
@@ -14303,6 +14312,21 @@ public final class ActivityManagerService extends ActivityManagerNative
// be in a consistent state at this point.
mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
}
+
+ boolean allChanged = mProcessTracker.setMemFactor(memFactor, !mSleeping, now);
+ if (changed || allChanged) {
+ memFactor = mProcessTracker.getMemFactor();
+ for (i=mLruProcesses.size()-1; i>=0; i--) {
+ ProcessRecord app = mLruProcesses.get(i);
+ if (allChanged || app.setAdjChanged) {
+ app.setProcessTrackerState(TOP_APP, memFactor, now, mProcessList);
+ }
+ }
+ }
+
+ if (DEBUG_OOM_ADJ) {
+ Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
+ }
}
final void trimApplications() {
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 6fe28f4..ba8de39 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -987,7 +987,7 @@ public final class ActivityStackSupervisor {
if (app != null && app.thread != null) {
try {
- app.addPackage(r.info.packageName);
+ app.addPackage(r.info.packageName, mService.mProcessTracker);
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index c7e6010..0e7513c 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -795,7 +795,7 @@ public final class BroadcastQueue {
info.activityInfo.applicationInfo.uid);
if (app != null && app.thread != null) {
try {
- app.addPackage(info.activityInfo.packageName);
+ app.addPackage(info.activityInfo.packageName, mService.mProcessTracker);
processCurBroadcastLocked(r, app);
return;
} catch (RemoteException e) {
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index f56371c..59e6787 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -300,7 +300,7 @@ public final class CompatModePackages {
// Tell all processes that loaded this package about the change.
for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
ProcessRecord app = mService.mLruProcesses.get(i);
- if (!app.pkgList.contains(packageName)) {
+ if (!app.pkgList.containsKey(packageName)) {
continue;
}
try {
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index e937d35..b5d783d 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -244,7 +244,7 @@ final class ProcessList {
}
int adjToTrackedState(int adj) {
- return mAdjToTrackedState[adj];
+ return adj >= FOREGROUND_APP_ADJ ? mAdjToTrackedState[adj] : ProcessTracker.STATE_NOTHING;
}
private void writeFile(String path, String data) {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 6cae67c..cc0a5a3 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -51,9 +51,10 @@ final class ProcessRecord {
final int uid; // uid of process; may be different from 'info' if isolated
final int userId; // user of process.
final String processName; // name of the process
- final ProcessTracker.ProcessState tracker; // tracking execution of process
+ final ProcessTracker.ProcessState baseProcessTracker;
// List of packages running in the process
- final HashSet<String> pkgList = new HashSet<String>();
+ final ArrayMap<String, ProcessTracker.ProcessState> pkgList
+ = new ArrayMap<String, ProcessTracker.ProcessState>();
IApplicationThread thread; // the actual proc... may be null only if
// 'persistent' is true (in which case we
// are in the process of launching the app)
@@ -87,6 +88,7 @@ final class ProcessRecord {
boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower
boolean bad; // True if disabled in the bad process list
boolean killedBackground; // True when proc has been killed due to too many bg
+ boolean setAdjChanged; // Keep track of whether we changed 'setAdj'.
String waitingToKill; // Process is waiting to be killed when in the bg; reason
IBinder forcingToForeground;// Token that is forcing this process to be foreground
int adjSeq; // Sequence id for identifying oom_adj assignment cycles
@@ -327,15 +329,15 @@ final class ProcessRecord {
ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
ApplicationInfo _info, String _processName, int _uid,
- ProcessTracker.ProcessState _tracker) {
+ ProcessTracker.ProcessState tracker) {
batteryStats = _batteryStats;
info = _info;
isolated = _info.uid != _uid;
uid = _uid;
userId = UserHandle.getUserId(_uid);
processName = _processName;
- tracker = _tracker;
- pkgList.add(_info.packageName);
+ baseProcessTracker = tracker;
+ pkgList.put(_info.packageName, tracker);
thread = _thread;
maxAdj = ProcessList.CACHED_APP_MAX_ADJ;
cachedAdj = clientCachedAdj = emptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
@@ -437,20 +439,33 @@ final class ProcessRecord {
/*
* Return true if package has been added false if not
*/
- public boolean addPackage(String pkg) {
- if (!pkgList.contains(pkg)) {
- pkgList.add(pkg);
+ public boolean addPackage(String pkg, ProcessTracker tracker) {
+ if (!pkgList.containsKey(pkg)) {
+ pkgList.put(pkg, tracker.getProcessStateLocked(pkg, info.uid, processName));
return true;
}
return false;
}
-
+
+ public void setProcessTrackerState(ProcessRecord TOP_APP, int memFactor, long now,
+ ProcessList plist) {
+ int state = this == TOP_APP ? ProcessTracker.STATE_TOP
+ : plist.adjToTrackedState(setAdj);
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pkgList.valueAt(ip).setState(state, memFactor, now);
+ }
+ }
+
/*
* Delete all packages from list except the package indicated in info
*/
public void resetPackageList() {
+ long now = SystemClock.uptimeMillis();
+ for (int i=0; i<pkgList.size(); i++) {
+ pkgList.valueAt(i).setState(ProcessTracker.STATE_NOTHING, 0, now);
+ }
pkgList.clear();
- pkgList.add(info.packageName);
+ pkgList.put(info.packageName, baseProcessTracker);
}
public String[] getPackageList() {
@@ -459,7 +474,9 @@ final class ProcessRecord {
return null;
}
String list[] = new String[size];
- pkgList.toArray(list);
+ for (int i=0; i<pkgList.size(); i++) {
+ list[i] = pkgList.keyAt(i);
+ }
return list;
}
}
diff --git a/services/java/com/android/server/am/ProcessTracker.java b/services/java/com/android/server/am/ProcessTracker.java
index 4eb71c7..fb8d09c 100644
--- a/services/java/com/android/server/am/ProcessTracker.java
+++ b/services/java/com/android/server/am/ProcessTracker.java
@@ -36,7 +36,15 @@ public final class ProcessTracker {
public static final int STATE_HOME = 6;
public static final int STATE_PREVIOUS = 7;
public static final int STATE_CACHED = 8;
- public static final int STATE_SCREEN_ON_MOD = STATE_CACHED+1;
+ public static final int STATE_MEM_FACTOR_MOD = STATE_CACHED+1;
+ public static final int STATE_MEM_FACTOR_NORMAL_ADJ = 0;
+ public static final int STATE_MEM_FACTOR_MODERATE_ADJ = STATE_MEM_FACTOR_MOD;
+ public static final int STATE_MEM_FACTOR_LOW_ADJ = STATE_MEM_FACTOR_MOD*2;
+ public static final int STATE_MEM_FACTOR_CRITIAL_ADJ = STATE_MEM_FACTOR_MOD*3;
+ public static final int STATE_MEM_FACTOR_COUNT = STATE_MEM_FACTOR_MOD*4;
+ public static final int STATE_SCREEN_ON_MOD = STATE_MEM_FACTOR_COUNT;
+ public static final int STATE_SCREEN_OFF_ADJ = 0;
+ public static final int STATE_SCREEN_ON_ADJ = STATE_SCREEN_ON_MOD;
public static final int STATE_COUNT = STATE_SCREEN_ON_MOD*2;
static String[] STATE_NAMES = new String[] {
@@ -45,21 +53,44 @@ public final class ProcessTracker {
};
public static final class ProcessState {
- final long[] mTimes = new long[STATE_COUNT];
+ final long[] mDurations = new long[STATE_COUNT];
int mCurState = STATE_NOTHING;
long mStartTime;
- public void setState(int state, long now) {
- if (mCurState != STATE_NOTHING) {
- mTimes[mCurState] += now - mStartTime;
+ public void setState(int state, int memFactor, long now) {
+ if (state != STATE_NOTHING) {
+ state += memFactor;
+ }
+ if (mCurState != state) {
+ if (mCurState != STATE_NOTHING) {
+ mDurations[mCurState] += now - mStartTime;
+ }
+ mCurState = state;
+ mStartTime = now;
}
- mCurState = state;
- mStartTime = now;
+ }
+ }
+
+ public static final class ServiceState {
+ long mStartedDuration;
+ long mStartedTime;
+ }
+
+ public static final class PackageState {
+ final ArrayMap<String, ProcessState> mProcesses = new ArrayMap<String, ProcessState>();
+ final ArrayMap<String, ServiceState> mServices = new ArrayMap<String, ServiceState>();
+ final int mUid;
+
+ public PackageState(int uid) {
+ mUid = uid;
}
}
static final class State {
- final ProcessMap<ProcessState> mProcesses = new ProcessMap<ProcessState>();
+ final ProcessMap<PackageState> mPackages = new ProcessMap<PackageState>();
+ final long[] mMemFactorDurations = new long[STATE_COUNT/STATE_MEM_FACTOR_MOD];
+ int mMemFactor = STATE_NOTHING;
+ long mStartTime;
}
final State mState = new State();
@@ -67,44 +98,198 @@ public final class ProcessTracker {
public ProcessTracker() {
}
- public ProcessState getStateLocked(String name, int uid) {
- ProcessState ps = mState.mProcesses.get(name, uid);
+ private PackageState getPackageStateLocked(String packageName, int uid) {
+ PackageState as = mState.mPackages.get(packageName, uid);
+ if (as != null) {
+ return as;
+ }
+ as = new PackageState(uid);
+ mState.mPackages.put(packageName, uid, as);
+ return as;
+ }
+
+ public ProcessState getProcessStateLocked(String packageName, int uid, String processName) {
+ final PackageState as = getPackageStateLocked(packageName, uid);
+ ProcessState ps = as.mProcesses.get(processName);
if (ps != null) {
return ps;
}
ps = new ProcessState();
- mState.mProcesses.put(name, uid, ps);
+ as.mProcesses.put(processName, ps);
return ps;
}
+ public ServiceState getServiceStateLocked(String packageName, int uid, String className) {
+ final PackageState as = getPackageStateLocked(packageName, uid);
+ ServiceState ss = as.mServices.get(className);
+ if (ss != null) {
+ return ss;
+ }
+ ss = new ServiceState();
+ as.mServices.put(className, ss);
+ return ss;
+ }
+
+ public boolean setMemFactor(int memFactor, boolean screenOn, long now) {
+ if (screenOn) {
+ memFactor += STATE_SCREEN_ON_MOD;
+ }
+ if (memFactor != mState.mMemFactor) {
+ if (mState.mMemFactor != STATE_NOTHING) {
+ mState.mMemFactorDurations[mState.mMemFactor/STATE_MEM_FACTOR_MOD]
+ += now - mState.mStartTime;
+ }
+ mState.mMemFactor = memFactor;
+ mState.mStartTime = now;
+ return true;
+ }
+ return false;
+ }
+
+ public int getMemFactor() {
+ return mState.mMemFactor != STATE_NOTHING ? mState.mMemFactor : 0;
+ }
+
+ private void printScreenLabel(PrintWriter pw, int offset) {
+ switch (offset) {
+ case STATE_NOTHING:
+ pw.print(" ");
+ break;
+ case STATE_SCREEN_OFF_ADJ:
+ pw.print("Screen Off / ");
+ break;
+ case STATE_SCREEN_ON_ADJ:
+ pw.print("Screen On / ");
+ break;
+ default:
+ pw.print("?????????? / ");
+ break;
+ }
+ }
+
+ private void printMemLabel(PrintWriter pw, int offset) {
+ switch (offset) {
+ case STATE_NOTHING:
+ pw.print(" ");
+ break;
+ case STATE_MEM_FACTOR_NORMAL_ADJ:
+ pw.print("Norm / ");
+ break;
+ case STATE_MEM_FACTOR_MODERATE_ADJ:
+ pw.print("Mod / ");
+ break;
+ case STATE_MEM_FACTOR_LOW_ADJ:
+ pw.print("Low / ");
+ break;
+ case STATE_MEM_FACTOR_CRITIAL_ADJ:
+ pw.print("Crit / ");
+ break;
+ default:
+ pw.print("???? / ");
+ break;
+ }
+ }
+
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
final long now = SystemClock.uptimeMillis();
- ArrayMap<String, SparseArray<ProcessState>> pmap = mState.mProcesses.getMap();
+ ArrayMap<String, SparseArray<PackageState>> pmap = mState.mPackages.getMap();
+ pw.println("Process Stats:");
for (int ip=0; ip<pmap.size(); ip++) {
String procName = pmap.keyAt(ip);
- SparseArray<ProcessState> procs = pmap.valueAt(ip);
+ SparseArray<PackageState> procs = pmap.valueAt(ip);
for (int iu=0; iu<procs.size(); iu++) {
int uid = procs.keyAt(iu);
- ProcessState state = procs.valueAt(iu);
+ PackageState state = procs.valueAt(iu);
pw.print(" "); pw.print(procName); pw.print(" / "); pw.print(uid); pw.println(":");
- long totalTime = 0;
- for (int is=0; is<STATE_NAMES.length; is++) {
- long time = state.mTimes[is];
- if (state.mCurState == is) {
- time += now - state.mStartTime;
+ for (int iproc=0; iproc<state.mProcesses.size(); iproc++) {
+ pw.print(" Process ");
+ pw.print(state.mProcesses.keyAt(iproc));
+ pw.println(":");
+ long totalTime = 0;
+ ProcessState proc = state.mProcesses.valueAt(iproc);
+ int printedScreen = -1;
+ for (int iscreen=0; iscreen<STATE_COUNT; iscreen+=STATE_SCREEN_ON_MOD) {
+ int printedMem = -1;
+ for (int imem=0; imem<STATE_MEM_FACTOR_COUNT; imem+=STATE_MEM_FACTOR_MOD) {
+ for (int is=0; is<STATE_NAMES.length; is++) {
+ int bucket = is+imem+iscreen;
+ long time = proc.mDurations[bucket];
+ String running = "";
+ if (proc.mCurState == bucket) {
+ time += now - proc.mStartTime;
+ running = " (running)";
+ }
+ if (time != 0) {
+ pw.print(" ");
+ printScreenLabel(pw, printedScreen != iscreen
+ ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING);
+ printedMem = imem;
+ pw.print(STATE_NAMES[is]); pw.print(": ");
+ TimeUtils.formatDuration(time, pw); pw.println(running);
+ totalTime += time;
+ }
+ }
+ }
+ }
+ if (totalTime != 0) {
+ pw.print(" ");
+ printScreenLabel(pw, STATE_NOTHING);
+ printMemLabel(pw, STATE_NOTHING);
+ pw.print("TOTAL : ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.println();
+ }
+ }
+ for (int isvc=0; isvc<state.mServices.size(); isvc++) {
+ pw.print(" Service ");
+ pw.print(state.mServices.keyAt(isvc));
+ pw.println(":");
+ ServiceState svc = state.mServices.valueAt(isvc);
+ long time = svc.mStartedDuration;
+ if (svc.mStartedTime >= 0) {
+ time += now - svc.mStartedTime;
}
if (time != 0) {
- pw.print(" "); pw.print(STATE_NAMES[is]); pw.print(": ");
+ pw.print(" Started: ");
TimeUtils.formatDuration(time, pw); pw.println();
- totalTime += time;
}
}
- if (totalTime != 0) {
- pw.print(" TOTAL : ");
- TimeUtils.formatDuration(totalTime, pw);
- pw.println();
+ }
+ }
+ pw.println();
+ pw.println("Run time Stats:");
+ long totalTime = 0;
+ int printedScreen = -1;
+ for (int iscreen=0; iscreen<STATE_COUNT; iscreen+=STATE_SCREEN_ON_MOD) {
+ int printedMem = -1;
+ for (int imem=0; imem<STATE_MEM_FACTOR_COUNT; imem+=STATE_MEM_FACTOR_MOD) {
+ int bucket = imem+iscreen;
+ long time = mState.mMemFactorDurations[bucket/STATE_MEM_FACTOR_MOD];
+ String running = "";
+ if (mState.mMemFactor == bucket) {
+ time += now - mState.mStartTime;
+ running = " (running)";
+ }
+ if (time != 0) {
+ pw.print(" ");
+ printScreenLabel(pw, printedScreen != iscreen
+ ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING);
+ printedMem = imem;
+ TimeUtils.formatDuration(time, pw); pw.println(running);
+ totalTime += time;
}
}
}
+ if (totalTime != 0) {
+ pw.print(" ");
+ printScreenLabel(pw, STATE_NOTHING);
+ pw.print("TOTAL: ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.println();
+ }
}
}
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 4a3699c..82e8c7f 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -28,7 +28,6 @@ import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
-import android.view.InputChannel;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -101,11 +100,8 @@ class DisplayContent {
/** Sorted most recent at top, oldest at [0]. */
ArrayList<TaskStack> mStackHistory = new ArrayList<TaskStack>();
- /** Forward motion events to mTapDetector. */
- InputChannel mTapInputChannel;
-
/** Detect user tapping outside of current focused stack bounds .*/
- StackTapDetector mTapDetector;
+ StackTapPointerEventListener mTapDetector;
/** Detect user tapping outside of current focused stack bounds .*/
Region mTouchExcludeRegion = new Region();
diff --git a/services/java/com/android/server/wm/PointerEventDispatcher.java b/services/java/com/android/server/wm/PointerEventDispatcher.java
new file mode 100644
index 0000000..6b0e4c9
--- /dev/null
+++ b/services/java/com/android/server/wm/PointerEventDispatcher.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicy.PointerEventListener;
+
+import com.android.server.UiThread;
+
+import java.util.ArrayList;
+
+public class PointerEventDispatcher extends InputEventReceiver {
+ ArrayList<PointerEventListener> mListeners = new ArrayList<PointerEventListener>();
+ PointerEventListener[] mListenersArray = new PointerEventListener[0];
+
+ public PointerEventDispatcher(InputChannel inputChannel) {
+ super(inputChannel, UiThread.getHandler().getLooper());
+ }
+
+ @Override
+ public void onInputEvent(InputEvent event) {
+ try {
+ if (event instanceof MotionEvent
+ && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ final MotionEvent motionEvent = (MotionEvent)event;
+ PointerEventListener[] listeners;
+ synchronized (mListeners) {
+ if (mListenersArray == null) {
+ mListenersArray = new PointerEventListener[mListeners.size()];
+ mListeners.toArray(mListenersArray);
+ }
+ listeners = mListenersArray;
+ }
+ for (int i = 0; i < listeners.length; ++i) {
+ listeners[i].onPointerEvent(motionEvent);
+ }
+ }
+ } finally {
+ finishInputEvent(event, false);
+ }
+ }
+
+ /**
+ * Add the specified listener to the list.
+ * @param listener The listener to add.
+ */
+ public void registerInputEventListener(PointerEventListener listener) {
+ synchronized (mListeners) {
+ if (mListeners.contains(listener)) {
+ throw new IllegalStateException("registerInputEventListener: trying to register" +
+ listener + " twice.");
+ }
+ mListeners.add(listener);
+ mListenersArray = null;
+ }
+ }
+
+ /**
+ * Remove the specified listener from the list.
+ * @param listener The listener to remove.
+ */
+ public void unregisterInputEventListener(PointerEventListener listener) {
+ synchronized (mListeners) {
+ if (!mListeners.contains(listener)) {
+ throw new IllegalStateException("registerInputEventListener: " + listener +
+ " not registered.");
+ }
+ mListeners.remove(listener);
+ mListenersArray = null;
+ }
+ }
+}
diff --git a/services/java/com/android/server/wm/StackTapDetector.java b/services/java/com/android/server/wm/StackTapDetector.java
deleted file mode 100644
index 7127fd2..0000000
--- a/services/java/com/android/server/wm/StackTapDetector.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import android.graphics.Region;
-import android.os.Looper;
-import android.view.DisplayInfo;
-import android.view.InputChannel;
-import android.view.InputDevice;
-import android.view.InputEvent;
-import android.view.InputEventReceiver;
-import android.view.MotionEvent;
-
-import com.android.server.wm.WindowManagerService.H;
-
-public class StackTapDetector extends InputEventReceiver {
- private static final int TAP_TIMEOUT_MSEC = 300;
- private static final float TAP_MOTION_SLOP_INCHES = 0.125f;
-
- private final int mMotionSlop;
- private float mDownX;
- private float mDownY;
- private int mPointerId;
- final private Region mTouchExcludeRegion;
- private final WindowManagerService mService;
- private final DisplayContent mDisplayContent;
-
- public StackTapDetector(WindowManagerService service, DisplayContent displayContent,
- InputChannel inputChannel, Looper looper) {
- super(inputChannel, looper);
- mService = service;
- mDisplayContent = displayContent;
- mTouchExcludeRegion = displayContent.mTouchExcludeRegion;
- DisplayInfo info = displayContent.getDisplayInfo();
- mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES);
- }
-
- @Override
- public void onInputEvent(InputEvent event) {
- try {
- if (!(event instanceof MotionEvent)
- || !event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
- return;
- }
- final MotionEvent motionEvent = (MotionEvent)event;
- final int action = motionEvent.getAction();
- switch (action & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN:
- mPointerId = motionEvent.getPointerId(0);
- mDownX = motionEvent.getX();
- mDownY = motionEvent.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- if (mPointerId >= 0) {
- int index = motionEvent.findPointerIndex(mPointerId);
- if ((motionEvent.getEventTime() - motionEvent.getDownTime())
- > TAP_TIMEOUT_MSEC
- || (motionEvent.getX(index) - mDownX) > mMotionSlop
- || (motionEvent.getY(index) - mDownY) > mMotionSlop) {
- mPointerId = -1;
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_POINTER_UP: {
- int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
- >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- // Extract the index of the pointer that left the touch sensor
- if (mPointerId == motionEvent.getPointerId(index)) {
- final int x = (int)motionEvent.getX(index);
- final int y = (int)motionEvent.getY(index);
- synchronized (this) {
- if ((motionEvent.getEventTime() - motionEvent.getDownTime())
- < TAP_TIMEOUT_MSEC
- && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop
- && !mTouchExcludeRegion.contains(x, y)) {
- mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
- mDisplayContent).sendToTarget();
- }
- }
- mPointerId = -1;
- }
- break;
- }
- }
- } finally {
- finishInputEvent(event, false /*ignored for monitors*/);
- }
- }
-}
diff --git a/services/java/com/android/server/wm/StackTapPointerEventListener.java b/services/java/com/android/server/wm/StackTapPointerEventListener.java
new file mode 100644
index 0000000..19d8ab3
--- /dev/null
+++ b/services/java/com/android/server/wm/StackTapPointerEventListener.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.graphics.Region;
+import android.view.DisplayInfo;
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicy.PointerEventListener;
+
+import com.android.server.wm.WindowManagerService.H;
+
+public class StackTapPointerEventListener implements PointerEventListener {
+ private static final int TAP_TIMEOUT_MSEC = 300;
+ private static final float TAP_MOTION_SLOP_INCHES = 0.125f;
+
+ private final int mMotionSlop;
+ private float mDownX;
+ private float mDownY;
+ private int mPointerId;
+ final private Region mTouchExcludeRegion;
+ private final WindowManagerService mService;
+ private final DisplayContent mDisplayContent;
+
+ public StackTapPointerEventListener(WindowManagerService service,
+ DisplayContent displayContent) {
+ mService = service;
+ mDisplayContent = displayContent;
+ mTouchExcludeRegion = displayContent.mTouchExcludeRegion;
+ DisplayInfo info = displayContent.getDisplayInfo();
+ mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES);
+ }
+
+ @Override
+ public void onPointerEvent(MotionEvent motionEvent) {
+ final int action = motionEvent.getAction();
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN:
+ mPointerId = motionEvent.getPointerId(0);
+ mDownX = motionEvent.getX();
+ mDownY = motionEvent.getY();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (mPointerId >= 0) {
+ int index = motionEvent.findPointerIndex(mPointerId);
+ if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC
+ || (motionEvent.getX(index) - mDownX) > mMotionSlop
+ || (motionEvent.getY(index) - mDownY) > mMotionSlop) {
+ mPointerId = -1;
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP: {
+ int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ // Extract the index of the pointer that left the touch sensor
+ if (mPointerId == motionEvent.getPointerId(index)) {
+ final int x = (int)motionEvent.getX(index);
+ final int y = (int)motionEvent.getY(index);
+ if ((motionEvent.getEventTime() - motionEvent.getDownTime())
+ < TAP_TIMEOUT_MSEC
+ && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop
+ && !mTouchExcludeRegion.contains(x, y)) {
+ mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
+ mDisplayContent).sendToTarget();
+ }
+ mPointerId = -1;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f166c31..079134b 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -124,6 +124,7 @@ import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerPolicy.FakeWindow;
+import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
@@ -281,8 +282,6 @@ public class WindowManagerService extends IWindowManager.Stub
private static final String SYSTEM_SECURE = "ro.secure";
private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
- private static final String TAP_INPUT_CHANNEL_NAME = "StackTapDetector";
-
private static final int MAX_SCREENSHOT_RETRIES = 3;
final private KeyguardDisableHandler mKeyguardDisableHandler;
@@ -594,6 +593,8 @@ public class WindowManagerService extends IWindowManager.Stub
SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
+ private final PointerEventDispatcher mPointerEventDispatcher;
+
final class DragInputEventReceiver extends InputEventReceiver {
public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
@@ -728,6 +729,8 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplaySettings = new DisplaySettings(context);
mDisplaySettings.readSettingsLocked();
+ mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
+
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
Display[] displays = mDisplayManager.getDisplays();
@@ -5098,6 +5101,16 @@ public class WindowManagerService extends IWindowManager.Stub
mAnimatorDurationScale };
}
+ @Override
+ public void registerPointerEventListener(PointerEventListener listener) {
+ mPointerEventDispatcher.registerInputEventListener(listener);
+ }
+
+ @Override
+ public void unregisterPointerEventListener(PointerEventListener listener) {
+ mPointerEventDispatcher.unregisterInputEventListener(listener);
+ }
+
// Called by window manager policy. Not exposed externally.
@Override
public int getLidState() {
@@ -5117,12 +5130,6 @@ public class WindowManagerService extends IWindowManager.Stub
// Called by window manager policy. Not exposed externally.
@Override
- public InputChannel monitorInput(String inputChannelName) {
- return mInputManager.monitorInput(inputChannelName);
- }
-
- // Called by window manager policy. Not exposed externally.
- @Override
public void switchKeyboardLayout(int deviceId, int direction) {
mInputManager.switchKeyboardLayout(deviceId, direction);
}
@@ -10652,10 +10659,8 @@ public class WindowManagerService extends IWindowManager.Stub
// TODO: Create an input channel for each display with touch capability.
if (displayId == Display.DEFAULT_DISPLAY) {
- InputChannel inputChannel = monitorInput(TAP_INPUT_CHANNEL_NAME);
- displayContent.mTapInputChannel = inputChannel;
- displayContent.mTapDetector =
- new StackTapDetector(this, displayContent, inputChannel, Looper.myLooper());
+ displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
+ registerPointerEventListener(displayContent.mTapDetector);
}
return displayContent;
@@ -10838,10 +10843,9 @@ public class WindowManagerService extends IWindowManager.Stub
if (displayContent != null) {
mDisplayContents.delete(displayId);
- if (displayContent.mTapInputChannel != null) {
- displayContent.mTapInputChannel.dispose();
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ unregisterPointerEventListener(displayContent.mTapDetector);
}
-
WindowList windows = displayContent.getWindowList();
while (!windows.isEmpty()) {
final WindowState win = windows.get(windows.size() - 1);