blob: b7cd6c7c75ae2791137b1a87c6fc9e56a2da83da [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.oomcatcher;
import android.app.Activity;
import android.os.Bundle;
import android.app.ActivityManager;
import android.content.Context;
import android.content.ComponentCallbacks2;
import android.util.Log;
import java.util.concurrent.atomic.AtomicBoolean;
/*
* An App to report to logcat the lowmemory status. As soon as the app detects low memory, it
* immediately reports. In addition, it also reports every second.
*/
public class OomCatcher extends Activity implements ComponentCallbacks2 {
private static final String LOG_TAG = "OomCatcher";
private AtomicBoolean isOom = new AtomicBoolean(false);
Thread logThread;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
logThread = new Thread() {
@Override
public void run() {
while (true) {
logStatus();
try {
Thread.sleep(1000); // 1 second
} catch (InterruptedException e) {
// thread has been killed
}
}
}
};
logThread.setDaemon(true);
logThread.start();
}
public void onDestroy() {
super.onDestroy();
if (logThread != null) {
logThread.interrupt();
}
}
/*
* Receive memory callbacks from the Android system. All report low memory except for
* TRIM_MEMORY_UI_HIDDEN, which reports when the app is in the background. We don't care about
* that, only when the device is at risk of OOMing.
*
* For all indications of low memory, onLowMemory() is called.
*/
@Override
public void onTrimMemory(int level) {
Log.i(LOG_TAG, "Memory trim level: " + level);
switch (level) {
// low priority messages being ignored
case TRIM_MEMORY_BACKGROUND: // bg
case TRIM_MEMORY_RUNNING_MODERATE: // fg
// fallthrough
Log.i(LOG_TAG, "ignoring low priority oom messages.");
break;
// medium priority messages being ignored
case TRIM_MEMORY_MODERATE: // bg
case TRIM_MEMORY_RUNNING_LOW: // fg
// fallthrough
Log.i(LOG_TAG, "ignoring medium priority oom messages.");
break;
// high priority messages
case TRIM_MEMORY_COMPLETE: // bg
case TRIM_MEMORY_RUNNING_CRITICAL: // fg
// fallthrough
onLowMemory();
break;
case TRIM_MEMORY_UI_HIDDEN:
Log.i(LOG_TAG, "UI is hidden because the app is in the background.");
break;
default:
Log.i(LOG_TAG, "unknown memory trim message.");
return;
}
}
/*
* An earlier API implementation of low memory callbacks. Sets oom status and logs.
*/
@Override
public void onLowMemory() {
isOom.set(true);
logStatus();
}
/*
* Log to logcat the current lowmemory status of the app.
*/
private void logStatus() {
Log.i(LOG_TAG, isOom.get() ? "Low memory" : "Normal memory");
}
}