SlideShare ist ein Scribd-Unternehmen logo
1 von 184
Downloaden Sie, um offline zu lesen
Automated Historical
Performance Analysis
with kmemtracer
LG전자 이경민
Contents
Why Automated Historical Performance Testing?

kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics

12th Kandroid Conference - www.kandroid.org

2
If you can’t measure it,
you can’t manage it.
Peter F. Drucker
(1909~2005)

12th Kandroid Conference - www.kandroid.org

3
If you can’t measure it,
you can’t manage it.
Peter F. Drucker
(1909~2005)

If you can’t automate
the measurement of it,
it is difficult to improve it.

12th Kandroid Conference - www.kandroid.org

4
Diversity or Fragmentation
Platform
Versions

http://developer.android.com/about/dashboards/index.html
12th Kandroid Conference - www.kandroid.org

5
Diversity or Fragmentation
Platform
Versions

Screen Sizes
and Densities

http://developer.android.com/about/dashboards/index.html
12th Kandroid Conference - www.kandroid.org

6
http://www.mactrast.com/2012/05/visualized-the-truth-about-android-fragmentation/
12th Kandroid Conference - www.kandroid.org

7
Historical Performance Analysis
Why Historical Analysis?

Source: Memory and Performance at the 11th Korea Android Conference
12th Kandroid Conference - www.kandroid.org

8
Historical Performance Analysis
Why Historical Analysis?

Source: Memory and Performance at the 11th Korea Android Conference
12th Kandroid Conference - www.kandroid.org

9
Historical Performance Analysis
Why Historical Analysis?

Activity
Navigation
& Lifecycle
Source: Memory and Performance at the 11th Korea Android Conference
12th Kandroid Conference - www.kandroid.org

10
How to Track Activity Navigation & Lifecycle?

12th Kandroid Conference - www.kandroid.org

11
How to Track Activity Navigation & Lifecycle?

Override onCreate, onStart, …
of your Activity classes

12th Kandroid Conference - www.kandroid.org

12
How to Track Activity Navigation & Lifecycle?

Modify android.app.Activity
in the framework

12th Kandroid Conference - www.kandroid.org

13
How to Track Activity Navigation & Lifecycle?

Is there a way that does not
require the modification of
an application or framework?

12th Kandroid Conference - www.kandroid.org

14
How to Track Activity Navigation & Lifecycle?

Is there a way that does not
require the modification of
an application or framework?

Instrumentation
12th Kandroid Conference - www.kandroid.org

15
12th Kandroid Conference - www.kandroid.org

16
Android instrumentation is a set of control methods
or "hooks" in the Android system.
These hooks control an Android component
independently of its normal lifecycle.
They also control how Android loads applications.
(http://developer.android.com/tools/testing/testing_android.html)
12th Kandroid Conference - www.kandroid.org

17
Contents
Why Automated Historical Performance Testing?

kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics

12th Kandroid Conference - www.kandroid.org

18
Historical Analysis w/ kmemtracer
Application
Package

Control
android.test.
Instrumentation
TestRunner

Test
Package
12th Kandroid Conference - www.kandroid.org

19
Historical Analysis w/ kmemtracer
https://github.com/snailee/kmemtracer-libs

Application
Package

Control

Track

android.test.
Instrumentation
TestRunner

org.kandroid.
memtracer.Memory
Instrumentation

Test
Package

Trace
Package
12th Kandroid Conference - www.kandroid.org

20
android.app.Instrumentation
void
void
void
void
void
void
void
void
void
void
void
void
void

callActivityOnCreate(Activity, Bundle)
callActivityOnDestroy(Activity)
callActivityOnNewIntent(Activity, Intent)
callActivityOnPause(Activity)
callActivityOnPostCreate(Activity, Bundle)
callActivityOnRestart(Activity)
callActivityOnRestoreInstanceState(Activity, Bundle)
callActivityOnResume(Activity)
callActivityOnSaveInstanceState(Activity, Bundle)
callActivityOnStart(Activity)
callActivityOnStop(Activity)
callActivityOnUserLeaving(Activity)
callApplicationOnCreate(Application)

12th Kandroid Conference - www.kandroid.org

21
android.app.Instrumentation
void
void
void
void
void
void
void
void
void
void
void
void
void

callActivityOnCreate(Activity, Bundle)
callActivityOnDestroy(Activity)
callActivityOnNewIntent(Activity, Intent)
callActivityOnPause(Activity)
callActivityOnPostCreate(Activity, Bundle)
callActivityOnRestart(Activity)
callActivityOnRestoreInstanceState(Activity, Bundle)
callActivityOnResume(Activity)
callActivityOnSaveInstanceState(Activity, Bundle)
callActivityOnStart(Activity)
callActivityOnStop(Activity)
callActivityOnUserLeaving(Activity)
callApplicationOnCreate(Application)

Call for
Control
12th Kandroid Conference - www.kandroid.org

22
android.app.Instrumentation
void
void
void
void
void
void
void
void
void
void
void
void
void

callActivityOnCreate(Activity, Bundle)
callActivityOnDestroy(Activity)
callActivityOnNewIntent(Activity, Intent)
callActivityOnPause(Activity)
callActivityOnPostCreate(Activity, Bundle)
callActivityOnRestart(Activity)
callActivityOnRestoreInstanceState(Activity, Bundle)
callActivityOnResume(Activity)
callActivityOnSaveInstanceState(Activity, Bundle)
callActivityOnStart(Activity)
callActivityOnStop(Activity)
callActivityOnUserLeaving(Activity)
callApplicationOnCreate(Application)

Call for
Control

Override for
Track
12th Kandroid Conference - www.kandroid.org

23
org.kandroid.memtracer.MemoryInstrumentation
public class MemoryInstrumentation extends Instrumentation {
private static final String ARGUMENT_INSTRUMENT_CLASS = "class";
private MemoryTracer mMemoryTracer;
private String mMainActivityName;
...
@Override
public void onCreate(Bundle arguments) {
mMainActivityName = arguments.getString(ARGUMENT_INSTRUMENT_CLASS);
mMemoryTracer = createMemoryTracer();
mMemoryTracer.startTracing(getTargetContext().getPackageName());
start();
}
@Override
public void callActivityOnCreate(Activity activity, Bundle icicle) {
String tag = activity.getLocalClassName()+"-OnCreate";
Bundle snapshot = mMemoryTracer.addSnapshot(tag);
super.callActivityOnCreate(activity, icicle);
}
}

12th Kandroid Conference - www.kandroid.org

24
Tracing Performance Snapshots in kmemtracer
public class MemoryInstrumentation extends Instrumentation {
...

...

}

12th Kandroid Conference - www.kandroid.org

25
Tracing Performance Snapshots in kmemtracer
public class MemoryInstrumentation extends Instrumentation {
...
private MemoryTracer mMemoryTracer;
...
@Override
public void onCreate(Bundle arguments) {
...
mMemoryTracer = createMemoryTracer();
...
}
...

Create an instance
of MemoryTracer

...

}

12th Kandroid Conference - www.kandroid.org

26
Tracing Performance Snapshots in kmemtracer
public class MemoryInstrumentation extends Instrumentation {
...
private MemoryTracer mMemoryTracer;
...
@Override
public void onCreate(Bundle arguments) {
...
mMemoryTracer = createMemoryTracer();
...
}
...
@Override
public void callActivityOnCreate(Activity activity, Bundle icicle) {
String tag = activity.getLocalClassName()+"-OnCreate";
Bundle snapshot = mMemoryTracer.addSnapshot(tag);
...
}
...
}

Create an instance
of MemoryTracer

Add performance snapshot

12th Kandroid Conference - www.kandroid.org

27
MemoryTracer.addSnapshot
public Bundle addSnapshot(String label) {
...

12th Kandroid Conference - www.kandroid.org

28
MemoryTracer.addSnapshot
public Bundle addSnapshot(String label) {
...
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
...

Get usage data

12th Kandroid Conference - www.kandroid.org

29
MemoryTracer.addSnapshot
public Bundle addSnapshot(String label) {
...
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
...
Bundle snapshot = new Bundle();
snapshot.putString(METRIC_KEY_LABEL, label);
...
snapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax);
snapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated);
snapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree);
...

Get usage data

Save data to
a bundle

12th Kandroid Conference - www.kandroid.org

30
MemoryTracer.addSnapshot
public Bundle addSnapshot(String label) {
...
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
...
Bundle snapshot = new Bundle();
snapshot.putString(METRIC_KEY_LABEL, label);
...
snapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax);
snapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated);
snapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree);
...
if (mResultsWriter != null) {
mResultsWriter.writeTraceSnapshot(snapshot);
}
return snapshot;
}

Get usage data

Save data to
a bundle

Write date using
ResultsWriter

12th Kandroid Conference - www.kandroid.org

31
MemoryTracerCsvWriter$writeTraceSnapshot
public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter {
...

12th Kandroid Conference - www.kandroid.org

32
MemoryTracerCsvWriter$writeTraceSnapshot
public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter {
...
public MemoryTraceCsvWriter(String[] metricKeys) {
mMetricKeys = metricKeys;
}
...

Create an instance
with metrics to print

12th Kandroid Conference - www.kandroid.org

33
MemoryTracerCsvWriter$writeTraceSnapshot
public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter {
...
public MemoryTraceCsvWriter(String[] metricKeys) {
mMetricKeys = metricKeys;
}
...
private void openTraceFile(String filename) {
...
mTraceOut = new PrintStream(new FileOutputStream(traceFile));
...
}
...

Create an instance
with metrics to print

Open a trace file in
the sdcard at init

12th Kandroid Conference - www.kandroid.org

34
MemoryTracerCsvWriter$writeTraceSnapshot
public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter {
...
public MemoryTraceCsvWriter(String[] metricKeys) {
mMetricKeys = metricKeys;
}
...
private void openTraceFile(String filename) {
...
mTraceOut = new PrintStream(new FileOutputStream(traceFile));
...
}
...
@Override
public void writeTraceSnapshot(Bundle snapshot) {
PrintStream out = mTraceOut;
for (String key : mMetricKeys) {
out.print(snapshot.get(key));
out.print(',');
}
out.println();
out.flush();
}
...
}
12 Kandroid Conference - www.kandroid.org

Create an instance
with metrics to print

Open a trace file in
the sdcard at init
Write snapshot to
a line of the file

th

35
How to Use kmemtracer?

12th Kandroid Conference - www.kandroid.org

36
How to Use kmemtracer?
1. Create an Android Test Project for the trace package.

12th Kandroid Conference - www.kandroid.org

37
How to Use kmemtracer?
1. Create an Android Test Project for the trace package.
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.

12th Kandroid Conference - www.kandroid.org

38
How to Use kmemtracer?
1. Create an Android Test Project for the trace package.
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the Manifest file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.apis.test"
android:versionCode="1"
android:versionName="1.0">
<instrumentation
android:name="org.kandroid.memtracer.MemoryInstrumentation"
android:targetPackage="com.example.android.apis" />

<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher“>
<uses-library android:theme="android.text.runner“>
</application>
</manifest>
12th Kandroid Conference - www.kandroid.org

39
How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk

12th Kandroid Conference - www.kandroid.org

40
How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk

5. Start the instrumentation with ‘am instrument’ in the shell.
$
>
>
>

adb shell am instrument -e class 
com.example.android.apis.ApiDemos 
com.example.android.apis.tests/
org.kandroid.memtracer.MemoryInstrumentation

12th Kandroid Conference - www.kandroid.org

41
How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk

5. Start the instrumentation with ‘am instrument’ in the shell.
$
>
>
>

adb shell am instrument -e class 
com.example.android.apis.ApiDemos 
com.example.android.apis.tests/
org.kandroid.memtracer.MemoryInstrumentation

6. Do interact with the application.

12th Kandroid Conference - www.kandroid.org

42
How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk

5. Start the instrumentation with ‘am instrument’ in the shell.
$
>
>
>

adb shell am instrument -e class 
com.example.android.apis.ApiDemos 
com.example.android.apis.tests/
org.kandroid.memtracer.MemoryInstrumentation

6. Do interact with the application.
7. Pull the trace file ‘kmemtrace.csv’ from /sdcard/kmemtracer.
$ adb pull /sdcard/kmemtracer/kmemtrace.csv .

12th Kandroid Conference - www.kandroid.org

43
How to Use kmemtracer?
8. Open the trace file with Excel and create charts.

12th Kandroid Conference - www.kandroid.org

44
Contents
Why Automated Historical Performance Testing?

kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics

12th Kandroid Conference - www.kandroid.org

45
Automate Controlling UI
Application
Package

Control

Track

android.test.
Instrumentation
TestRunner

org.kandroid.
memtracer.Memory
Instrumentation

Test
Package

Trace
Package
12th Kandroid Conference - www.kandroid.org

46
Automate Controlling UI
Application
Package

Control

Track

android.test.
Instrumentation
TestRunner

org.kandroid.
memtracer.Memory
Instrumentation

Test
Package

Trace
Package
12th Kandroid Conference - www.kandroid.org

47
Automate Controlling UI
Application
Package

Control

Track

android.test.
Instrumentation
TestRunner

org.kandroid.
memtracer.Memory
Instrumentation

Test
Package

Trace
Package
12th Kandroid Conference - www.kandroid.org

48
Three Alternatives

12th Kandroid Conference - www.kandroid.org

49
Three Alternatives
Instrumentation
API Level 1 ~
Single activity
Framework APIs
White-box

http://developer.android.com/tools/testing/testing_android.html

12th Kandroid Conference - www.kandroid.org

50
Three Alternatives
Instrumentation
API Level 1 ~
Single activity
Framework APIs
White-box

Robotium
2010/01 ~
Multiple activities
High-level APIs
White-box & black-box

http://developer.android.com/tools/testing/testing_android.html
https://code.google.com/p/robotium/

12th Kandroid Conference - www.kandroid.org

51
Three Alternatives
Instrumentation
API Level 1 ~
Single activity
Framework APIs
White-box

Robotium

uiautomator

2010/01 ~
Multiple activities
High-level APIs
White-box & black-box

API Level 17 ~
Multiple processes
Simple APIs
Black-box

http://developer.android.com/tools/testing/testing_android.html
https://code.google.com/p/robotium/
http://developer.android.com/tools/testing/testing_ui.html
12th Kandroid Conference - www.kandroid.org

52
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

12th Kandroid Conference - www.kandroid.org

53
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

12th Kandroid Conference - www.kandroid.org

54
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

12th Kandroid Conference - www.kandroid.org

55
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

Scroll
down

12th Kandroid Conference - www.kandroid.org

56
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

Scroll
down

12th Kandroid Conference - www.kandroid.org

57
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

Scroll
down
Click

12th Kandroid Conference - www.kandroid.org

58
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

Scroll
down
Click

12th Kandroid Conference - www.kandroid.org

59
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

Scroll
down
Click

Click

12th Kandroid Conference - www.kandroid.org

60
Case Study: ApiDemos
https://github.com/snailee/deview-2013-samples

Click

Scroll
down
Click

Click

12th Kandroid Conference - www.kandroid.org

61
Controlling UI Using Instrumentation

12th Kandroid Conference - www.kandroid.org

62
Controlling UI Using Instrumentation
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos 
> –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest

12th Kandroid Conference - www.kandroid.org

63
Controlling UI Using Instrumentation
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos 
> –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest

2. Add a test class inheriting ActivityInstrumentationTestCase2.
public class ApiDemosInstrumentTest extends
ActivityInstrumentationTestCase2<ApiDemos> {
...
public ApiDemosInstrumentTest() {
super(ApiDemos.class);
}

12th Kandroid Conference - www.kandroid.org

64
Controlling UI Using Instrumentation
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos 
> –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest

2. Add a test class inheriting ActivityInstrumentationTestCase2.
public class ApiDemosInstrumentTest extends
ActivityInstrumentationTestCase2<ApiDemos> {
...
public ApiDemosInstrumentTest() {
super(ApiDemos.class);
}

3. Add a test method and launch the activity.
public void testNavigate() {
final ApiDemos apiDemos = getActivity();
...
}

12th Kandroid Conference - www.kandroid.org

65
Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate() {
...

12th Kandroid Conference - www.kandroid.org

66
Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate()
...
final ListView demoList
final View graphicsDemo
assertNotNull("Graphics

{

Find a view
to control

= apiDemos.getListView();
= getChildViewByText(demoList, "Graphics");
demo should exist", graphicsDemo);

12th Kandroid Conference - www.kandroid.org

67
Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate()
...
final ListView demoList
final View graphicsDemo
assertNotNull("Graphics

{

Find a view
to control

= apiDemos.getListView();
= getChildViewByText(demoList, "Graphics");
demo should exist", graphicsDemo);

apiDemos.runOnUiThread(new Runnable() {
public void run() {
int pos = demoList.getPositionForView(graphicsDemo);
demoList.smoothScrollToPosition(pos);
demoList.setSelection(pos);
demoList.performItemClick(graphicsDemo, pos,
graphicsDemo.getId());
}
});
...

Act on
the view

12th Kandroid Conference - www.kandroid.org

68
Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate()
...
final ListView demoList
final View graphicsDemo
assertNotNull("Graphics

{

Find a view
to control

= apiDemos.getListView();
= getChildViewByText(demoList, "Graphics");
demo should exist", graphicsDemo);

apiDemos.runOnUiThread(new Runnable() {
public void run() {
int pos = demoList.getPositionForView(graphicsDemo);
demoList.smoothScrollToPosition(pos);
demoList.setSelection(pos);
demoList.performItemClick(graphicsDemo, pos,
graphicsDemo.getId());
}
});
...

Act on
the view

12th Kandroid Conference - www.kandroid.org

69
Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {

12th Kandroid Conference - www.kandroid.org

70
Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
View view = null;
int count = listView.getCount();
Log.e(TAG, “no. children = " + count);
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);

Iterate through
child views

12th Kandroid Conference - www.kandroid.org

71
Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
View view = null;
int count = listView.getCount();
Log.e(TAG, “no. children = " + count);
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
Log.e(TAG, i + "-th text view is " + textView);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
}
return view;
}

Iterate through
child views

Compare
texts

12th Kandroid Conference - www.kandroid.org

72
Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
View view = null;
int count = listView.getCount();
Log.e(TAG, “no. children = " + count);
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
Log.e(TAG, i + "-th text view is " + textView);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
}
return view;
}
com.example.android.apis.instrument.test.ApiDemosInstrumentTest:
INSTRUMENTATION_RESULT: shortMsg=junit.framework.AssertionFailedError
INSTRUMENTATION_RESULT: longMsg=
junit.framework.AssertionFailedError: OpenGL ES demo should exist
INSTRUMENTATION_CODE: 0

Iterate through
child views

Compare
texts

12th Kandroid Conference - www.kandroid.org

73
Controlling UI Using Instrumentation
4. Find and act on a control: Revised getChildViewByText.
private View getChildViewByText(final ListView listView, String text) {
...
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
if (textView == null) {
final int lastPos = listView.getLastVisiblePosition();
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
listView.smoothScrollToPosition(lastPos + 5, lastPos);
}
});
getInstrumentation().waitForIdleSync();
i = listView.getFirstVisiblePosition();
}
}
return view;
}
12th Kandroid Conference - www.kandroid.org

74
Controlling UI Using Instrumentation
4. Find and act on a control: Revised getChildViewByText.
private View getChildViewByText(final ListView listView, String text) {
...
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
if (textView == null) {
final int lastPos = listView.getLastVisiblePosition();
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
listView.smoothScrollToPosition(lastPos + 5, lastPos);
}
});
getInstrumentation().waitForIdleSync();
i = listView.getFirstVisiblePosition();
}
}
return view;
}

Scroll down

12th Kandroid Conference - www.kandroid.org

75
Controlling UI Using Instrumentation
4. Find and act on a control: getPositionForChildViewByText.
private int getPositionForChildViewByText(ListView listView, String text) {
ListAdapter listAdapter = listView.getAdapter();
int count = listAdapter.getCount();
Log.e(TAG, "children: " + count);
for (int i = 0; i < count; i++) {
String itemText = (String) ((Map)listAdapter.getItem(i)).get("title");
Log.e(TAG, i + "-th text item " + itemText);
if (itemText != null && itemText.equals(text)) {
return i;
}
}
return -1;
}
...
final ListView graphicsDemoList = graphicsDemoActivity.getListView();
int pos = getPositionForChildViewByText(graphicsDemoList, "OpenGL ES");
assertTrue("Cannot find OpenGL ES", pos != -1);
...
12th Kandroid Conference - www.kandroid.org

76
Controlling UI Using Instrumentation
4. Find and act on a control: getPositionForChildViewByText.
private int getPositionForChildViewByText(ListView listView, String text) {
ListAdapter listAdapter = listView.getAdapter();
int count = listAdapter.getCount();
Log.e(TAG, "children: " + count);
for (int i = 0; i < count; i++) {
String itemText = (String) ((Map)listAdapter.getItem(i)).get("title");
Log.e(TAG, i + "-th text item " + itemText);
if (itemText != null && itemText.equals(text)) {
return i;
}
}
return -1;
}
...
final ListView graphicsDemoList = graphicsDemoActivity.getListView();
int pos = getPositionForChildViewByText(graphicsDemoList, "OpenGL ES");
assertTrue("Cannot find OpenGL ES", pos != -1);
...
12th Kandroid Conference - www.kandroid.org

77
Controlling UI Using Instrumentation
5. Monitor a new Activity to launch.
public void testNavigate() {
...
Instrumentation.ActivityMonitor graphicsDemoActivityMonitor =
getInstrumentation().addMonitor(
ApiDemos.class.getName(), null, false);
final ApiDemos graphicsDemoActivity =
(ApiDemos) graphicsDemoActivityMonitor.waitForActivity();
assertNotNull("Graphics Demo (ApiDemos) activity should not be null",
graphicsDemoActivity);
...

12th Kandroid Conference - www.kandroid.org

78
Controlling UI Using Instrumentation
5. Monitor a new Activity to launch.
public void testNavigate() {
...
Instrumentation.ActivityMonitor graphicsDemoActivityMonitor =
getInstrumentation().addMonitor(
ApiDemos.class.getName(), null, false);
final ApiDemos graphicsDemoActivity =
(ApiDemos) graphicsDemoActivityMonitor.waitForActivity();
assertNotNull("Graphics Demo (ApiDemos) activity should not be null",
graphicsDemoActivity);
...

6. Iterate step 4 & 5.

12th Kandroid Conference - www.kandroid.org

79
Controlling UI Using Instrumentation
7. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk

12th Kandroid Conference - www.kandroid.org

80
Controlling UI Using Instrumentation
7. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk

8. Run the test and see the result.
$ adb shell am instrument -w 
> com.example.android.apis.instrument.test/
> android.test.InstrumentationTestRunner

12th Kandroid Conference - www.kandroid.org

81
Controlling UI Using Instrumentation
7. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk

8. Run the test and see the result.
$ adb shell am instrument -w 
> com.example.android.apis.instrument.test/
> android.test.InstrumentationTestRunner

$ ant test

12th Kandroid Conference - www.kandroid.org

82
Controlling UI Using Robotium

12th Kandroid Conference - www.kandroid.org

83
Controlling UI Using Robotium
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos 
> –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest

12th Kandroid Conference - www.kandroid.org

84
Controlling UI Using Robotium
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos 
> –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest

2. Add ‘robotium-solo-<ver>.jar’ in the ‘libs’ directory.

12th Kandroid Conference - www.kandroid.org

85
Controlling UI Using Robotium
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos 
> –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest

2. Add ‘robotium-solo-<ver>.jar’ in the ‘libs’ directory.
3. Add a test class inheriting ActivityInstrumentationTestCase2.
public class ApiDemosRobotiumTest extends
ActivityInstrumentationTestCase2<ApiDemos> {
...
public ApiDemosRobotiumTest() {
super(ApiDemos.class);
}
...

12th Kandroid Conference - www.kandroid.org

86
Controlling UI Using Robotium
4. Create an instance of Solo in the setUp method and
close open activities in the tearDown method.
...
private Solo solo;
...
@Override
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
...

12th Kandroid Conference - www.kandroid.org

87
Controlling UI Using Robotium
4. Find and act on a control.
public void testNavigate() {
solo.assertCurrentActivity("Should be on ApiDemos",
ApiDemos.class);

solo.clickOnText("^Graphics$", 1, true);
solo.assertCurrentActivity("Should be on a new ApiDemos",
ApiDemos.class, true);
solo.clickOnText("^OpenGL ES$", 1, true);
solo.assertCurrentActivity("Should be on a new ApiDemos",
ApiDemos.class, true);

solo.clickOnText("^Kube$", 1, true);
solo.assertCurrentActivity("Should be on a Kube",
Kube.class, true);
solo.sleep(3000);
}

12th Kandroid Conference - www.kandroid.org

88
Controlling UI Using Robotium
6. Build and Install the test package.
$ cd ApiDemosRobotiumTest
$ ant debug
$ adb install –r bin/ApiDemosRobotiumTest-debug.apk

12th Kandroid Conference - www.kandroid.org

89
Controlling UI Using Robotium
6. Build and Install the test package.
$ cd ApiDemosRobotiumTest
$ ant debug
$ adb install –r bin/ApiDemosRobotiumTest-debug.apk

7. Run the test and see the result.
$ adb shell am instrument -w 
> com.example.android.apis.robotium.test/
> android.test.InstrumentationTestRunner

12th Kandroid Conference - www.kandroid.org

90
Controlling UI Using Robotium
6. Build and Install the test package.
$ cd ApiDemosRobotiumTest
$ ant debug
$ adb install –r bin/ApiDemosRobotiumTest-debug.apk

7. Run the test and see the result.
$ adb shell am instrument -w 
> com.example.android.apis.robotium.test/
> android.test.InstrumentationTestRunner

$ ant test

12th Kandroid Conference - www.kandroid.org

91
Controlling UI Using uiautomator
1. Create an Java Project for the test jar.

12th Kandroid Conference - www.kandroid.org

92
Controlling UI Using uiautomator
1. Create an Java Project for the test jar.
2. Add ‘android.jar’ and ‘uiautomator.jar’ in the build path.

12th Kandroid Conference - www.kandroid.org

93
Controlling UI Using uiautomator
1. Create an Java Project for the test jar.
2. Add ‘android.jar’ and ‘uiautomator.jar’ in the build path.
3. Add a test class inheriting UiAutomatorTestCase.
public class ApiDemosUiAutoTest extends UiAutomatorTestCase {
...
}

12th Kandroid Conference - www.kandroid.org

94
Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {

12th Kandroid Conference - www.kandroid.org

95
Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();

Press home button

12th Kandroid Conference - www.kandroid.org

96
Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();

12th Kandroid Conference - www.kandroid.org

Press home button
Click ‘All Apps’
button

97
Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();

Press home button
Click ‘All Apps’
button

UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();

Click ‘Apps’ tab

12th Kandroid Conference - www.kandroid.org

98
Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();

Press home button
Click ‘All Apps’
button

UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();

Click ‘Apps’ tab

UiScrollable appList = new UiScrollable(
new UiSelector().scrollable(true));
appList.setAsHorizontalList();
UiObject apiDemos = appList.getChildByText(
new UiSelector().className(TextView.class.getName()), "API Demos");
apiDemos.clickAndWaitForNewWindow();

Click ‘ApiDemos’
icon

12th Kandroid Conference - www.kandroid.org

99
Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();

Press home button
Click ‘All Apps’
button

UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();

Click ‘Apps’ tab

UiScrollable appList = new UiScrollable(
new UiSelector().scrollable(true));
appList.setAsHorizontalList();
UiObject apiDemos = appList.getChildByText(
new UiSelector().className(TextView.class.getName()), "API Demos");
apiDemos.clickAndWaitForNewWindow();

Click ‘ApiDemos’
icon

Validate the launch
of ‘ApiDemos’

UiObject apiDemosPackage = new UiObject(
new UiSelector().packageName("com.example.android.apis"));
assertTrue("Should be on ApiDemos", apiDemosPackage.exists());
...
12th Kandroid Conference - www.kandroid.org

100
Controlling UI Using uiautomator
5. Find and act on a control.
...
UiScrollable demoList = new UiScrollable(
new UiSelector().className("android.widget.ListView"));
UiObject graphicsDemo = demoList.getChildByText(
new UiSelector().className(TextView.class.getName()), “Graphics");
graphicsDemo.clickAndWaitForNewWindow();

UiObject alphaBitmapDemo = new UiObject(
new UiSelector().text(“AlphaBitmap"));
assertTrue(“AlphaBitmap should be visible", alpahBitmapDemo.exists());
...

12th Kandroid Conference - www.kandroid.org

101
Controlling UI Using uiautomator
5. Find and act on a control.
...
UiScrollable demoList = new UiScrollable(
new UiSelector().className("android.widget.ListView"));
UiObject graphicsDemo = demoList.getChildByText(
new UiSelector().className(TextView.class.getName()), “Graphics");
graphicsDemo.clickAndWaitForNewWindow();

UiObject alphaBitmapDemo = new UiObject(
new UiSelector().text(“AlphaBitmap"));
assertTrue(“AlphaBitmap should be visible", alpahBitmapDemo.exists());
...

6. Iterate step 5.

12th Kandroid Conference - www.kandroid.org

102
Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$

android create uitest-project --name ApiDemosUiAutoTest 
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build

12th Kandroid Conference - www.kandroid.org

103
Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$

android create uitest-project --name ApiDemosUiAutoTest 
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build

8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/

12th Kandroid Conference - www.kandroid.org

104
Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$

android create uitest-project --name ApiDemosUiAutoTest 
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build

8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/

9. Run the test and view the test result.
$ adb shell uiautomator runtest ApiDemosUiAutoTest.jar 
> –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest

12th Kandroid Conference - www.kandroid.org

105
Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$

android create uitest-project --name ApiDemosUiAutoTest 
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build

8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/

9. Run the test and view the test result.
$ adb shell uiautomator runtest ApiDemosUiAutoTest.jar 
> –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest

$ ant test
12th Kandroid Conference - www.kandroid.org

106
Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$

android create uitest-project --name ApiDemosUiAutoTest 
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build

8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/

9. Run the test and view the test result.
$ adb shell uiautomator runtest ApiDemosUiAutoTest.jar 
> –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest

$ ant test
12th Kandroid Conference - www.kandroid.org

107
Doing both Controlling and Tracking

12th Kandroid Conference - www.kandroid.org

108
Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org

109
Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org

110
Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org

111
Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org

112
Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.

12th Kandroid Conference - www.kandroid.org

113
Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.

12th Kandroid Conference - www.kandroid.org

114
Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
4. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk

12th Kandroid Conference - www.kandroid.org

115
Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
4. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk

5. Run the test and see the result.
$ adb shell am instrument -w 
> com.example.android.apis.instrument.test/
> org.kandroid.memtracer.MemoryInstrumentation

12th Kandroid Conference - www.kandroid.org

116
Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
4. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk

5. Run the test and see the result.
$ adb shell am instrument -w 
> com.example.android.apis.instrument.test/
> org.kandroid.memtracer.MemoryInstrumentation

6. Pull the trace file ‘kmemtrace.csv’ from /sdcard/kmemtracer.
$ adb pull /sdcard/kmemtracer/kmemtrace.csv .

12th Kandroid Conference - www.kandroid.org

117
Comparison
Instrument

Robotium

uiautomator

Compatibility

O

O

X

Multi-activities



O

O

Multi-processes

X

X

O

Ease of APIs

X

O



Black box

X



O

12th Kandroid Conference - www.kandroid.org

118
Contents
Why Automated Historical Performance Testing?

kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics

12th Kandroid Conference - www.kandroid.org

119
What to Measure?
Rendering (or GUI) Performance
Frame Rate (FPS), Frame Time , Jankiness, Input Latency, …

Resource Consumption
Memory, CPU, I/O (Disk, Network), Battery, …

Network Performance
Response time, Throughput, …
…

12th Kandroid Conference - www.kandroid.org

120
What to Measure?
Rendering (or GUI) Performance
Frame Rate (FPS), Frame Time , Jankiness, Input Latency, …

Resource Consumption
Memory, CPU, I/O (Disk, Network), Battery, …

Network Performance
Response time, Throughput, …
…

12th Kandroid Conference - www.kandroid.org

121
How to Measure Resource Consumption?

12th Kandroid Conference - www.kandroid.org

122
How to Measure Resource Consumption?

cmds

API

12th Kandroid Conference - www.kandroid.org

123
How to Measure Resource Consumption?

cmds

API

Public

Internal

12th Kandroid Conference - www.kandroid.org

124
How to Measure Resource Consumption?

cmds

API

Public

Internal

Android

12th Kandroid Conference - www.kandroid.org

Linux

125
How to Measure Resource Consumption?

cmds

API

Public

Internal

Android

Easy

Linux

Flexible

12th Kandroid Conference - www.kandroid.org

126
Measuring Memory Usage

12th Kandroid Conference - www.kandroid.org

127
Measuring Memory Usage
Public
android.app.ActivityManager.MemoryInfo
android.os.Debug
android.os.Debug.MemoryInfo

12th Kandroid Conference - www.kandroid.org

128
Measuring Memory Usage
Public

Internal

android.app.ActivityManager.MemoryInfo
android.os.Debug
android.os.Debug.MemoryInfo
dalvik.system.VMDebug

12th Kandroid Conference - www.kandroid.org

129
Measuring Memory Usage
Public

Internal

Android

android.app.ActivityManager.MemoryInfo
android.os.Debug
android.os.Debug.MemoryInfo
dalvik.system.VMDebug
adb shell dumpsys meminfo [pid|pname]
adb shell dumpsys gfxinfo [pid|pname]
adb shell procrank

12th Kandroid Conference - www.kandroid.org

130
Measuring Memory Usage
Public

Internal

Android

Linux

android.app.ActivityManager.MemoryInfo
android.os.Debug
android.os.Debug.MemoryInfo
dalvik.system.VMDebug
adb shell dumpsys meminfo [pid|pname]
adb shell dumpsys gfxinfo [pid|pname]
adb shell procrank
adb shell cat /proc/meminfo
adb shell cat /proc/<pid>/[s]maps
adb shell cat /proc/vmstat
adb shell top
adb shell ps
12th Kandroid Conference - www.kandroid.org

131
Measuring Memory Usage: dumpsys meminfo
$ adb shell dumpsys meminfo com.example.android.apis
Applications Memory Usage (kB):
Uptime: 93065 Realtime: 93065

** MEMINFO in pid 1259 [com.example.android.apis] **
native
dalvik
other
total
size:
3548
5831
N/A
9379
allocated:
3475
3335
N/A
6810
free:
48
2496
N/A
2544
(Pss):
699
382
4889
5970
(shared dirty):
1500
1876
8356
11732
(priv dirty):
628
40
2472
3140
...

GB (API Level 10)

12th Kandroid Conference - www.kandroid.org

132
Measuring Memory Usage: dumpsys meminfo
$ adb shell dumpsys meminfo com.example.android.apis
Applications Memory Usage (kB):
Uptime: 93065 Realtime: 93065

** MEMINFO in pid 1259 [com.example.android.apis] **
native
dalvik
other
total
size:
3548
5831
N/A
9379
allocated:
3475
3335
N/A
6810
free:
48
2496
N/A
2544
(Pss):
699
382
4889
5970
(shared dirty):
1500
1876
8356
11732
(priv dirty):
628
40
2472
3140
...

GB (API Level 10)

12th Kandroid Conference - www.kandroid.org

133
Measuring Memory Usage: dumpsys meminfo
$ adb shell dumpsys meminfo com.example.android.apis
...
** MEMINFO in pid 1875 [com.example.android.apis] **
Shared Private
Heap
Heap
Pss
Dirty
Dirty
Size
Alloc
-------------------------Native
1377
1256
1300
12084
7332
Dalvik
5274
5476
4952
6260
5712
Stack
76
12
76
Cursor
0
0
0
Ashmem
0
0
0
Other dev
4
20
0
.so mmap
1526
4836
592
.jar mmap
0
0
0
.apk mmap
267
0
0
.ttf mmap
5
0
0
.dex mmap
1085
0
0
Other mmap
18
8
4
Unknown
824
0
824
TOTAL
10456
11608
7748
18344
13044
...

Heap
Free
-----567
548

1115

JB (API Level 18)
12th Kandroid Conference - www.kandroid.org

134
Measuring Memory Usage: dumpsys meminfo
$ adb shell dumpsys meminfo com.example.android.apis
...
** MEMINFO in pid 1875 [com.example.android.apis] **
Shared Private
Heap
Heap
Pss
Dirty
Dirty
Size
Alloc
-------------------------Native
1377
1256
1300
12084
7332
Dalvik
5274
5476
4952
6260
5712
Stack
76
12
76
Cursor
0
0
0
Ashmem
0
0
0
Other dev
4
20
0
.so mmap
1526
4836
592
.jar mmap
0
0
0
.apk mmap
267
0
0
.ttf mmap
5
0
0
.dex mmap
1085
0
0
Other mmap
18
8
4
Unknown
824
0
824
TOTAL
10456
11608
7748
18344
13044
...

Heap
Free
-----567
548

1115

JB (API Level 18)
12th Kandroid Conference - www.kandroid.org

135
https://android.googlesource.com/platform/frameworks/base.git/+/0e3328fbdd3845b0e2bec364e951498eaee6b079
12th Kandroid Conference - www.kandroid.org

136
How ‘dumpsys meminfo’ works?
adb shell dumpsys meminfo [-a] [-oom] [-process]

12th Kandroid Conference - www.kandroid.org

137
How ‘dumpsys meminfo’ works?
adb shell dumpsys meminfo [-a] [-oom] [-process]
com.android.server.am.
ActivityManagerService

12th Kandroid Conference - www.kandroid.org

138
How ‘dumpsys meminfo’ works?
adb shell dumpsys meminfo [-a] [-oom] [-process]
com.android.server.am.
ActivityManagerService

android.app.ActivityThread.
android.app.ActivityThread.
android.app.ActivityThread.
ApplicationThread
ApplicationThread
ApplicationThread
android.os
Debug

12th Kandroid Conference - www.kandroid.org

139
How ‘dumpsys meminfo’ works?
adb shell dumpsys meminfo [-a] [-oom] [-process]
com.android.server.am.
ActivityManagerService

android.app.ActivityThread.
android.app.ActivityThread.
android.app.ActivityThread.
ApplicationThread
ApplicationThread
ApplicationThread
android.os
Debug

12th Kandroid Conference - www.kandroid.org

140
How ‘dumpsys meminfo’ works?
adb shell dumpsys meminfo [-a] [-oom] [-process]
com.android.server.am.
ActivityManagerService

android.app.ActivityThread.
android.app.ActivityThread.
android.app.ActivityThread.
ApplicationThread
ApplicationThread
ApplicationThread
android.os
Debug
getNativeHeap*()

getMemoryInfo()

mallinfo()

/proc/<pid>/smaps

12th Kandroid Conference - www.kandroid.org

141
How ‘dumpsys meminfo’ works?
android.app.ActivityThread.ApplicationThread.dumpMemInfo()
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;

Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
Runtime runtime = Runtime.getRuntime();

long dalvikMax = runtime.totalMemory() / 1024;
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;

12th Kandroid Conference - www.kandroid.org

142
How ‘dumpsys meminfo’ works?
android.app.ActivityThread.ApplicationThread.dumpMemInfo()
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;

Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
Runtime runtime = Runtime.getRuntime();

long dalvikMax = runtime.totalMemory() / 1024;
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;

android.os.Debug.getNativeHeap*()
struct mallinfo info = mallinfo();
(jlong) info.usmblks; // Debug.getNativeHeapSize()
(jlong) info.uordblks; // Debug.getNativeHeapAllocatedSize()
(jlong) info.fordblks; // Debug.getNativeHeapFreeSize()

12th Kandroid Conference - www.kandroid.org

143
How ‘dumpsys meminfo’ works?
struct mallinfo {
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
};

arena;
ordblks;
smblks;
hblks;
hblkhd;
usmblks;
fsmblks;
uordblks;
fordblks;
keepcost;

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

non-mmapped space allocated from system */
number of free chunks */
always 0 */
always 0 */
space in mmapped regions */
maximum total allocated space */
always 0 */
total allocated space */
total free space */
releasable (via malloc_trim) space */

bioniclibcupstream-dlmallocmalloc.c

2

4
3

1

① Total allocated = uordblks
② Total free = fordblks
③ Footprint = uordblks + fordblks
④ Max footprint = usmblks

12th Kandroid Conference - www.kandroid.org

144
Measuring CPU Usage

12th Kandroid Conference - www.kandroid.org

145
Measuring CPU Usage
Public
android.os.Process
android.os.Debug.InstructionCount

12th Kandroid Conference - www.kandroid.org

146
Measuring CPU Usage
Public

Internal

android.os.Process
android.os.Debug.InstructionCount
com.android.internal.os.ProcessStats

12th Kandroid Conference - www.kandroid.org

147
Measuring CPU Usage
Public

Internal

Android

android.os.Process
android.os.Debug.InstructionCount
com.android.internal.os.ProcessStats

adb shell dumpsys cpuinfo

12th Kandroid Conference - www.kandroid.org

148
Measuring CPU Usage
Public

Internal

Android

Linux

android.os.Process
android.os.Debug.InstructionCount
com.android.internal.os.ProcessStats

adb shell dumpsys cpuinfo
adb shell cat /proc/stat
adb shell cat /proc/<pid>/stat
adb shell top

12th Kandroid Conference - www.kandroid.org

149
Measuring CPU Usage: dumpsys cpuinfo
$ adb shell dumpsys cpuinfo
Load: 0.0 / 0.01 / 0.05
CPU usage from 27006ms to 5405ms ago:
1.1% 1421/com.android.launcher: 0.3% user + 0.8% kernel / faults:
2187 minor
2.4% 1225/system_server: 0.4% user + 1.9% kernel / faults: 2030 minor
0.1% 949/surfaceflinger: 0% user + 0.1% kernel / faults: 3 minor
0% 952/mediaserver: 0% user + 0% kernel / faults: 8 minor
0% 959/adbd: 0% user + 0% kernel / faults: 11 minor
0% 1295/com.android.systemui: 0% user + 0% kernel / faults: 5 minor
+0% 1901/com.example.android.apis: 0% user + 0% kernel
56% TOTAL: 10% user + 45% kernel + 0.7% softirq

12th Kandroid Conference - www.kandroid.org

150
How ‘dumpsys cpuinfo’ works?
adb shell dumpsys cpuinfo

12th Kandroid Conference - www.kandroid.org

151
How ‘dumpsys cpuinfo’ works?
adb shell dumpsys cpuinfo
com.android.server.am.
ActivityManagerService

12th Kandroid Conference - www.kandroid.org

152
How ‘dumpsys cpuinfo’ works?
adb shell dumpsys cpuinfo
com.android.server.am.
ActivityManagerService
com.android.internal.os
ProcessStats

12th Kandroid Conference - www.kandroid.org

153
How ‘dumpsys cpuinfo’ works?
adb shell dumpsys cpuinfo
com.android.server.am.
ActivityManagerService
com.android.internal.os
ProcessStats
com.android.internal.os
com.android.internal.os
com.android.internal.os
ProcessStats.Stats
ProcessStats.Stats
ProcessStats.Stats

12th Kandroid Conference - www.kandroid.org

154
How ‘dumpsys cpuinfo’ works?
adb shell dumpsys cpuinfo
com.android.server.am.
ActivityManagerService
android.os
Process

com.android.internal.os
ProcessStats
com.android.internal.os
com.android.internal.os
com.android.internal.os
ProcessStats.Stats
ProcessStats.Stats
ProcessStats.Stats

android_util_
Process.cpp
/proc/stat
/proc/loadavg
/proc/<pid>/stat
/proc/<ppid>/task/<pid>/stat

12th Kandroid Conference - www.kandroid.org

155
How ‘dumpsys cpuinfo’ works?
procfs (or the proc filesystem) is a special filesystem in UNIXlike operating systems that presents information about processes
and other system information in a hierarchical file-like structure,
providing a more convenient and standardized method for
dynamically accessing process data held in the kernel than
traditional tracing methods or direct access to kernel memory.
http://en.wikipedia.org/wiki/Procfs

12th Kandroid Conference - www.kandroid.org

156
How ‘dumpsys cpuinfo’ works?
procfs (or the proc filesystem) is a special filesystem in UNIXlike operating systems that presents information about processes
and other system information in a hierarchical file-like structure,
providing a more convenient and standardized method for
dynamically accessing process data held in the kernel than
traditional tracing methods or direct access to kernel memory.
http://en.wikipedia.org/wiki/Procfs

http://manpages.courier-mta.org/htmlman5/proc.5.html
12th Kandroid Conference - www.kandroid.org

157
Measuring I/O Usage

12th Kandroid Conference - www.kandroid.org

158
Measuring I/O Usage
Public
android.net.TrafficStats

12th Kandroid Conference - www.kandroid.org

159
Measuring I/O Usage
Public

Internal

android.net.TrafficStats
android.net.NetworkStats
android.net.NetworkStatsHistory
com.android.internal.net.NetworkStatsFactory

12th Kandroid Conference - www.kandroid.org

160
Measuring I/O Usage
Public

Internal

Android

android.net.TrafficStats
android.net.NetworkStats
android.net.NetworkStatsHistory
com.android.internal.net.NetworkStatsFactory
adb shell dumpsys netstats
adb shell dumpsys diskstats

12th Kandroid Conference - www.kandroid.org

161
Measuring I/O Usage
Public

Internal

Android

Linux

android.net.TrafficStats
android.net.NetworkStats
android.net.NetworkStatsHistory
com.android.internal.net.NetworkStatsFactory
adb shell dumpsys netstats
adb shell dumpsys diskstats

/proc/net/*

12th Kandroid Conference - www.kandroid.org

162
Measuring Network IO Usage: dumpsys netstats
$ adb shell dumpsys netstats
Active interfaces:
iface=eth0 ident=[[type=MOBILE, subType=COMBINED, subscriberId=310260000000000]]
Dev stats:
Pending bytes: 43783
History since boot:
ident=[[type=MOBILE_HIPRI, subType=COMBINED, subscriberId=310260000000000],
[type=MOBILE, subType=COMBINED, subscriberId=310260000000000]] uid=-1 set=ALL
tag=0x0
NetworkStatsHistory: bucketDuration=3600000
bucketStart=1382443200000 activeTime=4813 rxBytes=17410 rxPackets=203
txBytes=25579 txPackets=173 operations=0
...
Xt stats:
Pending bytes: 37557
History since boot:
ident=[[type=MOBILE_HIPRI, subType=COMBINED, subscriberId=310260000000000],
[type=MOBILE, subType=COMBINED, subscriberId=310260000000000]] uid=-1 set=ALL
tag=0x0
...
UID stats:
...
UID tag stats:
...

12th Kandroid Conference - www.kandroid.org

163
How ‘dumpsys netstats’ works?
adb shell dumpsys netstats [--full] [--uid] [--tag]

12th Kandroid Conference - www.kandroid.org

164
How ‘dumpsys netstats’ works?
adb shell dumpsys netstats [--full] [--uid] [--tag]
com.android.server.net.
NetworkStatsService

12th Kandroid Conference - www.kandroid.org

165
How ‘dumpsys netstats’ works?
adb shell dumpsys netstats [--full] [--uid] [--tag]
com.android.server.net.
NetworkStatsService
com.android.server.net
com.android.server.net
com.android.server.net
NetworkStatsRecorder
NetworkStatsRecorder
com.android.server.net
NetworkStatsRecorder
NetworkStatsRecorder

12th Kandroid Conference - www.kandroid.org

166
How ‘dumpsys netstats’ works?
adb shell dumpsys netstats [--full] [--uid] [--tag]
com.android.server.net.
NetworkStatsService
com.android.server.net
com.android.server.net
com.android.server.net
NetworkStatsRecorder
NetworkStatsRecorder
com.android.server.net
NetworkStatsRecorder
NetworkStatsRecorder
com.android.server.net
NetworkStatsCollection
android.net
android.net
NetworkStatsHistory
android.net
NetworkStatsHistory
NetworkStatsHistory
12th Kandroid Conference - www.kandroid.org

167
How ‘dumpsys netstats’ works?
adb shell dumpsys netstats [--full] [--uid] [--tag]
com.android.server
NetworkManagementService

com.android.server.net.
NetworkStatsService
com.android.server.net
com.android.server.net
com.android.server.net
NetworkStatsRecorder
NetworkStatsRecorder
com.android.server.net
NetworkStatsRecorder
NetworkStatsRecorder
com.android.server.net
NetworkStatsCollection
android.net
android.net
NetworkStatsHistory
android.net
NetworkStatsHistory
NetworkStatsHistory

com.android.internal.net
NetworkStatsFactory
/proc/net/xt_qtaguid/iface_stat_all
/proc/net/xt_qtaguid/iface_stat_fmt
/proc/net/xt_qtaguid/stats

12th Kandroid Conference - www.kandroid.org

android.net
NetworkStats
168
How ‘dumpsys netstats’ works?
com.android.server.net.NetworkStatsService.DefaultNetworkStatsSettings
@Override
public Config getDevConfig() {
return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
}
@Override
public Config getXtConfig() {
return getDevConfig();
}
@Override
public Config getUidConfig() {
return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
}
@Override
public Config getUidTagConfig() {
return new Config(getSecureLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 *
HOUR_IN_MILLIS),
getSecureLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
}
12th Kandroid Conference - www.kandroid.org

169
How ‘dumpsys netstats’ works?
Dev: IP + Non IP layer traffic
$ adb shell cat /proc/net/xt_qtaguid/iface_stat_all
eth0 1 0 0 0 0 220609 3228 2891157 2995

Xt: Only IP layer traffic
$ adb shell cat /proc/net/xt_qtaguid/iface_stat_fmt
ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes
total_skb_tx_packets
eth0 163781 3231 2846738 2994

Uid: UID level details
$ adb shell cat /proc/net/xt_qtaguid/stats
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes
tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets
rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes
tx_udp_packets tx_other_bytes tx_other_packets
2 eth0 0x0 0 0 163335 3226 2846228 2988 161473 3222 1862 4 0 0 2845850 2982
266 4 112 2
3 eth0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 eth0 0x0 1000 0 819 11 965 12 667 9 152 2 0 0 813 10 152 2 0 0
5 eth0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
12th Kandroid Conference - www.kandroid.org

170
Measuring Battery Usage

12th Kandroid Conference - www.kandroid.org

171
Measuring Battery Usage
Public
android.os.BatteryManager

12th Kandroid Conference - www.kandroid.org

172
Measuring Battery Usage
Public

Internal

android.os.BatteryManager
android.os.BatteryStats
com.android.internal.os.BatteryStatsImpl
com.android.internal.os.PowerProfile
com.android.server.os.BatteryStatsService

12th Kandroid Conference - www.kandroid.org

173
Measuring Battery Usage
Public

Internal

Android

android.os.BatteryManager
android.os.BatteryStats
com.android.internal.os.BatteryStatsImpl
com.android.internal.os.PowerProfile
com.android.server.os.BatteryStatsService

adb shell dumpsys battery
adb shell dumpsys batteryinfo

12th Kandroid Conference - www.kandroid.org

174
Measuring Battery Usage
Public

Internal

Android

Linux

android.os.BatteryManager
android.os.BatteryStats
com.android.internal.os.BatteryStatsImpl
com.android.internal.os.PowerProfile
com.android.server.os.BatteryStatsService

adb shell dumpsys battery
adb shell dumpsys batteryinfo

None (?)

12th Kandroid Conference - www.kandroid.org

175
Measuring Battery Usage: dumpsys batteryinfo
$ adb shell dumpsys batteryinfo
Battery History:
-1d00h43m02s057ms START
-1d00h40m00s730ms 050 20080002 status=charging health=good plug=ac temp=0 volt=0
+plugged +sensor brightness=medium
-1d00h39m57s332ms 050 60080002 +wake_lock
-1d00h39m57s202ms 050 60080302 phone_state=off
...
Per-PID Stats:
PID 1227 wake time: +3s445ms
PID 1227 wake time: +199ms
...
Statistics since last charge:
System starts: 29, currently on battery: false
Time on battery: 0ms (0.0%) realtime, 0ms (0.0%) uptime
Total run time: 1d 2h 1m 3s 606ms realtime, 1d 2h 1m 3s 603ms uptime,
...
#1000:
User activity: 26 other, 27 button, 93 touch
Sensor 0: (not used)
Apk com.android.keychain:
(nothing executed)
...
Statistics since last unplugged:
Time on battery: 0ms (0.0%) realtime, 0ms (0.0%) uptime
...
12th Kandroid Conference - www.kandroid.org

176
How ‘dumpsys batteryinfo’ works?
adb shell dumpsys batteryinfo

12th Kandroid Conference - www.kandroid.org

177
How ‘dumpsys batteryinfo’ works?
adb shell dumpsys batteryinfo
com.android.server.am.
BatteryStatsService

12th Kandroid Conference - www.kandroid.org

178
How ‘dumpsys batteryinfo’ works?
adb shell dumpsys batteryinfo
com.android.server.am.
BatteryStatsService

com.android.internal.os
BatteryStatsImpl

12th Kandroid Conference - www.kandroid.org

179
How ‘dumpsys batteryinfo’ works?
adb shell dumpsys batteryinfo
com.android.server.am.
BatteryStatsService

com.android.internal.os
BatteryStatsImpl

android.os
BatteryStats

12th Kandroid Conference - www.kandroid.org

180
How ‘dumpsys batteryinfo’ works?
adb shell dumpsys batteryinfo
com.android.server.am.
BatteryStatsService

com.android.internal.os
BatteryStatsImpl

android.os
BatteryStats

noteBluetoothOff()
noteBluetoothOn()
noteFullWifiLockAcquired(int)
noteFullWifiLockAcquiredFromSource(WorkSource)
noteFullWifiLockReleased(int)
noteFullWifiLockReleasedFromSource(WorkSource)
noteInputEvent()
noteNetworkInterfaceType(String, int)
notePhoneDataConnectionState(int, boolean)
notePhoneOff()
notePhoneOn()
notePhoneSignalStrength(SignalStrength)
notePhoneState(int)
noteScreenBrightness(int)
noteScreenOff()
noteScreenOn()
...
noteWifiScanStarted(int)
noteWifiScanStartedFromSource(WorkSource)
noteWifiScanStopped(int)
noteWifiScanStoppedFromSource(WorkSource)
noteWifiStopped(WorkSource)
12th Kandroid Conference - www.kandroid.org

181
If you can’t automate
the measurement of it,
it is difficult to improve it.

12th Kandroid Conference - www.kandroid.org

182
If you can’t automate
the measurement of it,
it is difficult to improve it.
If you can’t understand
the measurement results,
it is impossible to improve it.
12th Kandroid Conference - www.kandroid.org

183
Automated Historical Performance Analysis with kmemtracer

Weitere ähnliche Inhalte

Was ist angesagt?

The Glass Class - Tutorial 3 - Android and GDK
The Glass Class - Tutorial 3 - Android and GDKThe Glass Class - Tutorial 3 - Android and GDK
The Glass Class - Tutorial 3 - Android and GDKGun Lee
 
Optimizing apps for better performance extended
Optimizing apps for better performance extended Optimizing apps for better performance extended
Optimizing apps for better performance extended Elif Boncuk
 
Android chapter02-setup1-sdk
Android chapter02-setup1-sdkAndroid chapter02-setup1-sdk
Android chapter02-setup1-sdkTran Le Hoan
 
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...Droidcon Berlin
 
Android reverse engineering: understanding third-party applications. OWASP EU...
Android reverse engineering: understanding third-party applications. OWASP EU...Android reverse engineering: understanding third-party applications. OWASP EU...
Android reverse engineering: understanding third-party applications. OWASP EU...Internet Security Auditors
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile wayAshwin Raghav
 
A guide to Android automated testing
A guide to Android automated testingA guide to Android automated testing
A guide to Android automated testingjotaemepereira
 
Utilizando expresso uiautomator na automacao de testes em apps android
Utilizando expresso uiautomator na automacao de testes em apps androidUtilizando expresso uiautomator na automacao de testes em apps android
Utilizando expresso uiautomator na automacao de testes em apps androidtdc-globalcode
 
android training_material ravy ramio
android training_material ravy ramioandroid training_material ravy ramio
android training_material ravy ramioslesulvy
 
9780134433646 annuzzi ch02 (1)
9780134433646 annuzzi ch02 (1)9780134433646 annuzzi ch02 (1)
9780134433646 annuzzi ch02 (1)Peter Mburu
 
What's new in android jakarta gdg (2015-08-26)
What's new in android   jakarta gdg (2015-08-26)What's new in android   jakarta gdg (2015-08-26)
What's new in android jakarta gdg (2015-08-26)Google
 
Overview of DroidCon UK 2015
Overview of DroidCon UK 2015 Overview of DroidCon UK 2015
Overview of DroidCon UK 2015 Elif Boncuk
 
How to create android applications
How to create android applicationsHow to create android applications
How to create android applicationsTOPS Technologies
 
How to reverse engineer Android applications
How to reverse engineer Android applicationsHow to reverse engineer Android applications
How to reverse engineer Android applicationshubx
 

Was ist angesagt? (20)

Webinar on Google Android SDK
Webinar on Google Android SDKWebinar on Google Android SDK
Webinar on Google Android SDK
 
Android Test Automation Workshop
Android Test Automation WorkshopAndroid Test Automation Workshop
Android Test Automation Workshop
 
The Glass Class - Tutorial 3 - Android and GDK
The Glass Class - Tutorial 3 - Android and GDKThe Glass Class - Tutorial 3 - Android and GDK
The Glass Class - Tutorial 3 - Android and GDK
 
Optimizing apps for better performance extended
Optimizing apps for better performance extended Optimizing apps for better performance extended
Optimizing apps for better performance extended
 
Android development beginners faq
Android development  beginners faqAndroid development  beginners faq
Android development beginners faq
 
Android studio
Android studioAndroid studio
Android studio
 
Android chapter02-setup1-sdk
Android chapter02-setup1-sdkAndroid chapter02-setup1-sdk
Android chapter02-setup1-sdk
 
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
Droidcon2013 pro guard, optimizer and obfuscator in the android sdk_eric lafo...
 
Android reverse engineering: understanding third-party applications. OWASP EU...
Android reverse engineering: understanding third-party applications. OWASP EU...Android reverse engineering: understanding third-party applications. OWASP EU...
Android reverse engineering: understanding third-party applications. OWASP EU...
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile way
 
A guide to Android automated testing
A guide to Android automated testingA guide to Android automated testing
A guide to Android automated testing
 
Utilizando expresso uiautomator na automacao de testes em apps android
Utilizando expresso uiautomator na automacao de testes em apps androidUtilizando expresso uiautomator na automacao de testes em apps android
Utilizando expresso uiautomator na automacao de testes em apps android
 
android training_material ravy ramio
android training_material ravy ramioandroid training_material ravy ramio
android training_material ravy ramio
 
Android 2.1-cdd
Android 2.1-cddAndroid 2.1-cdd
Android 2.1-cdd
 
Android ndk: Entering the native world
Android ndk: Entering the native worldAndroid ndk: Entering the native world
Android ndk: Entering the native world
 
9780134433646 annuzzi ch02 (1)
9780134433646 annuzzi ch02 (1)9780134433646 annuzzi ch02 (1)
9780134433646 annuzzi ch02 (1)
 
What's new in android jakarta gdg (2015-08-26)
What's new in android   jakarta gdg (2015-08-26)What's new in android   jakarta gdg (2015-08-26)
What's new in android jakarta gdg (2015-08-26)
 
Overview of DroidCon UK 2015
Overview of DroidCon UK 2015 Overview of DroidCon UK 2015
Overview of DroidCon UK 2015
 
How to create android applications
How to create android applicationsHow to create android applications
How to create android applications
 
How to reverse engineer Android applications
How to reverse engineer Android applicationsHow to reverse engineer Android applications
How to reverse engineer Android applications
 

Andere mochten auch

Hierarchy Viewer Internals
Hierarchy Viewer InternalsHierarchy Viewer Internals
Hierarchy Viewer InternalsKyungmin Lee
 
Skia & Freetype - Android 2D Graphics Essentials
Skia & Freetype - Android 2D Graphics EssentialsSkia & Freetype - Android 2D Graphics Essentials
Skia & Freetype - Android 2D Graphics EssentialsKyungmin Lee
 
Android. behind the scenes_programatica 2012
Android. behind the scenes_programatica 2012Android. behind the scenes_programatica 2012
Android. behind the scenes_programatica 2012Agora Group
 
Android Services Black Magic by Aleksandar Gargenta
Android Services Black Magic by Aleksandar GargentaAndroid Services Black Magic by Aleksandar Gargenta
Android Services Black Magic by Aleksandar GargentaMarakana Inc.
 
Improving Efficiency for Boiler and Steam System
Improving Efficiency for Boiler and Steam SystemImproving Efficiency for Boiler and Steam System
Improving Efficiency for Boiler and Steam SystemKamlesh Hariyani
 
Practical Boiler Control & Instrumentation for Engineers & Technicians
Practical Boiler Control & Instrumentation for Engineers & TechniciansPractical Boiler Control & Instrumentation for Engineers & Technicians
Practical Boiler Control & Instrumentation for Engineers & TechniciansLiving Online
 
Energy performance assessment of boilers
Energy performance assessment of boilersEnergy performance assessment of boilers
Energy performance assessment of boilersUtsav Jain
 
Improving steam boiler operating efficiency
Improving steam boiler operating efficiencyImproving steam boiler operating efficiency
Improving steam boiler operating efficiencyNaqqash Sajid
 
Boiler efficiency by loss Method
Boiler efficiency by loss MethodBoiler efficiency by loss Method
Boiler efficiency by loss MethodRajeev Saini
 

Andere mochten auch (14)

Hierarchy Viewer Internals
Hierarchy Viewer InternalsHierarchy Viewer Internals
Hierarchy Viewer Internals
 
Skia & Freetype - Android 2D Graphics Essentials
Skia & Freetype - Android 2D Graphics EssentialsSkia & Freetype - Android 2D Graphics Essentials
Skia & Freetype - Android 2D Graphics Essentials
 
Android. behind the scenes_programatica 2012
Android. behind the scenes_programatica 2012Android. behind the scenes_programatica 2012
Android. behind the scenes_programatica 2012
 
Android Services Black Magic by Aleksandar Gargenta
Android Services Black Magic by Aleksandar GargentaAndroid Services Black Magic by Aleksandar Gargenta
Android Services Black Magic by Aleksandar Gargenta
 
Boiler calculations
Boiler calculationsBoiler calculations
Boiler calculations
 
Improving Efficiency for Boiler and Steam System
Improving Efficiency for Boiler and Steam SystemImproving Efficiency for Boiler and Steam System
Improving Efficiency for Boiler and Steam System
 
Strategic Cost Management
Strategic Cost ManagementStrategic Cost Management
Strategic Cost Management
 
4.1 boiler
4.1 boiler4.1 boiler
4.1 boiler
 
Strategic Cost Management
Strategic Cost ManagementStrategic Cost Management
Strategic Cost Management
 
Practical Boiler Control & Instrumentation for Engineers & Technicians
Practical Boiler Control & Instrumentation for Engineers & TechniciansPractical Boiler Control & Instrumentation for Engineers & Technicians
Practical Boiler Control & Instrumentation for Engineers & Technicians
 
Energy performance assessment of boilers
Energy performance assessment of boilersEnergy performance assessment of boilers
Energy performance assessment of boilers
 
Improving steam boiler operating efficiency
Improving steam boiler operating efficiencyImproving steam boiler operating efficiency
Improving steam boiler operating efficiency
 
Boiler Performance Monitoring
Boiler Performance MonitoringBoiler Performance Monitoring
Boiler Performance Monitoring
 
Boiler efficiency by loss Method
Boiler efficiency by loss MethodBoiler efficiency by loss Method
Boiler efficiency by loss Method
 

Ähnlich wie Automated Historical Performance Analysis with kmemtracer

DEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsDEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsKyungmin Lee
 
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)DroidConTLV
 
Crash course in Kubernetes monitoring
Crash course in Kubernetes monitoringCrash course in Kubernetes monitoring
Crash course in Kubernetes monitoringRobert Munteanu
 
Rakuten Ichiba development Automation show case - Bamboo, Docker -
Rakuten Ichiba development Automation show case - Bamboo, Docker -Rakuten Ichiba development Automation show case - Bamboo, Docker -
Rakuten Ichiba development Automation show case - Bamboo, Docker -Rakuten Group, Inc.
 
Android Nâng cao-Bài 9-Debug in Android Application Development
Android Nâng cao-Bài 9-Debug in Android Application Development Android Nâng cao-Bài 9-Debug in Android Application Development
Android Nâng cao-Bài 9-Debug in Android Application Development Phuoc Nguyen
 
Front End performance as a Continuous Integration - Part1
Front End performance as a Continuous Integration - Part1Front End performance as a Continuous Integration - Part1
Front End performance as a Continuous Integration - Part1Tarence DSouza
 
Reversing & malware analysis training part 12 rootkit analysis
Reversing & malware analysis training part 12   rootkit analysisReversing & malware analysis training part 12   rootkit analysis
Reversing & malware analysis training part 12 rootkit analysisAbdulrahman Bassam
 
AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018 AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018 Theerasan Tonthongkam
 
Q4.11: Porting Android to new Platforms
Q4.11: Porting Android to new PlatformsQ4.11: Porting Android to new Platforms
Q4.11: Porting Android to new PlatformsLinaro
 
How to write clean & testable code without losing your mind
How to write clean & testable code without losing your mindHow to write clean & testable code without losing your mind
How to write clean & testable code without losing your mindAndreas Czakaj
 
Google analytics
Google analyticsGoogle analytics
Google analyticsSean Tsai
 
[Droidcon Paris 2013]Multi-Versioning Android Tips
[Droidcon Paris 2013]Multi-Versioning Android Tips[Droidcon Paris 2013]Multi-Versioning Android Tips
[Droidcon Paris 2013]Multi-Versioning Android TipsKenichi Kambara
 
The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202Mahmoud Samir Fayed
 
Google app engine
Google app engineGoogle app engine
Google app engineSuraj Mehta
 
Android Training in Chandigarh | Industrial Training in Android Apps Development
Android Training in Chandigarh | Industrial Training in Android Apps DevelopmentAndroid Training in Chandigarh | Industrial Training in Android Apps Development
Android Training in Chandigarh | Industrial Training in Android Apps DevelopmentBig Boxx Animation Academy
 
Kandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalNAVER D2
 

Ähnlich wie Automated Historical Performance Analysis with kmemtracer (20)

DEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsDEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android Applications
 
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
 
Android Froyo
Android FroyoAndroid Froyo
Android Froyo
 
Crash course in Kubernetes monitoring
Crash course in Kubernetes monitoringCrash course in Kubernetes monitoring
Crash course in Kubernetes monitoring
 
Rakuten Ichiba development Automation show case - Bamboo, Docker -
Rakuten Ichiba development Automation show case - Bamboo, Docker -Rakuten Ichiba development Automation show case - Bamboo, Docker -
Rakuten Ichiba development Automation show case - Bamboo, Docker -
 
Android Nâng cao-Bài 9-Debug in Android Application Development
Android Nâng cao-Bài 9-Debug in Android Application Development Android Nâng cao-Bài 9-Debug in Android Application Development
Android Nâng cao-Bài 9-Debug in Android Application Development
 
Front End performance as a Continuous Integration - Part1
Front End performance as a Continuous Integration - Part1Front End performance as a Continuous Integration - Part1
Front End performance as a Continuous Integration - Part1
 
Reversing & malware analysis training part 12 rootkit analysis
Reversing & malware analysis training part 12   rootkit analysisReversing & malware analysis training part 12   rootkit analysis
Reversing & malware analysis training part 12 rootkit analysis
 
AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018 AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018
 
Q4.11: Porting Android to new Platforms
Q4.11: Porting Android to new PlatformsQ4.11: Porting Android to new Platforms
Q4.11: Porting Android to new Platforms
 
How to write clean & testable code without losing your mind
How to write clean & testable code without losing your mindHow to write clean & testable code without losing your mind
How to write clean & testable code without losing your mind
 
Google analytics
Google analyticsGoogle analytics
Google analytics
 
Night Watch with QA
Night Watch with QANight Watch with QA
Night Watch with QA
 
[Droidcon Paris 2013]Multi-Versioning Android Tips
[Droidcon Paris 2013]Multi-Versioning Android Tips[Droidcon Paris 2013]Multi-Versioning Android Tips
[Droidcon Paris 2013]Multi-Versioning Android Tips
 
Android - Day 1
Android - Day 1Android - Day 1
Android - Day 1
 
The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202
 
Google app engine
Google app engineGoogle app engine
Google app engine
 
Android Training in Chandigarh | Industrial Training in Android Apps Development
Android Training in Chandigarh | Industrial Training in Android Apps DevelopmentAndroid Training in Chandigarh | Industrial Training in Android Apps Development
Android Training in Chandigarh | Industrial Training in Android Apps Development
 
Kandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_final
 
The MirAL Story
The MirAL StoryThe MirAL Story
The MirAL Story
 

Kürzlich hochgeladen

From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 

Kürzlich hochgeladen (20)

From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 

Automated Historical Performance Analysis with kmemtracer

  • 1. Automated Historical Performance Analysis with kmemtracer LG전자 이경민
  • 2. Contents Why Automated Historical Performance Testing? kmemtracer: What and How? Enhancement I : Automating UI Interaction Enhancement II: Adding More Performance Metrics 12th Kandroid Conference - www.kandroid.org 2
  • 3. If you can’t measure it, you can’t manage it. Peter F. Drucker (1909~2005) 12th Kandroid Conference - www.kandroid.org 3
  • 4. If you can’t measure it, you can’t manage it. Peter F. Drucker (1909~2005) If you can’t automate the measurement of it, it is difficult to improve it. 12th Kandroid Conference - www.kandroid.org 4
  • 6. Diversity or Fragmentation Platform Versions Screen Sizes and Densities http://developer.android.com/about/dashboards/index.html 12th Kandroid Conference - www.kandroid.org 6
  • 8. Historical Performance Analysis Why Historical Analysis? Source: Memory and Performance at the 11th Korea Android Conference 12th Kandroid Conference - www.kandroid.org 8
  • 9. Historical Performance Analysis Why Historical Analysis? Source: Memory and Performance at the 11th Korea Android Conference 12th Kandroid Conference - www.kandroid.org 9
  • 10. Historical Performance Analysis Why Historical Analysis? Activity Navigation & Lifecycle Source: Memory and Performance at the 11th Korea Android Conference 12th Kandroid Conference - www.kandroid.org 10
  • 11. How to Track Activity Navigation & Lifecycle? 12th Kandroid Conference - www.kandroid.org 11
  • 12. How to Track Activity Navigation & Lifecycle? Override onCreate, onStart, … of your Activity classes 12th Kandroid Conference - www.kandroid.org 12
  • 13. How to Track Activity Navigation & Lifecycle? Modify android.app.Activity in the framework 12th Kandroid Conference - www.kandroid.org 13
  • 14. How to Track Activity Navigation & Lifecycle? Is there a way that does not require the modification of an application or framework? 12th Kandroid Conference - www.kandroid.org 14
  • 15. How to Track Activity Navigation & Lifecycle? Is there a way that does not require the modification of an application or framework? Instrumentation 12th Kandroid Conference - www.kandroid.org 15
  • 16. 12th Kandroid Conference - www.kandroid.org 16
  • 17. Android instrumentation is a set of control methods or "hooks" in the Android system. These hooks control an Android component independently of its normal lifecycle. They also control how Android loads applications. (http://developer.android.com/tools/testing/testing_android.html) 12th Kandroid Conference - www.kandroid.org 17
  • 18. Contents Why Automated Historical Performance Testing? kmemtracer: What and How? Enhancement I : Automating UI Interaction Enhancement II: Adding More Performance Metrics 12th Kandroid Conference - www.kandroid.org 18
  • 19. Historical Analysis w/ kmemtracer Application Package Control android.test. Instrumentation TestRunner Test Package 12th Kandroid Conference - www.kandroid.org 19
  • 20. Historical Analysis w/ kmemtracer https://github.com/snailee/kmemtracer-libs Application Package Control Track android.test. Instrumentation TestRunner org.kandroid. memtracer.Memory Instrumentation Test Package Trace Package 12th Kandroid Conference - www.kandroid.org 20
  • 21. android.app.Instrumentation void void void void void void void void void void void void void callActivityOnCreate(Activity, Bundle) callActivityOnDestroy(Activity) callActivityOnNewIntent(Activity, Intent) callActivityOnPause(Activity) callActivityOnPostCreate(Activity, Bundle) callActivityOnRestart(Activity) callActivityOnRestoreInstanceState(Activity, Bundle) callActivityOnResume(Activity) callActivityOnSaveInstanceState(Activity, Bundle) callActivityOnStart(Activity) callActivityOnStop(Activity) callActivityOnUserLeaving(Activity) callApplicationOnCreate(Application) 12th Kandroid Conference - www.kandroid.org 21
  • 22. android.app.Instrumentation void void void void void void void void void void void void void callActivityOnCreate(Activity, Bundle) callActivityOnDestroy(Activity) callActivityOnNewIntent(Activity, Intent) callActivityOnPause(Activity) callActivityOnPostCreate(Activity, Bundle) callActivityOnRestart(Activity) callActivityOnRestoreInstanceState(Activity, Bundle) callActivityOnResume(Activity) callActivityOnSaveInstanceState(Activity, Bundle) callActivityOnStart(Activity) callActivityOnStop(Activity) callActivityOnUserLeaving(Activity) callApplicationOnCreate(Application) Call for Control 12th Kandroid Conference - www.kandroid.org 22
  • 23. android.app.Instrumentation void void void void void void void void void void void void void callActivityOnCreate(Activity, Bundle) callActivityOnDestroy(Activity) callActivityOnNewIntent(Activity, Intent) callActivityOnPause(Activity) callActivityOnPostCreate(Activity, Bundle) callActivityOnRestart(Activity) callActivityOnRestoreInstanceState(Activity, Bundle) callActivityOnResume(Activity) callActivityOnSaveInstanceState(Activity, Bundle) callActivityOnStart(Activity) callActivityOnStop(Activity) callActivityOnUserLeaving(Activity) callApplicationOnCreate(Application) Call for Control Override for Track 12th Kandroid Conference - www.kandroid.org 23
  • 24. org.kandroid.memtracer.MemoryInstrumentation public class MemoryInstrumentation extends Instrumentation { private static final String ARGUMENT_INSTRUMENT_CLASS = "class"; private MemoryTracer mMemoryTracer; private String mMainActivityName; ... @Override public void onCreate(Bundle arguments) { mMainActivityName = arguments.getString(ARGUMENT_INSTRUMENT_CLASS); mMemoryTracer = createMemoryTracer(); mMemoryTracer.startTracing(getTargetContext().getPackageName()); start(); } @Override public void callActivityOnCreate(Activity activity, Bundle icicle) { String tag = activity.getLocalClassName()+"-OnCreate"; Bundle snapshot = mMemoryTracer.addSnapshot(tag); super.callActivityOnCreate(activity, icicle); } } 12th Kandroid Conference - www.kandroid.org 24
  • 25. Tracing Performance Snapshots in kmemtracer public class MemoryInstrumentation extends Instrumentation { ... ... } 12th Kandroid Conference - www.kandroid.org 25
  • 26. Tracing Performance Snapshots in kmemtracer public class MemoryInstrumentation extends Instrumentation { ... private MemoryTracer mMemoryTracer; ... @Override public void onCreate(Bundle arguments) { ... mMemoryTracer = createMemoryTracer(); ... } ... Create an instance of MemoryTracer ... } 12th Kandroid Conference - www.kandroid.org 26
  • 27. Tracing Performance Snapshots in kmemtracer public class MemoryInstrumentation extends Instrumentation { ... private MemoryTracer mMemoryTracer; ... @Override public void onCreate(Bundle arguments) { ... mMemoryTracer = createMemoryTracer(); ... } ... @Override public void callActivityOnCreate(Activity activity, Bundle icicle) { String tag = activity.getLocalClassName()+"-OnCreate"; Bundle snapshot = mMemoryTracer.addSnapshot(tag); ... } ... } Create an instance of MemoryTracer Add performance snapshot 12th Kandroid Conference - www.kandroid.org 27
  • 28. MemoryTracer.addSnapshot public Bundle addSnapshot(String label) { ... 12th Kandroid Conference - www.kandroid.org 28
  • 29. MemoryTracer.addSnapshot public Bundle addSnapshot(String label) { ... long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); ... Get usage data 12th Kandroid Conference - www.kandroid.org 29
  • 30. MemoryTracer.addSnapshot public Bundle addSnapshot(String label) { ... long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); ... Bundle snapshot = new Bundle(); snapshot.putString(METRIC_KEY_LABEL, label); ... snapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax); snapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated); snapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree); ... Get usage data Save data to a bundle 12th Kandroid Conference - www.kandroid.org 30
  • 31. MemoryTracer.addSnapshot public Bundle addSnapshot(String label) { ... long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); ... Bundle snapshot = new Bundle(); snapshot.putString(METRIC_KEY_LABEL, label); ... snapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax); snapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated); snapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree); ... if (mResultsWriter != null) { mResultsWriter.writeTraceSnapshot(snapshot); } return snapshot; } Get usage data Save data to a bundle Write date using ResultsWriter 12th Kandroid Conference - www.kandroid.org 31
  • 32. MemoryTracerCsvWriter$writeTraceSnapshot public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter { ... 12th Kandroid Conference - www.kandroid.org 32
  • 33. MemoryTracerCsvWriter$writeTraceSnapshot public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter { ... public MemoryTraceCsvWriter(String[] metricKeys) { mMetricKeys = metricKeys; } ... Create an instance with metrics to print 12th Kandroid Conference - www.kandroid.org 33
  • 34. MemoryTracerCsvWriter$writeTraceSnapshot public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter { ... public MemoryTraceCsvWriter(String[] metricKeys) { mMetricKeys = metricKeys; } ... private void openTraceFile(String filename) { ... mTraceOut = new PrintStream(new FileOutputStream(traceFile)); ... } ... Create an instance with metrics to print Open a trace file in the sdcard at init 12th Kandroid Conference - www.kandroid.org 34
  • 35. MemoryTracerCsvWriter$writeTraceSnapshot public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter { ... public MemoryTraceCsvWriter(String[] metricKeys) { mMetricKeys = metricKeys; } ... private void openTraceFile(String filename) { ... mTraceOut = new PrintStream(new FileOutputStream(traceFile)); ... } ... @Override public void writeTraceSnapshot(Bundle snapshot) { PrintStream out = mTraceOut; for (String key : mMetricKeys) { out.print(snapshot.get(key)); out.print(','); } out.println(); out.flush(); } ... } 12 Kandroid Conference - www.kandroid.org Create an instance with metrics to print Open a trace file in the sdcard at init Write snapshot to a line of the file th 35
  • 36. How to Use kmemtracer? 12th Kandroid Conference - www.kandroid.org 36
  • 37. How to Use kmemtracer? 1. Create an Android Test Project for the trace package. 12th Kandroid Conference - www.kandroid.org 37
  • 38. How to Use kmemtracer? 1. Create an Android Test Project for the trace package. 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 12th Kandroid Conference - www.kandroid.org 38
  • 39. How to Use kmemtracer? 1. Create an Android Test Project for the trace package. 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 3. Edit the <instrumentation> element in the Manifest file. <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.apis.test" android:versionCode="1" android:versionName="1.0"> <instrumentation android:name="org.kandroid.memtracer.MemoryInstrumentation" android:targetPackage="com.example.android.apis" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:label="@string/app_name" android:icon="@drawable/ic_launcher“> <uses-library android:theme="android.text.runner“> </application> </manifest> 12th Kandroid Conference - www.kandroid.org 39
  • 40. How to Use kmemtracer? 4. Install the trace package as well as the application package. $ adb install –r ApiDemos.apk $ adb install –r ApiDemosTest.apk 12th Kandroid Conference - www.kandroid.org 40
  • 41. How to Use kmemtracer? 4. Install the trace package as well as the application package. $ adb install –r ApiDemos.apk $ adb install –r ApiDemosTest.apk 5. Start the instrumentation with ‘am instrument’ in the shell. $ > > > adb shell am instrument -e class com.example.android.apis.ApiDemos com.example.android.apis.tests/ org.kandroid.memtracer.MemoryInstrumentation 12th Kandroid Conference - www.kandroid.org 41
  • 42. How to Use kmemtracer? 4. Install the trace package as well as the application package. $ adb install –r ApiDemos.apk $ adb install –r ApiDemosTest.apk 5. Start the instrumentation with ‘am instrument’ in the shell. $ > > > adb shell am instrument -e class com.example.android.apis.ApiDemos com.example.android.apis.tests/ org.kandroid.memtracer.MemoryInstrumentation 6. Do interact with the application. 12th Kandroid Conference - www.kandroid.org 42
  • 43. How to Use kmemtracer? 4. Install the trace package as well as the application package. $ adb install –r ApiDemos.apk $ adb install –r ApiDemosTest.apk 5. Start the instrumentation with ‘am instrument’ in the shell. $ > > > adb shell am instrument -e class com.example.android.apis.ApiDemos com.example.android.apis.tests/ org.kandroid.memtracer.MemoryInstrumentation 6. Do interact with the application. 7. Pull the trace file ‘kmemtrace.csv’ from /sdcard/kmemtracer. $ adb pull /sdcard/kmemtracer/kmemtrace.csv . 12th Kandroid Conference - www.kandroid.org 43
  • 44. How to Use kmemtracer? 8. Open the trace file with Excel and create charts. 12th Kandroid Conference - www.kandroid.org 44
  • 45. Contents Why Automated Historical Performance Testing? kmemtracer: What and How? Enhancement I : Automating UI Interaction Enhancement II: Adding More Performance Metrics 12th Kandroid Conference - www.kandroid.org 45
  • 49. Three Alternatives 12th Kandroid Conference - www.kandroid.org 49
  • 50. Three Alternatives Instrumentation API Level 1 ~ Single activity Framework APIs White-box http://developer.android.com/tools/testing/testing_android.html 12th Kandroid Conference - www.kandroid.org 50
  • 51. Three Alternatives Instrumentation API Level 1 ~ Single activity Framework APIs White-box Robotium 2010/01 ~ Multiple activities High-level APIs White-box & black-box http://developer.android.com/tools/testing/testing_android.html https://code.google.com/p/robotium/ 12th Kandroid Conference - www.kandroid.org 51
  • 52. Three Alternatives Instrumentation API Level 1 ~ Single activity Framework APIs White-box Robotium uiautomator 2010/01 ~ Multiple activities High-level APIs White-box & black-box API Level 17 ~ Multiple processes Simple APIs Black-box http://developer.android.com/tools/testing/testing_android.html https://code.google.com/p/robotium/ http://developer.android.com/tools/testing/testing_ui.html 12th Kandroid Conference - www.kandroid.org 52
  • 62. Controlling UI Using Instrumentation 12th Kandroid Conference - www.kandroid.org 62
  • 63. Controlling UI Using Instrumentation 1. Create an Android Test Project for the test package. $ android create test-project --main ../ApiDemos > –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest 12th Kandroid Conference - www.kandroid.org 63
  • 64. Controlling UI Using Instrumentation 1. Create an Android Test Project for the test package. $ android create test-project --main ../ApiDemos > –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest 2. Add a test class inheriting ActivityInstrumentationTestCase2. public class ApiDemosInstrumentTest extends ActivityInstrumentationTestCase2<ApiDemos> { ... public ApiDemosInstrumentTest() { super(ApiDemos.class); } 12th Kandroid Conference - www.kandroid.org 64
  • 65. Controlling UI Using Instrumentation 1. Create an Android Test Project for the test package. $ android create test-project --main ../ApiDemos > –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest 2. Add a test class inheriting ActivityInstrumentationTestCase2. public class ApiDemosInstrumentTest extends ActivityInstrumentationTestCase2<ApiDemos> { ... public ApiDemosInstrumentTest() { super(ApiDemos.class); } 3. Add a test method and launch the activity. public void testNavigate() { final ApiDemos apiDemos = getActivity(); ... } 12th Kandroid Conference - www.kandroid.org 65
  • 66. Controlling UI Using Instrumentation 4. Find and act on a control. public void testNavigate() { ... 12th Kandroid Conference - www.kandroid.org 66
  • 67. Controlling UI Using Instrumentation 4. Find and act on a control. public void testNavigate() ... final ListView demoList final View graphicsDemo assertNotNull("Graphics { Find a view to control = apiDemos.getListView(); = getChildViewByText(demoList, "Graphics"); demo should exist", graphicsDemo); 12th Kandroid Conference - www.kandroid.org 67
  • 68. Controlling UI Using Instrumentation 4. Find and act on a control. public void testNavigate() ... final ListView demoList final View graphicsDemo assertNotNull("Graphics { Find a view to control = apiDemos.getListView(); = getChildViewByText(demoList, "Graphics"); demo should exist", graphicsDemo); apiDemos.runOnUiThread(new Runnable() { public void run() { int pos = demoList.getPositionForView(graphicsDemo); demoList.smoothScrollToPosition(pos); demoList.setSelection(pos); demoList.performItemClick(graphicsDemo, pos, graphicsDemo.getId()); } }); ... Act on the view 12th Kandroid Conference - www.kandroid.org 68
  • 69. Controlling UI Using Instrumentation 4. Find and act on a control. public void testNavigate() ... final ListView demoList final View graphicsDemo assertNotNull("Graphics { Find a view to control = apiDemos.getListView(); = getChildViewByText(demoList, "Graphics"); demo should exist", graphicsDemo); apiDemos.runOnUiThread(new Runnable() { public void run() { int pos = demoList.getPositionForView(graphicsDemo); demoList.smoothScrollToPosition(pos); demoList.setSelection(pos); demoList.performItemClick(graphicsDemo, pos, graphicsDemo.getId()); } }); ... Act on the view 12th Kandroid Conference - www.kandroid.org 69
  • 70. Controlling UI Using Instrumentation 4. Find and act on a control: getChildViewByText. private View getChildViewByText(ListView listView, String text) { 12th Kandroid Conference - www.kandroid.org 70
  • 71. Controlling UI Using Instrumentation 4. Find and act on a control: getChildViewByText. private View getChildViewByText(ListView listView, String text) { View view = null; int count = listView.getCount(); Log.e(TAG, “no. children = " + count); for (int i = 0; i < count; i++) { TextView textView = (TextView) listView.getChildAt(i); Iterate through child views 12th Kandroid Conference - www.kandroid.org 71
  • 72. Controlling UI Using Instrumentation 4. Find and act on a control: getChildViewByText. private View getChildViewByText(ListView listView, String text) { View view = null; int count = listView.getCount(); Log.e(TAG, “no. children = " + count); for (int i = 0; i < count; i++) { TextView textView = (TextView) listView.getChildAt(i); Log.e(TAG, i + "-th text view is " + textView); if (textView != null && textView.getText().equals(text)) { view = textView; break; } } return view; } Iterate through child views Compare texts 12th Kandroid Conference - www.kandroid.org 72
  • 73. Controlling UI Using Instrumentation 4. Find and act on a control: getChildViewByText. private View getChildViewByText(ListView listView, String text) { View view = null; int count = listView.getCount(); Log.e(TAG, “no. children = " + count); for (int i = 0; i < count; i++) { TextView textView = (TextView) listView.getChildAt(i); Log.e(TAG, i + "-th text view is " + textView); if (textView != null && textView.getText().equals(text)) { view = textView; break; } } return view; } com.example.android.apis.instrument.test.ApiDemosInstrumentTest: INSTRUMENTATION_RESULT: shortMsg=junit.framework.AssertionFailedError INSTRUMENTATION_RESULT: longMsg= junit.framework.AssertionFailedError: OpenGL ES demo should exist INSTRUMENTATION_CODE: 0 Iterate through child views Compare texts 12th Kandroid Conference - www.kandroid.org 73
  • 74. Controlling UI Using Instrumentation 4. Find and act on a control: Revised getChildViewByText. private View getChildViewByText(final ListView listView, String text) { ... for (int i = 0; i < count; i++) { TextView textView = (TextView) listView.getChildAt(i); if (textView != null && textView.getText().equals(text)) { view = textView; break; } if (textView == null) { final int lastPos = listView.getLastVisiblePosition(); getInstrumentation().runOnMainSync(new Runnable() { public void run() { listView.smoothScrollToPosition(lastPos + 5, lastPos); } }); getInstrumentation().waitForIdleSync(); i = listView.getFirstVisiblePosition(); } } return view; } 12th Kandroid Conference - www.kandroid.org 74
  • 75. Controlling UI Using Instrumentation 4. Find and act on a control: Revised getChildViewByText. private View getChildViewByText(final ListView listView, String text) { ... for (int i = 0; i < count; i++) { TextView textView = (TextView) listView.getChildAt(i); if (textView != null && textView.getText().equals(text)) { view = textView; break; } if (textView == null) { final int lastPos = listView.getLastVisiblePosition(); getInstrumentation().runOnMainSync(new Runnable() { public void run() { listView.smoothScrollToPosition(lastPos + 5, lastPos); } }); getInstrumentation().waitForIdleSync(); i = listView.getFirstVisiblePosition(); } } return view; } Scroll down 12th Kandroid Conference - www.kandroid.org 75
  • 76. Controlling UI Using Instrumentation 4. Find and act on a control: getPositionForChildViewByText. private int getPositionForChildViewByText(ListView listView, String text) { ListAdapter listAdapter = listView.getAdapter(); int count = listAdapter.getCount(); Log.e(TAG, "children: " + count); for (int i = 0; i < count; i++) { String itemText = (String) ((Map)listAdapter.getItem(i)).get("title"); Log.e(TAG, i + "-th text item " + itemText); if (itemText != null && itemText.equals(text)) { return i; } } return -1; } ... final ListView graphicsDemoList = graphicsDemoActivity.getListView(); int pos = getPositionForChildViewByText(graphicsDemoList, "OpenGL ES"); assertTrue("Cannot find OpenGL ES", pos != -1); ... 12th Kandroid Conference - www.kandroid.org 76
  • 77. Controlling UI Using Instrumentation 4. Find and act on a control: getPositionForChildViewByText. private int getPositionForChildViewByText(ListView listView, String text) { ListAdapter listAdapter = listView.getAdapter(); int count = listAdapter.getCount(); Log.e(TAG, "children: " + count); for (int i = 0; i < count; i++) { String itemText = (String) ((Map)listAdapter.getItem(i)).get("title"); Log.e(TAG, i + "-th text item " + itemText); if (itemText != null && itemText.equals(text)) { return i; } } return -1; } ... final ListView graphicsDemoList = graphicsDemoActivity.getListView(); int pos = getPositionForChildViewByText(graphicsDemoList, "OpenGL ES"); assertTrue("Cannot find OpenGL ES", pos != -1); ... 12th Kandroid Conference - www.kandroid.org 77
  • 78. Controlling UI Using Instrumentation 5. Monitor a new Activity to launch. public void testNavigate() { ... Instrumentation.ActivityMonitor graphicsDemoActivityMonitor = getInstrumentation().addMonitor( ApiDemos.class.getName(), null, false); final ApiDemos graphicsDemoActivity = (ApiDemos) graphicsDemoActivityMonitor.waitForActivity(); assertNotNull("Graphics Demo (ApiDemos) activity should not be null", graphicsDemoActivity); ... 12th Kandroid Conference - www.kandroid.org 78
  • 79. Controlling UI Using Instrumentation 5. Monitor a new Activity to launch. public void testNavigate() { ... Instrumentation.ActivityMonitor graphicsDemoActivityMonitor = getInstrumentation().addMonitor( ApiDemos.class.getName(), null, false); final ApiDemos graphicsDemoActivity = (ApiDemos) graphicsDemoActivityMonitor.waitForActivity(); assertNotNull("Graphics Demo (ApiDemos) activity should not be null", graphicsDemoActivity); ... 6. Iterate step 4 & 5. 12th Kandroid Conference - www.kandroid.org 79
  • 80. Controlling UI Using Instrumentation 7. Build and Install the test package. $ cd ApiDemosInstrumentTest $ ant debug $ adb install –r bin/ApiDemosInstrumentTest-debug.apk 12th Kandroid Conference - www.kandroid.org 80
  • 81. Controlling UI Using Instrumentation 7. Build and Install the test package. $ cd ApiDemosInstrumentTest $ ant debug $ adb install –r bin/ApiDemosInstrumentTest-debug.apk 8. Run the test and see the result. $ adb shell am instrument -w > com.example.android.apis.instrument.test/ > android.test.InstrumentationTestRunner 12th Kandroid Conference - www.kandroid.org 81
  • 82. Controlling UI Using Instrumentation 7. Build and Install the test package. $ cd ApiDemosInstrumentTest $ ant debug $ adb install –r bin/ApiDemosInstrumentTest-debug.apk 8. Run the test and see the result. $ adb shell am instrument -w > com.example.android.apis.instrument.test/ > android.test.InstrumentationTestRunner $ ant test 12th Kandroid Conference - www.kandroid.org 82
  • 83. Controlling UI Using Robotium 12th Kandroid Conference - www.kandroid.org 83
  • 84. Controlling UI Using Robotium 1. Create an Android Test Project for the test package. $ android create test-project --main ../ApiDemos > –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest 12th Kandroid Conference - www.kandroid.org 84
  • 85. Controlling UI Using Robotium 1. Create an Android Test Project for the test package. $ android create test-project --main ../ApiDemos > –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest 2. Add ‘robotium-solo-<ver>.jar’ in the ‘libs’ directory. 12th Kandroid Conference - www.kandroid.org 85
  • 86. Controlling UI Using Robotium 1. Create an Android Test Project for the test package. $ android create test-project --main ../ApiDemos > –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest 2. Add ‘robotium-solo-<ver>.jar’ in the ‘libs’ directory. 3. Add a test class inheriting ActivityInstrumentationTestCase2. public class ApiDemosRobotiumTest extends ActivityInstrumentationTestCase2<ApiDemos> { ... public ApiDemosRobotiumTest() { super(ApiDemos.class); } ... 12th Kandroid Conference - www.kandroid.org 86
  • 87. Controlling UI Using Robotium 4. Create an instance of Solo in the setUp method and close open activities in the tearDown method. ... private Solo solo; ... @Override public void setUp() throws Exception { solo = new Solo(getInstrumentation(), getActivity()); } @Override public void tearDown() throws Exception { solo.finishOpenedActivities(); } ... 12th Kandroid Conference - www.kandroid.org 87
  • 88. Controlling UI Using Robotium 4. Find and act on a control. public void testNavigate() { solo.assertCurrentActivity("Should be on ApiDemos", ApiDemos.class); solo.clickOnText("^Graphics$", 1, true); solo.assertCurrentActivity("Should be on a new ApiDemos", ApiDemos.class, true); solo.clickOnText("^OpenGL ES$", 1, true); solo.assertCurrentActivity("Should be on a new ApiDemos", ApiDemos.class, true); solo.clickOnText("^Kube$", 1, true); solo.assertCurrentActivity("Should be on a Kube", Kube.class, true); solo.sleep(3000); } 12th Kandroid Conference - www.kandroid.org 88
  • 89. Controlling UI Using Robotium 6. Build and Install the test package. $ cd ApiDemosRobotiumTest $ ant debug $ adb install –r bin/ApiDemosRobotiumTest-debug.apk 12th Kandroid Conference - www.kandroid.org 89
  • 90. Controlling UI Using Robotium 6. Build and Install the test package. $ cd ApiDemosRobotiumTest $ ant debug $ adb install –r bin/ApiDemosRobotiumTest-debug.apk 7. Run the test and see the result. $ adb shell am instrument -w > com.example.android.apis.robotium.test/ > android.test.InstrumentationTestRunner 12th Kandroid Conference - www.kandroid.org 90
  • 91. Controlling UI Using Robotium 6. Build and Install the test package. $ cd ApiDemosRobotiumTest $ ant debug $ adb install –r bin/ApiDemosRobotiumTest-debug.apk 7. Run the test and see the result. $ adb shell am instrument -w > com.example.android.apis.robotium.test/ > android.test.InstrumentationTestRunner $ ant test 12th Kandroid Conference - www.kandroid.org 91
  • 92. Controlling UI Using uiautomator 1. Create an Java Project for the test jar. 12th Kandroid Conference - www.kandroid.org 92
  • 93. Controlling UI Using uiautomator 1. Create an Java Project for the test jar. 2. Add ‘android.jar’ and ‘uiautomator.jar’ in the build path. 12th Kandroid Conference - www.kandroid.org 93
  • 94. Controlling UI Using uiautomator 1. Create an Java Project for the test jar. 2. Add ‘android.jar’ and ‘uiautomator.jar’ in the build path. 3. Add a test class inheriting UiAutomatorTestCase. public class ApiDemosUiAutoTest extends UiAutomatorTestCase { ... } 12th Kandroid Conference - www.kandroid.org 94
  • 95. Controlling UI Using uiautomator 4. Launch ApiDemos. public void testNavigate() throws UiObjectNotFoundException { 12th Kandroid Conference - www.kandroid.org 95
  • 96. Controlling UI Using uiautomator 4. Launch ApiDemos. public void testNavigate() throws UiObjectNotFoundException { getUiDevice().pressHome(); Press home button 12th Kandroid Conference - www.kandroid.org 96
  • 97. Controlling UI Using uiautomator 4. Launch ApiDemos. public void testNavigate() throws UiObjectNotFoundException { getUiDevice().pressHome(); UiObject allAppsButton = new UiObject( new UiSelector().description("Apps")); allAppsButton.clickAndWaitForNewWindow(); 12th Kandroid Conference - www.kandroid.org Press home button Click ‘All Apps’ button 97
  • 98. Controlling UI Using uiautomator 4. Launch ApiDemos. public void testNavigate() throws UiObjectNotFoundException { getUiDevice().pressHome(); UiObject allAppsButton = new UiObject( new UiSelector().description("Apps")); allAppsButton.clickAndWaitForNewWindow(); Press home button Click ‘All Apps’ button UiObject appsTab = new UiObject(new UiSelector().text("Apps")); appsTab.click(); Click ‘Apps’ tab 12th Kandroid Conference - www.kandroid.org 98
  • 99. Controlling UI Using uiautomator 4. Launch ApiDemos. public void testNavigate() throws UiObjectNotFoundException { getUiDevice().pressHome(); UiObject allAppsButton = new UiObject( new UiSelector().description("Apps")); allAppsButton.clickAndWaitForNewWindow(); Press home button Click ‘All Apps’ button UiObject appsTab = new UiObject(new UiSelector().text("Apps")); appsTab.click(); Click ‘Apps’ tab UiScrollable appList = new UiScrollable( new UiSelector().scrollable(true)); appList.setAsHorizontalList(); UiObject apiDemos = appList.getChildByText( new UiSelector().className(TextView.class.getName()), "API Demos"); apiDemos.clickAndWaitForNewWindow(); Click ‘ApiDemos’ icon 12th Kandroid Conference - www.kandroid.org 99
  • 100. Controlling UI Using uiautomator 4. Launch ApiDemos. public void testNavigate() throws UiObjectNotFoundException { getUiDevice().pressHome(); UiObject allAppsButton = new UiObject( new UiSelector().description("Apps")); allAppsButton.clickAndWaitForNewWindow(); Press home button Click ‘All Apps’ button UiObject appsTab = new UiObject(new UiSelector().text("Apps")); appsTab.click(); Click ‘Apps’ tab UiScrollable appList = new UiScrollable( new UiSelector().scrollable(true)); appList.setAsHorizontalList(); UiObject apiDemos = appList.getChildByText( new UiSelector().className(TextView.class.getName()), "API Demos"); apiDemos.clickAndWaitForNewWindow(); Click ‘ApiDemos’ icon Validate the launch of ‘ApiDemos’ UiObject apiDemosPackage = new UiObject( new UiSelector().packageName("com.example.android.apis")); assertTrue("Should be on ApiDemos", apiDemosPackage.exists()); ... 12th Kandroid Conference - www.kandroid.org 100
  • 101. Controlling UI Using uiautomator 5. Find and act on a control. ... UiScrollable demoList = new UiScrollable( new UiSelector().className("android.widget.ListView")); UiObject graphicsDemo = demoList.getChildByText( new UiSelector().className(TextView.class.getName()), “Graphics"); graphicsDemo.clickAndWaitForNewWindow(); UiObject alphaBitmapDemo = new UiObject( new UiSelector().text(“AlphaBitmap")); assertTrue(“AlphaBitmap should be visible", alpahBitmapDemo.exists()); ... 12th Kandroid Conference - www.kandroid.org 101
  • 102. Controlling UI Using uiautomator 5. Find and act on a control. ... UiScrollable demoList = new UiScrollable( new UiSelector().className("android.widget.ListView")); UiObject graphicsDemo = demoList.getChildByText( new UiSelector().className(TextView.class.getName()), “Graphics"); graphicsDemo.clickAndWaitForNewWindow(); UiObject alphaBitmapDemo = new UiObject( new UiSelector().text(“AlphaBitmap")); assertTrue(“AlphaBitmap should be visible", alpahBitmapDemo.exists()); ... 6. Iterate step 5. 12th Kandroid Conference - www.kandroid.org 102
  • 103. Controlling UI Using uiautomator 7. Compile your test case into a JAR file. $ > $ $ android create uitest-project --name ApiDemosUiAutoTest --target 1 --path ApiDemosUiAutoTest cd ApiDemosUiAutoTest ant build 12th Kandroid Conference - www.kandroid.org 103
  • 104. Controlling UI Using uiautomator 7. Compile your test case into a JAR file. $ > $ $ android create uitest-project --name ApiDemosUiAutoTest --target 1 --path ApiDemosUiAutoTest cd ApiDemosUiAutoTest ant build 8. Install the jar on your test device. $ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/ 12th Kandroid Conference - www.kandroid.org 104
  • 105. Controlling UI Using uiautomator 7. Compile your test case into a JAR file. $ > $ $ android create uitest-project --name ApiDemosUiAutoTest --target 1 --path ApiDemosUiAutoTest cd ApiDemosUiAutoTest ant build 8. Install the jar on your test device. $ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/ 9. Run the test and view the test result. $ adb shell uiautomator runtest ApiDemosUiAutoTest.jar > –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest 12th Kandroid Conference - www.kandroid.org 105
  • 106. Controlling UI Using uiautomator 7. Compile your test case into a JAR file. $ > $ $ android create uitest-project --name ApiDemosUiAutoTest --target 1 --path ApiDemosUiAutoTest cd ApiDemosUiAutoTest ant build 8. Install the jar on your test device. $ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/ 9. Run the test and view the test result. $ adb shell uiautomator runtest ApiDemosUiAutoTest.jar > –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest $ ant test 12th Kandroid Conference - www.kandroid.org 106
  • 107. Controlling UI Using uiautomator 7. Compile your test case into a JAR file. $ > $ $ android create uitest-project --name ApiDemosUiAutoTest --target 1 --path ApiDemosUiAutoTest cd ApiDemosUiAutoTest ant build 8. Install the jar on your test device. $ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/ 9. Run the test and view the test result. $ adb shell uiautomator runtest ApiDemosUiAutoTest.jar > –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest $ ant test 12th Kandroid Conference - www.kandroid.org 107
  • 108. Doing both Controlling and Tracking 12th Kandroid Conference - www.kandroid.org 108
  • 109. Doing both Controlling and Tracking 1. Modify org.kandroid.memtracer.MemoryInstrumentation. public class MemoryInstrumentation extends InstrumentationTestRunner { ... @Override public void onCreate(Bundle arguments) { ... start(); super.onCreate(arguments); } @Override public void onStart() { String mainActivityName = getMainActivityName(); if (mainActivityName != null && mainActivityName.length() > 0) { launchMainActivity(getTargetContext().getPackageName(), getMainActivityName()); } else { super.onStart(); } } ... 12th Kandroid Conference - www.kandroid.org 109
  • 110. Doing both Controlling and Tracking 1. Modify org.kandroid.memtracer.MemoryInstrumentation. public class MemoryInstrumentation extends InstrumentationTestRunner { ... @Override public void onCreate(Bundle arguments) { ... start(); super.onCreate(arguments); } @Override public void onStart() { String mainActivityName = getMainActivityName(); if (mainActivityName != null && mainActivityName.length() > 0) { launchMainActivity(getTargetContext().getPackageName(), getMainActivityName()); } else { super.onStart(); } } ... 12th Kandroid Conference - www.kandroid.org 110
  • 111. Doing both Controlling and Tracking 1. Modify org.kandroid.memtracer.MemoryInstrumentation. public class MemoryInstrumentation extends InstrumentationTestRunner { ... @Override public void onCreate(Bundle arguments) { ... start(); super.onCreate(arguments); } @Override public void onStart() { String mainActivityName = getMainActivityName(); if (mainActivityName != null && mainActivityName.length() > 0) { launchMainActivity(getTargetContext().getPackageName(), getMainActivityName()); } else { super.onStart(); } } ... 12th Kandroid Conference - www.kandroid.org 111
  • 112. Doing both Controlling and Tracking 1. Modify org.kandroid.memtracer.MemoryInstrumentation. public class MemoryInstrumentation extends InstrumentationTestRunner { ... @Override public void onCreate(Bundle arguments) { ... start(); super.onCreate(arguments); } @Override public void onStart() { String mainActivityName = getMainActivityName(); if (mainActivityName != null && mainActivityName.length() > 0) { launchMainActivity(getTargetContext().getPackageName(), getMainActivityName()); } else { super.onStart(); } } ... 12th Kandroid Conference - www.kandroid.org 112
  • 113. Doing both Controlling and Tracking 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 12th Kandroid Conference - www.kandroid.org 113
  • 114. Doing both Controlling and Tracking 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 3. Edit the <instrumentation> element in the manifest file. 12th Kandroid Conference - www.kandroid.org 114
  • 115. Doing both Controlling and Tracking 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 3. Edit the <instrumentation> element in the manifest file. 4. Build and Install the test package. $ cd ApiDemosInstrumentTest $ ant debug $ adb install –r bin/ApiDemosInstrumentTest-debug.apk 12th Kandroid Conference - www.kandroid.org 115
  • 116. Doing both Controlling and Tracking 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 3. Edit the <instrumentation> element in the manifest file. 4. Build and Install the test package. $ cd ApiDemosInstrumentTest $ ant debug $ adb install –r bin/ApiDemosInstrumentTest-debug.apk 5. Run the test and see the result. $ adb shell am instrument -w > com.example.android.apis.instrument.test/ > org.kandroid.memtracer.MemoryInstrumentation 12th Kandroid Conference - www.kandroid.org 116
  • 117. Doing both Controlling and Tracking 2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory. 3. Edit the <instrumentation> element in the manifest file. 4. Build and Install the test package. $ cd ApiDemosInstrumentTest $ ant debug $ adb install –r bin/ApiDemosInstrumentTest-debug.apk 5. Run the test and see the result. $ adb shell am instrument -w > com.example.android.apis.instrument.test/ > org.kandroid.memtracer.MemoryInstrumentation 6. Pull the trace file ‘kmemtrace.csv’ from /sdcard/kmemtracer. $ adb pull /sdcard/kmemtracer/kmemtrace.csv . 12th Kandroid Conference - www.kandroid.org 117
  • 119. Contents Why Automated Historical Performance Testing? kmemtracer: What and How? Enhancement I : Automating UI Interaction Enhancement II: Adding More Performance Metrics 12th Kandroid Conference - www.kandroid.org 119
  • 120. What to Measure? Rendering (or GUI) Performance Frame Rate (FPS), Frame Time , Jankiness, Input Latency, … Resource Consumption Memory, CPU, I/O (Disk, Network), Battery, … Network Performance Response time, Throughput, … … 12th Kandroid Conference - www.kandroid.org 120
  • 121. What to Measure? Rendering (or GUI) Performance Frame Rate (FPS), Frame Time , Jankiness, Input Latency, … Resource Consumption Memory, CPU, I/O (Disk, Network), Battery, … Network Performance Response time, Throughput, … … 12th Kandroid Conference - www.kandroid.org 121
  • 122. How to Measure Resource Consumption? 12th Kandroid Conference - www.kandroid.org 122
  • 123. How to Measure Resource Consumption? cmds API 12th Kandroid Conference - www.kandroid.org 123
  • 124. How to Measure Resource Consumption? cmds API Public Internal 12th Kandroid Conference - www.kandroid.org 124
  • 125. How to Measure Resource Consumption? cmds API Public Internal Android 12th Kandroid Conference - www.kandroid.org Linux 125
  • 126. How to Measure Resource Consumption? cmds API Public Internal Android Easy Linux Flexible 12th Kandroid Conference - www.kandroid.org 126
  • 127. Measuring Memory Usage 12th Kandroid Conference - www.kandroid.org 127
  • 130. Measuring Memory Usage Public Internal Android android.app.ActivityManager.MemoryInfo android.os.Debug android.os.Debug.MemoryInfo dalvik.system.VMDebug adb shell dumpsys meminfo [pid|pname] adb shell dumpsys gfxinfo [pid|pname] adb shell procrank 12th Kandroid Conference - www.kandroid.org 130
  • 131. Measuring Memory Usage Public Internal Android Linux android.app.ActivityManager.MemoryInfo android.os.Debug android.os.Debug.MemoryInfo dalvik.system.VMDebug adb shell dumpsys meminfo [pid|pname] adb shell dumpsys gfxinfo [pid|pname] adb shell procrank adb shell cat /proc/meminfo adb shell cat /proc/<pid>/[s]maps adb shell cat /proc/vmstat adb shell top adb shell ps 12th Kandroid Conference - www.kandroid.org 131
  • 132. Measuring Memory Usage: dumpsys meminfo $ adb shell dumpsys meminfo com.example.android.apis Applications Memory Usage (kB): Uptime: 93065 Realtime: 93065 ** MEMINFO in pid 1259 [com.example.android.apis] ** native dalvik other total size: 3548 5831 N/A 9379 allocated: 3475 3335 N/A 6810 free: 48 2496 N/A 2544 (Pss): 699 382 4889 5970 (shared dirty): 1500 1876 8356 11732 (priv dirty): 628 40 2472 3140 ... GB (API Level 10) 12th Kandroid Conference - www.kandroid.org 132
  • 133. Measuring Memory Usage: dumpsys meminfo $ adb shell dumpsys meminfo com.example.android.apis Applications Memory Usage (kB): Uptime: 93065 Realtime: 93065 ** MEMINFO in pid 1259 [com.example.android.apis] ** native dalvik other total size: 3548 5831 N/A 9379 allocated: 3475 3335 N/A 6810 free: 48 2496 N/A 2544 (Pss): 699 382 4889 5970 (shared dirty): 1500 1876 8356 11732 (priv dirty): 628 40 2472 3140 ... GB (API Level 10) 12th Kandroid Conference - www.kandroid.org 133
  • 134. Measuring Memory Usage: dumpsys meminfo $ adb shell dumpsys meminfo com.example.android.apis ... ** MEMINFO in pid 1875 [com.example.android.apis] ** Shared Private Heap Heap Pss Dirty Dirty Size Alloc -------------------------Native 1377 1256 1300 12084 7332 Dalvik 5274 5476 4952 6260 5712 Stack 76 12 76 Cursor 0 0 0 Ashmem 0 0 0 Other dev 4 20 0 .so mmap 1526 4836 592 .jar mmap 0 0 0 .apk mmap 267 0 0 .ttf mmap 5 0 0 .dex mmap 1085 0 0 Other mmap 18 8 4 Unknown 824 0 824 TOTAL 10456 11608 7748 18344 13044 ... Heap Free -----567 548 1115 JB (API Level 18) 12th Kandroid Conference - www.kandroid.org 134
  • 135. Measuring Memory Usage: dumpsys meminfo $ adb shell dumpsys meminfo com.example.android.apis ... ** MEMINFO in pid 1875 [com.example.android.apis] ** Shared Private Heap Heap Pss Dirty Dirty Size Alloc -------------------------Native 1377 1256 1300 12084 7332 Dalvik 5274 5476 4952 6260 5712 Stack 76 12 76 Cursor 0 0 0 Ashmem 0 0 0 Other dev 4 20 0 .so mmap 1526 4836 592 .jar mmap 0 0 0 .apk mmap 267 0 0 .ttf mmap 5 0 0 .dex mmap 1085 0 0 Other mmap 18 8 4 Unknown 824 0 824 TOTAL 10456 11608 7748 18344 13044 ... Heap Free -----567 548 1115 JB (API Level 18) 12th Kandroid Conference - www.kandroid.org 135
  • 137. How ‘dumpsys meminfo’ works? adb shell dumpsys meminfo [-a] [-oom] [-process] 12th Kandroid Conference - www.kandroid.org 137
  • 138. How ‘dumpsys meminfo’ works? adb shell dumpsys meminfo [-a] [-oom] [-process] com.android.server.am. ActivityManagerService 12th Kandroid Conference - www.kandroid.org 138
  • 139. How ‘dumpsys meminfo’ works? adb shell dumpsys meminfo [-a] [-oom] [-process] com.android.server.am. ActivityManagerService android.app.ActivityThread. android.app.ActivityThread. android.app.ActivityThread. ApplicationThread ApplicationThread ApplicationThread android.os Debug 12th Kandroid Conference - www.kandroid.org 139
  • 140. How ‘dumpsys meminfo’ works? adb shell dumpsys meminfo [-a] [-oom] [-process] com.android.server.am. ActivityManagerService android.app.ActivityThread. android.app.ActivityThread. android.app.ActivityThread. ApplicationThread ApplicationThread ApplicationThread android.os Debug 12th Kandroid Conference - www.kandroid.org 140
  • 141. How ‘dumpsys meminfo’ works? adb shell dumpsys meminfo [-a] [-oom] [-process] com.android.server.am. ActivityManagerService android.app.ActivityThread. android.app.ActivityThread. android.app.ActivityThread. ApplicationThread ApplicationThread ApplicationThread android.os Debug getNativeHeap*() getMemoryInfo() mallinfo() /proc/<pid>/smaps 12th Kandroid Conference - www.kandroid.org 141
  • 142. How ‘dumpsys meminfo’ works? android.app.ActivityThread.ApplicationThread.dumpMemInfo() long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.totalMemory() / 1024; long dalvikFree = runtime.freeMemory() / 1024; long dalvikAllocated = dalvikMax - dalvikFree; 12th Kandroid Conference - www.kandroid.org 142
  • 143. How ‘dumpsys meminfo’ works? android.app.ActivityThread.ApplicationThread.dumpMemInfo() long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.totalMemory() / 1024; long dalvikFree = runtime.freeMemory() / 1024; long dalvikAllocated = dalvikMax - dalvikFree; android.os.Debug.getNativeHeap*() struct mallinfo info = mallinfo(); (jlong) info.usmblks; // Debug.getNativeHeapSize() (jlong) info.uordblks; // Debug.getNativeHeapAllocatedSize() (jlong) info.fordblks; // Debug.getNativeHeapFreeSize() 12th Kandroid Conference - www.kandroid.org 143
  • 144. How ‘dumpsys meminfo’ works? struct mallinfo { MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE MALLINFO_FIELD_TYPE }; arena; ordblks; smblks; hblks; hblkhd; usmblks; fsmblks; uordblks; fordblks; keepcost; /* /* /* /* /* /* /* /* /* /* non-mmapped space allocated from system */ number of free chunks */ always 0 */ always 0 */ space in mmapped regions */ maximum total allocated space */ always 0 */ total allocated space */ total free space */ releasable (via malloc_trim) space */ bioniclibcupstream-dlmallocmalloc.c 2 4 3 1 ① Total allocated = uordblks ② Total free = fordblks ③ Footprint = uordblks + fordblks ④ Max footprint = usmblks 12th Kandroid Conference - www.kandroid.org 144
  • 145. Measuring CPU Usage 12th Kandroid Conference - www.kandroid.org 145
  • 149. Measuring CPU Usage Public Internal Android Linux android.os.Process android.os.Debug.InstructionCount com.android.internal.os.ProcessStats adb shell dumpsys cpuinfo adb shell cat /proc/stat adb shell cat /proc/<pid>/stat adb shell top 12th Kandroid Conference - www.kandroid.org 149
  • 150. Measuring CPU Usage: dumpsys cpuinfo $ adb shell dumpsys cpuinfo Load: 0.0 / 0.01 / 0.05 CPU usage from 27006ms to 5405ms ago: 1.1% 1421/com.android.launcher: 0.3% user + 0.8% kernel / faults: 2187 minor 2.4% 1225/system_server: 0.4% user + 1.9% kernel / faults: 2030 minor 0.1% 949/surfaceflinger: 0% user + 0.1% kernel / faults: 3 minor 0% 952/mediaserver: 0% user + 0% kernel / faults: 8 minor 0% 959/adbd: 0% user + 0% kernel / faults: 11 minor 0% 1295/com.android.systemui: 0% user + 0% kernel / faults: 5 minor +0% 1901/com.example.android.apis: 0% user + 0% kernel 56% TOTAL: 10% user + 45% kernel + 0.7% softirq 12th Kandroid Conference - www.kandroid.org 150
  • 151. How ‘dumpsys cpuinfo’ works? adb shell dumpsys cpuinfo 12th Kandroid Conference - www.kandroid.org 151
  • 152. How ‘dumpsys cpuinfo’ works? adb shell dumpsys cpuinfo com.android.server.am. ActivityManagerService 12th Kandroid Conference - www.kandroid.org 152
  • 153. How ‘dumpsys cpuinfo’ works? adb shell dumpsys cpuinfo com.android.server.am. ActivityManagerService com.android.internal.os ProcessStats 12th Kandroid Conference - www.kandroid.org 153
  • 154. How ‘dumpsys cpuinfo’ works? adb shell dumpsys cpuinfo com.android.server.am. ActivityManagerService com.android.internal.os ProcessStats com.android.internal.os com.android.internal.os com.android.internal.os ProcessStats.Stats ProcessStats.Stats ProcessStats.Stats 12th Kandroid Conference - www.kandroid.org 154
  • 155. How ‘dumpsys cpuinfo’ works? adb shell dumpsys cpuinfo com.android.server.am. ActivityManagerService android.os Process com.android.internal.os ProcessStats com.android.internal.os com.android.internal.os com.android.internal.os ProcessStats.Stats ProcessStats.Stats ProcessStats.Stats android_util_ Process.cpp /proc/stat /proc/loadavg /proc/<pid>/stat /proc/<ppid>/task/<pid>/stat 12th Kandroid Conference - www.kandroid.org 155
  • 156. How ‘dumpsys cpuinfo’ works? procfs (or the proc filesystem) is a special filesystem in UNIXlike operating systems that presents information about processes and other system information in a hierarchical file-like structure, providing a more convenient and standardized method for dynamically accessing process data held in the kernel than traditional tracing methods or direct access to kernel memory. http://en.wikipedia.org/wiki/Procfs 12th Kandroid Conference - www.kandroid.org 156
  • 157. How ‘dumpsys cpuinfo’ works? procfs (or the proc filesystem) is a special filesystem in UNIXlike operating systems that presents information about processes and other system information in a hierarchical file-like structure, providing a more convenient and standardized method for dynamically accessing process data held in the kernel than traditional tracing methods or direct access to kernel memory. http://en.wikipedia.org/wiki/Procfs http://manpages.courier-mta.org/htmlman5/proc.5.html 12th Kandroid Conference - www.kandroid.org 157
  • 158. Measuring I/O Usage 12th Kandroid Conference - www.kandroid.org 158
  • 159. Measuring I/O Usage Public android.net.TrafficStats 12th Kandroid Conference - www.kandroid.org 159
  • 163. Measuring Network IO Usage: dumpsys netstats $ adb shell dumpsys netstats Active interfaces: iface=eth0 ident=[[type=MOBILE, subType=COMBINED, subscriberId=310260000000000]] Dev stats: Pending bytes: 43783 History since boot: ident=[[type=MOBILE_HIPRI, subType=COMBINED, subscriberId=310260000000000], [type=MOBILE, subType=COMBINED, subscriberId=310260000000000]] uid=-1 set=ALL tag=0x0 NetworkStatsHistory: bucketDuration=3600000 bucketStart=1382443200000 activeTime=4813 rxBytes=17410 rxPackets=203 txBytes=25579 txPackets=173 operations=0 ... Xt stats: Pending bytes: 37557 History since boot: ident=[[type=MOBILE_HIPRI, subType=COMBINED, subscriberId=310260000000000], [type=MOBILE, subType=COMBINED, subscriberId=310260000000000]] uid=-1 set=ALL tag=0x0 ... UID stats: ... UID tag stats: ... 12th Kandroid Conference - www.kandroid.org 163
  • 164. How ‘dumpsys netstats’ works? adb shell dumpsys netstats [--full] [--uid] [--tag] 12th Kandroid Conference - www.kandroid.org 164
  • 165. How ‘dumpsys netstats’ works? adb shell dumpsys netstats [--full] [--uid] [--tag] com.android.server.net. NetworkStatsService 12th Kandroid Conference - www.kandroid.org 165
  • 166. How ‘dumpsys netstats’ works? adb shell dumpsys netstats [--full] [--uid] [--tag] com.android.server.net. NetworkStatsService com.android.server.net com.android.server.net com.android.server.net NetworkStatsRecorder NetworkStatsRecorder com.android.server.net NetworkStatsRecorder NetworkStatsRecorder 12th Kandroid Conference - www.kandroid.org 166
  • 167. How ‘dumpsys netstats’ works? adb shell dumpsys netstats [--full] [--uid] [--tag] com.android.server.net. NetworkStatsService com.android.server.net com.android.server.net com.android.server.net NetworkStatsRecorder NetworkStatsRecorder com.android.server.net NetworkStatsRecorder NetworkStatsRecorder com.android.server.net NetworkStatsCollection android.net android.net NetworkStatsHistory android.net NetworkStatsHistory NetworkStatsHistory 12th Kandroid Conference - www.kandroid.org 167
  • 168. How ‘dumpsys netstats’ works? adb shell dumpsys netstats [--full] [--uid] [--tag] com.android.server NetworkManagementService com.android.server.net. NetworkStatsService com.android.server.net com.android.server.net com.android.server.net NetworkStatsRecorder NetworkStatsRecorder com.android.server.net NetworkStatsRecorder NetworkStatsRecorder com.android.server.net NetworkStatsCollection android.net android.net NetworkStatsHistory android.net NetworkStatsHistory NetworkStatsHistory com.android.internal.net NetworkStatsFactory /proc/net/xt_qtaguid/iface_stat_all /proc/net/xt_qtaguid/iface_stat_fmt /proc/net/xt_qtaguid/stats 12th Kandroid Conference - www.kandroid.org android.net NetworkStats 168
  • 169. How ‘dumpsys netstats’ works? com.android.server.net.NetworkStatsService.DefaultNetworkStatsSettings @Override public Config getDevConfig() { return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS), getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS), getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS)); } @Override public Config getXtConfig() { return getDevConfig(); } @Override public Config getUidConfig() { return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS), getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS), getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS)); } @Override public Config getUidTagConfig() { return new Config(getSecureLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS), getSecureLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS), getSecureLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS)); } 12th Kandroid Conference - www.kandroid.org 169
  • 170. How ‘dumpsys netstats’ works? Dev: IP + Non IP layer traffic $ adb shell cat /proc/net/xt_qtaguid/iface_stat_all eth0 1 0 0 0 0 220609 3228 2891157 2995 Xt: Only IP layer traffic $ adb shell cat /proc/net/xt_qtaguid/iface_stat_fmt ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes total_skb_tx_packets eth0 163781 3231 2846738 2994 Uid: UID level details $ adb shell cat /proc/net/xt_qtaguid/stats idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets 2 eth0 0x0 0 0 163335 3226 2846228 2988 161473 3222 1862 4 0 0 2845850 2982 266 4 112 2 3 eth0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 eth0 0x0 1000 0 819 11 965 12 667 9 152 2 0 0 813 10 152 2 0 0 5 eth0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12th Kandroid Conference - www.kandroid.org 170
  • 171. Measuring Battery Usage 12th Kandroid Conference - www.kandroid.org 171
  • 172. Measuring Battery Usage Public android.os.BatteryManager 12th Kandroid Conference - www.kandroid.org 172
  • 176. Measuring Battery Usage: dumpsys batteryinfo $ adb shell dumpsys batteryinfo Battery History: -1d00h43m02s057ms START -1d00h40m00s730ms 050 20080002 status=charging health=good plug=ac temp=0 volt=0 +plugged +sensor brightness=medium -1d00h39m57s332ms 050 60080002 +wake_lock -1d00h39m57s202ms 050 60080302 phone_state=off ... Per-PID Stats: PID 1227 wake time: +3s445ms PID 1227 wake time: +199ms ... Statistics since last charge: System starts: 29, currently on battery: false Time on battery: 0ms (0.0%) realtime, 0ms (0.0%) uptime Total run time: 1d 2h 1m 3s 606ms realtime, 1d 2h 1m 3s 603ms uptime, ... #1000: User activity: 26 other, 27 button, 93 touch Sensor 0: (not used) Apk com.android.keychain: (nothing executed) ... Statistics since last unplugged: Time on battery: 0ms (0.0%) realtime, 0ms (0.0%) uptime ... 12th Kandroid Conference - www.kandroid.org 176
  • 177. How ‘dumpsys batteryinfo’ works? adb shell dumpsys batteryinfo 12th Kandroid Conference - www.kandroid.org 177
  • 178. How ‘dumpsys batteryinfo’ works? adb shell dumpsys batteryinfo com.android.server.am. BatteryStatsService 12th Kandroid Conference - www.kandroid.org 178
  • 179. How ‘dumpsys batteryinfo’ works? adb shell dumpsys batteryinfo com.android.server.am. BatteryStatsService com.android.internal.os BatteryStatsImpl 12th Kandroid Conference - www.kandroid.org 179
  • 180. How ‘dumpsys batteryinfo’ works? adb shell dumpsys batteryinfo com.android.server.am. BatteryStatsService com.android.internal.os BatteryStatsImpl android.os BatteryStats 12th Kandroid Conference - www.kandroid.org 180
  • 181. How ‘dumpsys batteryinfo’ works? adb shell dumpsys batteryinfo com.android.server.am. BatteryStatsService com.android.internal.os BatteryStatsImpl android.os BatteryStats noteBluetoothOff() noteBluetoothOn() noteFullWifiLockAcquired(int) noteFullWifiLockAcquiredFromSource(WorkSource) noteFullWifiLockReleased(int) noteFullWifiLockReleasedFromSource(WorkSource) noteInputEvent() noteNetworkInterfaceType(String, int) notePhoneDataConnectionState(int, boolean) notePhoneOff() notePhoneOn() notePhoneSignalStrength(SignalStrength) notePhoneState(int) noteScreenBrightness(int) noteScreenOff() noteScreenOn() ... noteWifiScanStarted(int) noteWifiScanStartedFromSource(WorkSource) noteWifiScanStopped(int) noteWifiScanStoppedFromSource(WorkSource) noteWifiStopped(WorkSource) 12th Kandroid Conference - www.kandroid.org 181
  • 182. If you can’t automate the measurement of it, it is difficult to improve it. 12th Kandroid Conference - www.kandroid.org 182
  • 183. If you can’t automate the measurement of it, it is difficult to improve it. If you can’t understand the measurement results, it is impossible to improve it. 12th Kandroid Conference - www.kandroid.org 183