blob: a2da23e918d21245ddbc2224a07011cc4e69e813 [file] [log] [blame]
/*
* Copyright (C) 2012 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.fakeoemfeatures;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.Application;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Slog;
import android.view.Display;
import android.view.ViewGroup;
import android.view.WindowManager;
public class FakeApp extends Application {
// Stuffing of 20MB
static final int STUFFING_SIZE_BYTES = 20*1024*1024;
static final int STUFFING_SIZE_INTS = STUFFING_SIZE_BYTES/4;
int[] mStuffing;
// Assume 4k pages.
static final int PAGE_SIZE = 4*1024;
static final long TICK_DELAY = 4*60*60*1000; // One hour
static final int MSG_TICK = 1;
final Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TICK:
// Our service is IMPORTANT. We know, we wrote it.
// We need to keep that thing running. Because WE KNOW.
// Damn you users, STOP MESSING WITH US.
startService(new Intent(FakeApp.this, FakeBackgroundService.class));
sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
break;
default:
super.handleMessage(msg);
break;
}
}
};
// Always run another process for more per-process overhead.
ServiceConnection mServiceConnection = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override public void onServiceDisconnected(ComponentName name) {
}
};
ServiceConnection mServiceConnection2 = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override public void onServiceDisconnected(ComponentName name) {
}
};
ServiceConnection mServiceConnection3 = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override public void onServiceDisconnected(ComponentName name) {
}
};
@Override
public void onCreate() {
String processName = ActivityThread.currentProcessName();
Slog.i("FakeOEMFeatures", "Creating app in process: " + processName);
if (!getApplicationInfo().packageName.equals(processName)) {
// If we are not in the main process of the app, then don't do
// our extra overhead stuff.
return;
}
// Construct an instance of WindowManager to add the window of TYPE_APPLICATION_OVERLAY to
// the default display.
final DisplayManager dm = getSystemService(DisplayManager.class);
final Display defaultDisplay = dm.getDisplay(DEFAULT_DISPLAY);
final Context windowContext = createDisplayContext(defaultDisplay)
.createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
final WindowManager wm = windowContext.getSystemService(WindowManager.class);
// Check to make sure we are not running on a user build. If this
// is a user build, WARN! Do not want!
if ("user".equals(android.os.Build.TYPE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Should not be on user build");
builder.setMessage("The app Fake OEM Features should not be installed on a "
+ "user build. Please remove this .apk before shipping this build to "
+ " your customers!");
builder.setCancelable(false);
builder.setPositiveButton("I understand", null);
Dialog dialog = builder.create();
dialog.getWindow().setType(TYPE_APPLICATION_OVERLAY);
dialog.show();
}
// Make a fake window that is always around eating graphics resources.
FakeView view = new FakeView(this);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
Rect maxWindowBounds = wm.getMaximumWindowMetrics().getBounds();
int maxSize = Math.max(maxWindowBounds.width(), maxWindowBounds.height());
maxSize *= 2;
lp.x = maxSize;
lp.y = maxSize;
lp.setTitle(getPackageName());
wm.addView(view, lp);
// Bind to a fake service we want to keep running in another process.
bindService(new Intent(this, FakeCoreService.class), mServiceConnection,
Context.BIND_AUTO_CREATE);
bindService(new Intent(this, FakeCoreService2.class), mServiceConnection2,
Context.BIND_AUTO_CREATE);
bindService(new Intent(this, FakeCoreService3.class), mServiceConnection3,
Context.BIND_AUTO_CREATE);
// Start to a fake service that should run in the background of
// another process.
mHandler.sendEmptyMessage(MSG_TICK);
// Make a fake allocation to consume some RAM.
mStuffing = new int[STUFFING_SIZE_INTS];
for (int i=0; i<STUFFING_SIZE_BYTES/PAGE_SIZE; i++) {
// Fill each page with a unique value.
final int VAL = i*2 + 100;
final int OFF = (i*PAGE_SIZE)/4;
for (int j=0; j<(PAGE_SIZE/4); j++) {
mStuffing[OFF+j] = VAL;
}
}
}
}