1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.fakeoemfeatures; 18 19 import static android.view.Display.DEFAULT_DISPLAY; 20 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 21 22 import android.app.ActivityManager; 23 import android.app.ActivityThread; 24 import android.app.AlertDialog; 25 import android.app.Application; 26 import android.app.Dialog; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.ServiceConnection; 31 import android.graphics.Rect; 32 import android.hardware.display.DisplayManager; 33 import android.os.Handler; 34 import android.os.IBinder; 35 import android.os.Message; 36 import android.util.Slog; 37 import android.view.Display; 38 import android.view.ViewGroup; 39 import android.view.WindowManager; 40 41 public class FakeApp extends Application { 42 // Stuffing of 20MB 43 static final int STUFFING_SIZE_BYTES = 20*1024*1024; 44 static final int STUFFING_SIZE_INTS = STUFFING_SIZE_BYTES/4; 45 int[] mStuffing; 46 47 // Assume 4k pages. 48 static final int PAGE_SIZE = 4*1024; 49 50 static final long TICK_DELAY = 4*60*60*1000; // One hour 51 static final int MSG_TICK = 1; 52 final Handler mHandler = new Handler() { 53 @Override public void handleMessage(Message msg) { 54 switch (msg.what) { 55 case MSG_TICK: 56 // Our service is IMPORTANT. We know, we wrote it. 57 // We need to keep that thing running. Because WE KNOW. 58 // Damn you users, STOP MESSING WITH US. 59 startService(new Intent(FakeApp.this, FakeBackgroundService.class)); 60 sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY); 61 break; 62 default: 63 super.handleMessage(msg); 64 break; 65 } 66 } 67 }; 68 69 // Always run another process for more per-process overhead. 70 ServiceConnection mServiceConnection = new ServiceConnection() { 71 @Override public void onServiceConnected(ComponentName name, IBinder service) { 72 } 73 74 @Override public void onServiceDisconnected(ComponentName name) { 75 } 76 }; 77 ServiceConnection mServiceConnection2 = new ServiceConnection() { 78 @Override public void onServiceConnected(ComponentName name, IBinder service) { 79 } 80 81 @Override public void onServiceDisconnected(ComponentName name) { 82 } 83 }; 84 ServiceConnection mServiceConnection3 = new ServiceConnection() { 85 @Override public void onServiceConnected(ComponentName name, IBinder service) { 86 } 87 88 @Override public void onServiceDisconnected(ComponentName name) { 89 } 90 }; 91 92 @Override onCreate()93 public void onCreate() { 94 String processName = ActivityThread.currentProcessName(); 95 Slog.i("FakeOEMFeatures", "Creating app in process: " + processName); 96 if (!getApplicationInfo().packageName.equals(processName)) { 97 // If we are not in the main process of the app, then don't do 98 // our extra overhead stuff. 99 return; 100 } 101 102 // Construct an instance of WindowManager to add the window of TYPE_APPLICATION_OVERLAY to 103 // the default display. 104 final DisplayManager dm = getSystemService(DisplayManager.class); 105 final Display defaultDisplay = dm.getDisplay(DEFAULT_DISPLAY); 106 final Context windowContext = createDisplayContext(defaultDisplay) 107 .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */); 108 final WindowManager wm = windowContext.getSystemService(WindowManager.class); 109 110 // Check to make sure we are not running on a user build. If this 111 // is a user build, WARN! Do not want! 112 if ("user".equals(android.os.Build.TYPE)) { 113 AlertDialog.Builder builder = new AlertDialog.Builder(this); 114 builder.setTitle("Should not be on user build"); 115 builder.setMessage("The app Fake OEM Features should not be installed on a " 116 + "user build. Please remove this .apk before shipping this build to " 117 + " your customers!"); 118 builder.setCancelable(false); 119 builder.setPositiveButton("I understand", null); 120 Dialog dialog = builder.create(); 121 dialog.getWindow().setType(TYPE_APPLICATION_OVERLAY); 122 dialog.show(); 123 } 124 125 // Make a fake window that is always around eating graphics resources. 126 FakeView view = new FakeView(this); 127 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 128 TYPE_APPLICATION_OVERLAY, 129 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 130 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 131 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); 132 if (ActivityManager.isHighEndGfx()) { 133 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 134 } 135 lp.width = ViewGroup.LayoutParams.MATCH_PARENT; 136 lp.height = ViewGroup.LayoutParams.MATCH_PARENT; 137 Rect maxWindowBounds = wm.getMaximumWindowMetrics().getBounds(); 138 int maxSize = Math.max(maxWindowBounds.width(), maxWindowBounds.height()); 139 maxSize *= 2; 140 lp.x = maxSize; 141 lp.y = maxSize; 142 lp.setTitle(getPackageName()); 143 wm.addView(view, lp); 144 145 // Bind to a fake service we want to keep running in another process. 146 bindService(new Intent(this, FakeCoreService.class), mServiceConnection, 147 Context.BIND_AUTO_CREATE); 148 bindService(new Intent(this, FakeCoreService2.class), mServiceConnection2, 149 Context.BIND_AUTO_CREATE); 150 bindService(new Intent(this, FakeCoreService3.class), mServiceConnection3, 151 Context.BIND_AUTO_CREATE); 152 153 // Start to a fake service that should run in the background of 154 // another process. 155 mHandler.sendEmptyMessage(MSG_TICK); 156 157 // Make a fake allocation to consume some RAM. 158 mStuffing = new int[STUFFING_SIZE_INTS]; 159 for (int i=0; i<STUFFING_SIZE_BYTES/PAGE_SIZE; i++) { 160 // Fill each page with a unique value. 161 final int VAL = i*2 + 100; 162 final int OFF = (i*PAGE_SIZE)/4; 163 for (int j=0; j<(PAGE_SIZE/4); j++) { 164 mStuffing[OFF+j] = VAL; 165 } 166 } 167 } 168 } 169