Various performance and other work.
- IME service now switches between visible and perceptible depending on
whether it is being showm, allowing us to more aggressively free its
memory when not shown.
- The activity display time is no longer delayed by the activity
transition animation.
- New -R (repeat) option for launching activities with the am command.
- Improved some documentation on Loader to be clear about some methods
that apps should not normally call.
- FrameworkPerf test now allows you to select individual tests to run.
Change-Id: Id1f73de66dc93d63212183958a72119ad174318b
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 17ea03b..ddac35c 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -161,6 +161,16 @@
private final LruCache<SuggestionSpan, InputMethodInfo> mSecureSuggestionSpans =
new LruCache<SuggestionSpan, InputMethodInfo>(SECURE_SUGGESTION_SPANS_MAX_SIZE);
+ // Used to bring IME service up to visible adjustment while it is being shown.
+ final ServiceConnection mVisibleConnection = new ServiceConnection() {
+ @Override public void onServiceConnected(ComponentName name, IBinder service) {
+ }
+
+ @Override public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+ boolean mVisibleBound = false;
+
// Ongoing notification
private NotificationManager mNotificationManager;
private KeyguardManager mKeyguardManager;
@@ -893,7 +903,8 @@
com.android.internal.R.string.input_method_binding_label);
mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
- if (mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE)) {
+ if (mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE
+ | Context.BIND_NOT_VISIBLE)) {
mLastBindTime = SystemClock.uptimeMillis();
mHaveConnection = true;
mCurId = info.getId();
@@ -975,6 +986,11 @@
}
void unbindCurrentMethodLocked(boolean reportToClient) {
+ if (mVisibleBound) {
+ mContext.unbindService(mVisibleConnection);
+ mVisibleBound = false;
+ }
+
if (mHaveConnection) {
mContext.unbindService(this);
mHaveConnection = false;
@@ -1366,6 +1382,10 @@
MSG_SHOW_SOFT_INPUT, getImeShowFlags(), mCurMethod,
resultReceiver));
mInputShown = true;
+ if (mHaveConnection && !mVisibleBound) {
+ mContext.bindService(mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE);
+ mVisibleBound = true;
+ }
res = true;
} else if (mHaveConnection && SystemClock.uptimeMillis()
>= (mLastBindTime+TIME_TO_RECONNECT)) {
@@ -1377,7 +1397,8 @@
SystemClock.uptimeMillis()-mLastBindTime,1);
Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()");
mContext.unbindService(this);
- mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE);
+ mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE
+ | Context.BIND_NOT_VISIBLE);
}
return res;
@@ -1436,6 +1457,10 @@
} else {
res = false;
}
+ if (mHaveConnection && mVisibleBound) {
+ mContext.unbindService(mVisibleConnection);
+ mVisibleBound = false;
+ }
mInputShown = false;
mShowRequested = false;
mShowExplicitlyRequested = false;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 04bbc11..f8a7d6a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -13241,10 +13241,17 @@
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
|Context.BIND_IMPORTANT)) != 0) {
adj = clientAdj;
- } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
+ && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
+ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
adj = clientAdj;
} else {
- adj = ProcessList.VISIBLE_APP_ADJ;
+ app.pendingUiClean = true;
+ if (adj > ProcessList.VISIBLE_APP_ADJ) {
+ adj = ProcessList.VISIBLE_APP_ADJ;
+ }
}
if (!client.hidden) {
app.hidden = false;
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index ce45bfb1..00e6cb2 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -523,7 +523,7 @@
}
}
- public void windowsVisible() {
+ public void windowsDrawn() {
synchronized(service) {
if (launchTime != 0) {
final long curTime = SystemClock.uptimeMillis();
@@ -555,6 +555,11 @@
stack.mInitialStartTime = 0;
}
startTime = 0;
+ }
+ }
+
+ public void windowsVisible() {
+ synchronized(service) {
stack.reportActivityVisibleLocked(this);
if (ActivityManagerService.DEBUG_SWITCH) Log.v(
ActivityManagerService.TAG, "windowsVisible(): " + this);
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 61c96bb..0e3d20a 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -77,6 +77,9 @@
// Last visibility state we reported to the app token.
boolean reportedVisible;
+ // Last drawn state we reported to the app token.
+ boolean reportedDrawn;
+
// Set to true when the token has been removed from the window mgr.
boolean removed;
@@ -277,6 +280,7 @@
int numInteresting = 0;
int numVisible = 0;
+ int numDrawn = 0;
boolean nowGone = true;
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Update reported visibility: " + this);
@@ -307,6 +311,7 @@
}
numInteresting++;
if (win.isDrawnLw()) {
+ numDrawn++;
if (!win.isAnimating()) {
numVisible++;
}
@@ -316,9 +321,27 @@
}
}
+ boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+ if (!nowGone) {
+ // If the app is not yet gone, then it can only become visible/drawn.
+ if (!nowDrawn) {
+ nowDrawn = reportedDrawn;
+ }
+ if (!nowVisible) {
+ nowVisible = reportedVisible;
+ }
+ }
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting="
+ numInteresting + " visible=" + numVisible);
+ if (nowDrawn != reportedDrawn) {
+ if (nowDrawn) {
+ Message m = service.mH.obtainMessage(
+ H.REPORT_APPLICATION_TOKEN_DRAWN, this);
+ service.mH.sendMessage(m);
+ }
+ reportedDrawn = nowDrawn;
+ }
if (nowVisible != reportedVisible) {
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
WindowManagerService.TAG, "Visibility changed in " + this
@@ -360,6 +383,7 @@
pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
pw.print(" clientHidden="); pw.print(clientHidden);
pw.print(" willBeHidden="); pw.print(willBeHidden);
+ pw.print(" reportedDrawn="); pw.print(reportedDrawn);
pw.print(" reportedVisible="); pw.println(reportedVisible);
if (paused || freezingScreen) {
pw.print(prefix); pw.print("paused="); pw.print(paused);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 08797dd..2cd3062 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -6386,6 +6386,7 @@
public static final int REMOVE_STARTING = 6;
public static final int FINISHED_STARTING = 7;
public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
+ public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
public static final int WINDOW_FREEZE_TIMEOUT = 11;
public static final int HOLD_SCREEN_CHANGED = 12;
public static final int APP_TRANSITION_TIMEOUT = 13;
@@ -6599,6 +6600,17 @@
}
} break;
+ case REPORT_APPLICATION_TOKEN_DRAWN: {
+ final AppWindowToken wtoken = (AppWindowToken)msg.obj;
+
+ try {
+ if (DEBUG_VISIBILITY) Slog.v(
+ TAG, "Reporting drawn in " + wtoken);
+ wtoken.appToken.windowsDrawn();
+ } catch (RemoteException ex) {
+ }
+ } break;
+
case REPORT_APPLICATION_TOKEN_WINDOWS: {
final AppWindowToken wtoken = (AppWindowToken)msg.obj;