summaryrefslogtreecommitdiffstats
path: root/tools/android
diff options
context:
space:
mode:
authorqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-25 16:01:03 +0000
committerqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-25 16:01:03 +0000
commit7061f74d55901a430ba1a016c6335b54e0882716 (patch)
tree1b510e547cbdfd6ba33fc854ccf54bc2f1a8e7e7 /tools/android
parent520463bb07afafa722cceceea1247f2e833b2e75 (diff)
downloadchromium_src-7061f74d55901a430ba1a016c6335b54e0882716.zip
chromium_src-7061f74d55901a430ba1a016c6335b54e0882716.tar.gz
chromium_src-7061f74d55901a430ba1a016c6335b54e0882716.tar.bz2
Adding MemConsumer android application.
The MemConsumer application is a simple android application that will allocate a configurable amount of memory and that can be used to test the system with a known external memory pressure. R=bulach@chromium.org, frankf@chromium.org BUG=244975 Review URL: https://codereview.chromium.org/23976013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225191 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/android')
-rw-r--r--tools/android/android_tools.gyp9
-rw-r--r--tools/android/memconsumer/java/AndroidManifest.xml23
-rw-r--r--tools/android/memconsumer/java/src/org/chromium/memconsumer/MemConsumer.java107
-rw-r--r--tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java62
-rw-r--r--tools/android/memconsumer/memconsumer.gyp40
-rw-r--r--tools/android/memconsumer/memconsumer_hook.cc55
6 files changed, 295 insertions, 1 deletions
diff --git a/tools/android/android_tools.gyp b/tools/android/android_tools.gyp
index c38cd70..0e566d9 100644
--- a/tools/android/android_tools.gyp
+++ b/tools/android/android_tools.gyp
@@ -22,6 +22,13 @@
'dependencies': [
'memdump/memdump.gyp:memdump',
],
- }
+ },
+ {
+ 'target_name': 'memconsumer',
+ 'type': 'none',
+ 'dependencies': [
+ 'memconsumer/memconsumer.gyp:memconsumer',
+ ],
+ },
],
}
diff --git a/tools/android/memconsumer/java/AndroidManifest.xml b/tools/android/memconsumer/java/AndroidManifest.xml
new file mode 100644
index 0000000..c7f12e42
--- /dev/null
+++ b/tools/android/memconsumer/java/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2013 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.chromium.memconsumer" android:versionCode="1"
+ android:versionName="1.0">
+
+ <application
+ android:label="MemConsumer">
+ <activity android:name=".MemConsumer" android:icon="@drawable/icon" android:launchMode="singleTop">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ <service android:name="ResidentService" android:enabled="true" />
+ </application>
+
+</manifest>
diff --git a/tools/android/memconsumer/java/src/org/chromium/memconsumer/MemConsumer.java b/tools/android/memconsumer/java/src/org/chromium/memconsumer/MemConsumer.java
new file mode 100644
index 0000000..8f45d94
--- /dev/null
+++ b/tools/android/memconsumer/java/src/org/chromium/memconsumer/MemConsumer.java
@@ -0,0 +1,107 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.memconsumer;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.KeyEvent;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.NumberPicker;
+import android.widget.TextView;
+
+public class MemConsumer extends Activity {
+ public static final String NOTIFICATION_ACTION =
+ MemConsumer.class.toString() + ".NOTIFICATION";
+
+ private ResidentService mResidentService;
+ private int mMemory = 0;
+ private NumberPicker mMemoryPicker;
+
+ private ServiceConnection mServiceConnection = new ServiceConnection() {
+
+ public void onServiceConnected(ComponentName name,
+ IBinder binder) {
+ mResidentService = ((ResidentService.ServiceBinder)binder).getService();
+ mResidentService.useMemory(mMemory);
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ mResidentService = null;
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mMemoryPicker = new NumberPicker(this);
+ mMemoryPicker.setGravity(Gravity.CENTER);
+ mMemoryPicker.setMaxValue(Integer.MAX_VALUE);
+ mMemoryPicker.setMinValue(0);
+ mMemoryPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ updateMemoryConsumption(picker.getValue());
+ }
+ });
+ for (int i = 0; i < mMemoryPicker.getChildCount(); i++) {
+ View child = mMemoryPicker.getChildAt(i);
+ if (child instanceof EditText) {
+ EditText editText = (EditText)child;
+ editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction (TextView v, int actionId, KeyEvent event) {
+ if (v.getText().length() > 0) {
+ updateMemoryConsumption(Integer.parseInt(v.getText().toString()));
+ }
+ return false;
+ }
+ });
+ }
+ }
+ setContentView(mMemoryPicker);
+ onNewIntent(getIntent());
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ if (intent.getAction() == NOTIFICATION_ACTION) {
+ updateMemoryConsumption(0);
+ return;
+ }
+ if (!intent.hasExtra("memory")) return;
+ updateMemoryConsumption(intent.getIntExtra("memory", 0));
+ }
+
+ void updateMemoryConsumption(int memory) {
+ if (memory == mMemory || memory < 0) return;
+ mMemory = memory;
+ mMemoryPicker.setValue(mMemory);
+ if (mResidentService == null) {
+ if (mMemory > 0) {
+ Intent resident = new Intent();
+ resident.setClass(this, ResidentService.class);
+ startService(resident);
+ bindService(new Intent(this, ResidentService.class),
+ mServiceConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+ } else {
+ mResidentService.useMemory(mMemory);
+ if (mMemory == 0) {
+ unbindService(mServiceConnection);
+ stopService(new Intent(this, ResidentService.class));
+ mResidentService = null;
+ }
+ }
+ }
+}
diff --git a/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java b/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java
new file mode 100644
index 0000000..e40fbfe
--- /dev/null
+++ b/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java
@@ -0,0 +1,62 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.memconsumer;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+
+public class ResidentService extends Service {
+ static {
+ // Loading the native library.
+ System.loadLibrary("memconsumer");
+ }
+
+ public class ServiceBinder extends Binder {
+ ResidentService getService() {
+ return ResidentService.this;
+ }
+ }
+
+ private static final int RESIDENT_NOTIFICATION_ID = 1;
+
+ private final IBinder mBinder = new ServiceBinder();
+ private boolean mIsInForeground = false;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ public void useMemory(long memory) {
+ if (memory > 0) {
+ Intent notificationIntent = new Intent(this, MemConsumer.class);
+ notificationIntent.setAction(MemConsumer.NOTIFICATION_ACTION);
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(this, 0, notificationIntent, 0);
+ Notification notification =
+ new Notification.Builder(getApplicationContext()).
+ setContentTitle("MC running (" + memory + "Mb)").
+ setSmallIcon(R.drawable.notification_icon).
+ setDeleteIntent(pendingIntent).
+ setContentIntent(pendingIntent).
+ build();
+ startForeground(RESIDENT_NOTIFICATION_ID, notification);
+ mIsInForeground = true;
+ }
+ if (mIsInForeground && memory == 0) {
+ stopForeground(true);
+ mIsInForeground = false;
+ }
+ nativeUseMemory(memory * 1024 * 1024);
+ }
+
+ // Allocate the amount of memory in native code. Otherwise the memory
+ // allocation is limited by the framework.
+ private native void nativeUseMemory(long memory);
+}
diff --git a/tools/android/memconsumer/memconsumer.gyp b/tools/android/memconsumer/memconsumer.gyp
new file mode 100644
index 0000000..e87a92b
--- /dev/null
+++ b/tools/android/memconsumer/memconsumer.gyp
@@ -0,0 +1,40 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'memconsumer',
+ 'type': 'none',
+ 'dependencies': [
+ 'memconsumer_apk',
+ ],
+ },
+ {
+ 'target_name': 'memconsumer_apk',
+ 'type': 'none',
+ 'variables': {
+ 'apk_name': 'MemConsumer',
+ 'package_name': 'memconsumer',
+ 'java_in_dir': 'java',
+ 'resource_dir': 'java/res',
+ 'native_lib_target': 'libmemconsumer',
+ },
+ 'dependencies': [
+ 'libmemconsumer',
+ ],
+ 'includes': [ '../../../build/java_apk.gypi' ],
+ },
+ {
+ 'target_name': 'libmemconsumer',
+ 'type': 'shared_library',
+ 'sources': [
+ 'memconsumer_hook.cc',
+ ],
+ 'libraries': [
+ '-llog',
+ ],
+ },
+ ],
+}
diff --git a/tools/android/memconsumer/memconsumer_hook.cc b/tools/android/memconsumer/memconsumer_hook.cc
new file mode 100644
index 0000000..9ae0bc1
--- /dev/null
+++ b/tools/android/memconsumer/memconsumer_hook.cc
@@ -0,0 +1,55 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <android/log.h>
+#include <jni.h>
+#include <stdio.h>
+#include <string.h>
+
+extern "C" {
+JNIEXPORT void JNICALL
+ Java_org_chromium_memconsumer_ResidentService_nativeUseMemory(JNIEnv* env,
+ jobject clazz,
+ jlong memory);
+}
+
+namespace {
+
+uint32_t get_random() {
+ static uint32_t m_w = 1;
+ static uint32_t m_z = 1;
+ m_z = 36969 * (m_z & 65535) + (m_z >> 16);
+ m_w = 18000 * (m_w & 65535) + (m_w >> 16);
+ return (m_z << 16) + m_w;
+}
+
+} // namespace
+
+JNIEXPORT void JNICALL
+ Java_org_chromium_memconsumer_ResidentService_nativeUseMemory(
+ JNIEnv* env,
+ jobject clazz,
+ jlong memory) {
+ static uint32_t* g_memory = NULL;
+ if (g_memory)
+ free(g_memory);
+ if (memory == 0) {
+ g_memory = NULL;
+ return;
+ }
+ g_memory = static_cast<uint32_t*>(malloc(memory));
+ if (!g_memory) {
+ __android_log_print(ANDROID_LOG_WARN,
+ "MemConsumer",
+ "Unable to allocate %ld bytes",
+ memory);
+ }
+ // If memory allocation failed, try to allocate as much as possible.
+ while (!g_memory) {
+ memory /= 2;
+ g_memory = static_cast<uint32_t*>(malloc(memory));
+ }
+ for (int i = 0; i < memory / sizeof(uint32_t); ++i)
+ *(g_memory + i) = get_random();
+}