Skip to content

Commit 2c84cfc

Browse files
author
Dianne Hackborn
committed
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
1 parent dd79b4c commit 2c84cfc

File tree

17 files changed

+47021
-153
lines changed

17 files changed

+47021
-153
lines changed

api/15.txt

Lines changed: 46591 additions & 0 deletions
Large diffs are not rendered by default.

api/current.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5087,7 +5087,7 @@ package android.content {
50875087
field public static final java.lang.String ALARM_SERVICE = "alarm";
50885088
field public static final java.lang.String AUDIO_SERVICE = "audio";
50895089
field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
5090-
field public static final int BIND_ADJUST_WITH_ACTIVITY = 64; // 0x40
5090+
field public static final int BIND_ADJUST_WITH_ACTIVITY = 128; // 0x80
50915091
field public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; // 0x10
50925092
field public static final int BIND_AUTO_CREATE = 1; // 0x1
50935093
field public static final int BIND_DEBUG_UNBIND = 2; // 0x2

cmds/am/src/com/android/commands/am/Am.java

Lines changed: 137 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public class Am {
6060
private boolean mWaitOption = false;
6161
private boolean mStopOption = false;
6262

63+
private int mRepeat = 0;
64+
6365
private String mProfileFile;
6466
private boolean mProfileAutoStop;
6567

@@ -133,6 +135,7 @@ private Intent makeIntent() throws URISyntaxException {
133135
mDebugOption = false;
134136
mWaitOption = false;
135137
mStopOption = false;
138+
mRepeat = 0;
136139
mProfileFile = null;
137140
Uri data = null;
138141
String type = null;
@@ -263,6 +266,8 @@ private Intent makeIntent() throws URISyntaxException {
263266
} else if (opt.equals("--start-profiler")) {
264267
mProfileFile = nextArgRequired();
265268
mProfileAutoStop = false;
269+
} else if (opt.equals("-R")) {
270+
mRepeat = Integer.parseInt(nextArgRequired());
266271
} else if (opt.equals("-S")) {
267272
mStopOption = true;
268273
} else {
@@ -335,138 +340,144 @@ private void runStart() throws Exception {
335340
mimeType = mAm.getProviderMimeType(intent.getData());
336341
}
337342

338-
if (mStopOption) {
339-
String packageName;
340-
if (intent.getComponent() != null) {
341-
packageName = intent.getComponent().getPackageName();
342-
} else {
343-
IPackageManager pm = IPackageManager.Stub.asInterface(
344-
ServiceManager.getService("package"));
345-
if (pm == null) {
346-
System.err.println("Error: Package manager not running; aborting");
347-
return;
343+
do {
344+
if (mStopOption) {
345+
String packageName;
346+
if (intent.getComponent() != null) {
347+
packageName = intent.getComponent().getPackageName();
348+
} else {
349+
IPackageManager pm = IPackageManager.Stub.asInterface(
350+
ServiceManager.getService("package"));
351+
if (pm == null) {
352+
System.err.println("Error: Package manager not running; aborting");
353+
return;
354+
}
355+
List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0);
356+
if (activities == null || activities.size() <= 0) {
357+
System.err.println("Error: Intent does not match any activities: "
358+
+ intent);
359+
return;
360+
} else if (activities.size() > 1) {
361+
System.err.println("Error: Intent matches multiple activities; can't stop: "
362+
+ intent);
363+
return;
364+
}
365+
packageName = activities.get(0).activityInfo.packageName;
348366
}
349-
List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0);
350-
if (activities == null || activities.size() <= 0) {
351-
System.err.println("Error: Intent does not match any activities: "
352-
+ intent);
353-
return;
354-
} else if (activities.size() > 1) {
355-
System.err.println("Error: Intent matches multiple activities; can't stop: "
356-
+ intent);
367+
System.out.println("Stopping: " + packageName);
368+
mAm.forceStopPackage(packageName);
369+
Thread.sleep(250);
370+
}
371+
372+
System.out.println("Starting: " + intent);
373+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
374+
375+
ParcelFileDescriptor fd = null;
376+
377+
if (mProfileFile != null) {
378+
try {
379+
fd = ParcelFileDescriptor.open(
380+
new File(mProfileFile),
381+
ParcelFileDescriptor.MODE_CREATE |
382+
ParcelFileDescriptor.MODE_TRUNCATE |
383+
ParcelFileDescriptor.MODE_READ_WRITE);
384+
} catch (FileNotFoundException e) {
385+
System.err.println("Error: Unable to open file: " + mProfileFile);
357386
return;
358387
}
359-
packageName = activities.get(0).activityInfo.packageName;
360-
}
361-
System.out.println("Stopping: " + packageName);
362-
mAm.forceStopPackage(packageName);
363-
Thread.sleep(250);
364-
}
365-
366-
System.out.println("Starting: " + intent);
367-
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
368-
369-
ParcelFileDescriptor fd = null;
370-
371-
if (mProfileFile != null) {
372-
try {
373-
fd = ParcelFileDescriptor.open(
374-
new File(mProfileFile),
375-
ParcelFileDescriptor.MODE_CREATE |
376-
ParcelFileDescriptor.MODE_TRUNCATE |
377-
ParcelFileDescriptor.MODE_READ_WRITE);
378-
} catch (FileNotFoundException e) {
379-
System.err.println("Error: Unable to open file: " + mProfileFile);
380-
return;
381388
}
382-
}
383-
384-
IActivityManager.WaitResult result = null;
385-
int res;
386-
if (mWaitOption) {
387-
result = mAm.startActivityAndWait(null, intent, mimeType,
389+
390+
IActivityManager.WaitResult result = null;
391+
int res;
392+
if (mWaitOption) {
393+
result = mAm.startActivityAndWait(null, intent, mimeType,
394+
null, 0, null, null, 0, false, mDebugOption,
395+
mProfileFile, fd, mProfileAutoStop);
396+
res = result.result;
397+
} else {
398+
res = mAm.startActivity(null, intent, mimeType,
388399
null, 0, null, null, 0, false, mDebugOption,
389400
mProfileFile, fd, mProfileAutoStop);
390-
res = result.result;
391-
} else {
392-
res = mAm.startActivity(null, intent, mimeType,
393-
null, 0, null, null, 0, false, mDebugOption,
394-
mProfileFile, fd, mProfileAutoStop);
395-
}
396-
PrintStream out = mWaitOption ? System.out : System.err;
397-
boolean launched = false;
398-
switch (res) {
399-
case IActivityManager.START_SUCCESS:
400-
launched = true;
401-
break;
402-
case IActivityManager.START_SWITCHES_CANCELED:
403-
launched = true;
404-
out.println(
405-
"Warning: Activity not started because the "
406-
+ " current activity is being kept for the user.");
407-
break;
408-
case IActivityManager.START_DELIVERED_TO_TOP:
409-
launched = true;
410-
out.println(
411-
"Warning: Activity not started, intent has "
412-
+ "been delivered to currently running "
413-
+ "top-most instance.");
414-
break;
415-
case IActivityManager.START_RETURN_INTENT_TO_CALLER:
416-
launched = true;
417-
out.println(
418-
"Warning: Activity not started because intent "
419-
+ "should be handled by the caller");
420-
break;
421-
case IActivityManager.START_TASK_TO_FRONT:
422-
launched = true;
423-
out.println(
424-
"Warning: Activity not started, its current "
425-
+ "task has been brought to the front");
426-
break;
427-
case IActivityManager.START_INTENT_NOT_RESOLVED:
428-
out.println(
429-
"Error: Activity not started, unable to "
430-
+ "resolve " + intent.toString());
431-
break;
432-
case IActivityManager.START_CLASS_NOT_FOUND:
433-
out.println(NO_CLASS_ERROR_CODE);
434-
out.println("Error: Activity class " +
435-
intent.getComponent().toShortString()
436-
+ " does not exist.");
437-
break;
438-
case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
439-
out.println(
440-
"Error: Activity not started, you requested to "
441-
+ "both forward and receive its result");
442-
break;
443-
case IActivityManager.START_PERMISSION_DENIED:
444-
out.println(
445-
"Error: Activity not started, you do not "
446-
+ "have permission to access it.");
447-
break;
448-
default:
449-
out.println(
450-
"Error: Activity not started, unknown error code " + res);
451-
break;
452-
}
453-
if (mWaitOption && launched) {
454-
if (result == null) {
455-
result = new IActivityManager.WaitResult();
456-
result.who = intent.getComponent();
457401
}
458-
System.out.println("Status: " + (result.timeout ? "timeout" : "ok"));
459-
if (result.who != null) {
460-
System.out.println("Activity: " + result.who.flattenToShortString());
402+
PrintStream out = mWaitOption ? System.out : System.err;
403+
boolean launched = false;
404+
switch (res) {
405+
case IActivityManager.START_SUCCESS:
406+
launched = true;
407+
break;
408+
case IActivityManager.START_SWITCHES_CANCELED:
409+
launched = true;
410+
out.println(
411+
"Warning: Activity not started because the "
412+
+ " current activity is being kept for the user.");
413+
break;
414+
case IActivityManager.START_DELIVERED_TO_TOP:
415+
launched = true;
416+
out.println(
417+
"Warning: Activity not started, intent has "
418+
+ "been delivered to currently running "
419+
+ "top-most instance.");
420+
break;
421+
case IActivityManager.START_RETURN_INTENT_TO_CALLER:
422+
launched = true;
423+
out.println(
424+
"Warning: Activity not started because intent "
425+
+ "should be handled by the caller");
426+
break;
427+
case IActivityManager.START_TASK_TO_FRONT:
428+
launched = true;
429+
out.println(
430+
"Warning: Activity not started, its current "
431+
+ "task has been brought to the front");
432+
break;
433+
case IActivityManager.START_INTENT_NOT_RESOLVED:
434+
out.println(
435+
"Error: Activity not started, unable to "
436+
+ "resolve " + intent.toString());
437+
break;
438+
case IActivityManager.START_CLASS_NOT_FOUND:
439+
out.println(NO_CLASS_ERROR_CODE);
440+
out.println("Error: Activity class " +
441+
intent.getComponent().toShortString()
442+
+ " does not exist.");
443+
break;
444+
case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
445+
out.println(
446+
"Error: Activity not started, you requested to "
447+
+ "both forward and receive its result");
448+
break;
449+
case IActivityManager.START_PERMISSION_DENIED:
450+
out.println(
451+
"Error: Activity not started, you do not "
452+
+ "have permission to access it.");
453+
break;
454+
default:
455+
out.println(
456+
"Error: Activity not started, unknown error code " + res);
457+
break;
461458
}
462-
if (result.thisTime >= 0) {
463-
System.out.println("ThisTime: " + result.thisTime);
459+
if (mWaitOption && launched) {
460+
if (result == null) {
461+
result = new IActivityManager.WaitResult();
462+
result.who = intent.getComponent();
463+
}
464+
System.out.println("Status: " + (result.timeout ? "timeout" : "ok"));
465+
if (result.who != null) {
466+
System.out.println("Activity: " + result.who.flattenToShortString());
467+
}
468+
if (result.thisTime >= 0) {
469+
System.out.println("ThisTime: " + result.thisTime);
470+
}
471+
if (result.totalTime >= 0) {
472+
System.out.println("TotalTime: " + result.totalTime);
473+
}
474+
System.out.println("Complete");
464475
}
465-
if (result.totalTime >= 0) {
466-
System.out.println("TotalTime: " + result.totalTime);
476+
mRepeat--;
477+
if (mRepeat > 1) {
478+
mAm.unhandledBack();
467479
}
468-
System.out.println("Complete");
469-
}
480+
} while (mRepeat > 1);
470481
}
471482

472483
private void runForceStop() throws Exception {
@@ -1164,7 +1175,8 @@ private String nextArgRequired() {
11641175
private static void showUsage() {
11651176
System.err.println(
11661177
"usage: am [subcommand] [options]\n" +
1167-
"usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>] [-S] <INTENT>\n" +
1178+
"usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
1179+
" [--R COUNT] [-S] <INTENT>\n" +
11681180
" am startservice <INTENT>\n" +
11691181
" am force-stop <PACKAGE>\n" +
11701182
" am broadcast <INTENT>\n" +
@@ -1182,6 +1194,8 @@ private static void showUsage() {
11821194
" -W: wait for launch to complete\n" +
11831195
" --start-profiler <FILE>: start profiler and send results to <FILE>\n" +
11841196
" -P <FILE>: like above, but profiling stops when app goes idle\n" +
1197+
" -R: repeat the activity launch <COUNT> times. Prior to each repeat,\n" +
1198+
" the top activity will be finished.\n" +
11851199
" -S: force stop the target app before starting the activity\n" +
11861200
"\n" +
11871201
"am startservice: start a Service.\n" +

core/java/android/content/Context.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ public abstract class Context {
185185
* used to reduce the amount that the client process's overall importance
186186
* is used to impact it.
187187
*/
188-
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0040;
188+
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
189+
190+
/**
191+
* Flag for {@link #bindService}: Don't consider the bound service to be
192+
* visible, even if the caller is visible.
193+
* @hide
194+
*/
195+
public static final int BIND_NOT_VISIBLE = 0x40000000;
189196

190197
/** Return an AssetManager instance for your application's package. */
191198
public abstract AssetManager getAssets();

core/java/android/content/Loader.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ public boolean isReset() {
183183
}
184184

185185
/**
186+
* This function will normally be called for you automatically by
187+
* {@link android.app.LoaderManager} when the associated fragment/activity
188+
* is being started. When using a Loader with {@link android.app.LoaderManager},
189+
* you <em>must not</em> call this method yourself, or you will conflict
190+
* with its management of the Loader.
191+
*
186192
* Starts an asynchronous load of the Loader's data. When the result
187193
* is ready the callbacks will be called on the process's main thread.
188194
* If a previous load has been completed and is still valid
@@ -232,7 +238,13 @@ protected void onForceLoad() {
232238
}
233239

234240
/**
235-
* Stops delivery of updates until the next time {@link #startLoading()} is called.
241+
* This function will normally be called for you automatically by
242+
* {@link android.app.LoaderManager} when the associated fragment/activity
243+
* is being stopped. When using a Loader with {@link android.app.LoaderManager},
244+
* you <em>must not</em> call this method yourself, or you will conflict
245+
* with its management of the Loader.
246+
*
247+
* <p>Stops delivery of updates until the next time {@link #startLoading()} is called.
236248
* Implementations should <em>not</em> invalidate their data at this point --
237249
* clients are still free to use the last data the loader reported. They will,
238250
* however, typically stop reporting new data if the data changes; they can
@@ -260,6 +272,12 @@ protected void onStopLoading() {
260272
}
261273

262274
/**
275+
* This function will normally be called for you automatically by
276+
* {@link android.app.LoaderManager} when restarting a Loader. When using
277+
* a Loader with {@link android.app.LoaderManager},
278+
* you <em>must not</em> call this method yourself, or you will conflict
279+
* with its management of the Loader.
280+
*
263281
* Tell the Loader that it is being abandoned. This is called prior
264282
* to {@link #reset} to have it retain its current data but not report
265283
* any new data.
@@ -282,6 +300,12 @@ protected void onAbandon() {
282300
}
283301

284302
/**
303+
* This function will normally be called for you automatically by
304+
* {@link android.app.LoaderManager} when destroying a Loader. When using
305+
* a Loader with {@link android.app.LoaderManager},
306+
* you <em>must not</em> call this method yourself, or you will conflict
307+
* with its management of the Loader.
308+
*
285309
* Resets the state of the Loader. The Loader should at this point free
286310
* all of its resources, since it may never be called again; however, its
287311
* {@link #startLoading()} may later be called at which point it must be

0 commit comments

Comments
 (0)