• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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