1b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka/* 2b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * Copyright (C) 2017 The Android Open Source Project 3b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * 4b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * Licensed under the Apache License, Version 2.0 (the "License"); 5b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * you may not use this file except in compliance with the License. 6b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * You may obtain a copy of the License at 7b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * 8b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * http://www.apache.org/licenses/LICENSE-2.0 9b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * 10b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * Unless required by applicable law or agreed to in writing, software 11b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * distributed under the License is distributed on an "AS IS" BASIS, 12b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * See the License for the specific language governing permissions and 14b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * limitations under the License. 15b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka */ 16b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankapackage com.android.coretests.apps.bstatstestapp; 17b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 18b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.R; 19b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.Notification; 20b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.NotificationChannel; 21b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.NotificationManager; 22b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.Service; 23b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.content.Intent; 24b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.graphics.Color; 25b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.graphics.Point; 26b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.Handler; 27b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.IBinder; 28b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.Process; 29b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.RemoteException; 30b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.util.Log; 31b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.Gravity; 32b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.View; 33b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.ViewGroup; 34b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.WindowManager; 35b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 36b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport java.util.concurrent.CountDownLatch; 37b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport java.util.concurrent.TimeUnit; 38b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 39b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankapublic class TestService extends Service { 40b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private static final String TAG = TestService.class.getSimpleName(); 41b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 42b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private static final int FLAG_START_FOREGROUND = 1; 43b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 44b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private static final String NOTIFICATION_CHANNEL_ID = TAG; 45b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private static final int NOTIFICATION_ID = 42; 46b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 47b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private static final int TIMEOUT_OVERLAY_SEC = 2; 48b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 49b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private View mOverlay; 50b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 51b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 52b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public void onCreate() { 53b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Log.d(TAG, "onCreate called. myUid=" + Process.myUid()); 54b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 55b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 56b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 57b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public int onStartCommand(Intent intent, int flags, int startId) { 58b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Log.d(TAG, "onStartCommand called. myUid=" + Process.myUid()); 59b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka if (intent != null && (intent.getFlags() & FLAG_START_FOREGROUND) != 0) { 60b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka startForeground(); 61b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 62b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka notifyServiceLaunched(intent); 63b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka return START_STICKY; 64b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 65b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 66b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 67b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public IBinder onBind(Intent intent) { 68b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Log.d(TAG, "onBind called. myUid=" + Process.myUid()); 69b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka return null; 70b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 71b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 72b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 73b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public void onDestroy() { 74b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Log.d(TAG, "onDestroy called. myUid=" + Process.myUid()); 75b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka removeOverlays(); 76b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 77b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 78b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private void notifyServiceLaunched(Intent intent) { 79b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Common.notifyLaunched(intent, mReceiver.asBinder(), TAG); 80b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 81b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 82b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private void startForeground() { 83b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final NotificationManager noMan = getSystemService(NotificationManager.class); 84b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka noMan.createNotificationChannel(new NotificationChannel( 85b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID, 86b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka NotificationManager.IMPORTANCE_DEFAULT)); 87b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Log.d(TAG, "Starting foreground. myUid=" + Process.myUid()); 88b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka startForeground(NOTIFICATION_ID, 89b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka new Notification.Builder(this, NOTIFICATION_CHANNEL_ID) 90b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka .setSmallIcon(R.drawable.ic_dialog_alert) 91b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka .build()); 92b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 93b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 94b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private void removeOverlays() { 95b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka if (mOverlay != null) { 96b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final WindowManager wm = TestService.this.getSystemService(WindowManager.class); 97b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wm.removeView(mOverlay); 98b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka mOverlay = null; 99b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 100b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 101b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 102b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka private BaseCmdReceiver mReceiver = new BaseCmdReceiver() { 103b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 104b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public void doSomeWork(int durationMs) { 105b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Common.doSomeWork(durationMs); 106b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 107b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 108b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 109b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public void showApplicationOverlay() throws RemoteException { 110b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final WindowManager wm = TestService.this.getSystemService(WindowManager.class); 111b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final Point size = new Point(); 112b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wm.getDefaultDisplay().getSize(size); 113b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 114b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams( 115b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, 116b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 117b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 118b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 119b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wmlp.width = size.x / 2; 120b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wmlp.height = size.y / 2; 121b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wmlp.gravity = Gravity.CENTER | Gravity.LEFT; 122b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wmlp.setTitle(TAG); 123b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 124b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final ViewGroup.LayoutParams vglp = new ViewGroup.LayoutParams( 125b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka ViewGroup.LayoutParams.MATCH_PARENT, 126b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka ViewGroup.LayoutParams.MATCH_PARENT); 127b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 128b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka mOverlay = new View(TestService.this); 129b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka mOverlay.setBackgroundColor(Color.GREEN); 130b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka mOverlay.setLayoutParams(vglp); 131b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 132b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final CountDownLatch latch = new CountDownLatch(1); 133b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka final Handler handler = new Handler(TestService.this.getMainLooper()); 134b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka handler.post(() -> { 135b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka wm.addView(mOverlay, wmlp); 136b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka latch.countDown(); 137b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka }); 138b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka try { 139b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka if (!latch.await(TIMEOUT_OVERLAY_SEC, TimeUnit.SECONDS)) { 140b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka throw new RemoteException("Timed out waiting for the overlay"); 141b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 142b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } catch (InterruptedException e) { 143b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka throw new RemoteException("Error while adding overlay: " + e.toString()); 144b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 145b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka Log.d(TAG, "Overlay displayed, myUid=" + Process.myUid()); 146b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 147b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka 148b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka @Override 149b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka public void finishHost() { 150b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka removeOverlays(); 151b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka stopSelf(); 152b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka } 153b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka }; 154b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka} 155