diff options
author | qsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-25 16:01:03 +0000 |
---|---|---|
committer | qsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-25 16:01:03 +0000 |
commit | 7061f74d55901a430ba1a016c6335b54e0882716 (patch) | |
tree | 1b510e547cbdfd6ba33fc854ccf54bc2f1a8e7e7 /tools/android | |
parent | 520463bb07afafa722cceceea1247f2e833b2e75 (diff) | |
download | chromium_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')
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(); +} |