Home | History | Annotate | Download | only in bstatstestapp
      1 /*
      2  * Copyright (C) 2017 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 package com.android.coretests.apps.bstatstestapp;
     17 
     18 import android.R;
     19 import android.app.Notification;
     20 import android.app.NotificationChannel;
     21 import android.app.NotificationManager;
     22 import android.app.Service;
     23 import android.content.Intent;
     24 import android.graphics.Color;
     25 import android.graphics.Point;
     26 import android.os.Handler;
     27 import android.os.IBinder;
     28 import android.os.Process;
     29 import android.os.RemoteException;
     30 import android.util.Log;
     31 import android.view.Gravity;
     32 import android.view.View;
     33 import android.view.ViewGroup;
     34 import android.view.WindowManager;
     35 
     36 import java.util.concurrent.CountDownLatch;
     37 import java.util.concurrent.TimeUnit;
     38 
     39 public class TestService extends Service {
     40     private static final String TAG = TestService.class.getSimpleName();
     41 
     42     private static final int FLAG_START_FOREGROUND = 1;
     43 
     44     private static final String NOTIFICATION_CHANNEL_ID = TAG;
     45     private static final int NOTIFICATION_ID = 42;
     46 
     47     private static final int TIMEOUT_OVERLAY_SEC = 2;
     48 
     49     private View mOverlay;
     50 
     51     @Override
     52     public void onCreate() {
     53         Log.d(TAG, "onCreate called. myUid=" + Process.myUid());
     54     }
     55 
     56     @Override
     57     public int onStartCommand(Intent intent, int flags, int startId) {
     58         Log.d(TAG, "onStartCommand called. myUid=" + Process.myUid());
     59         if (intent != null && (intent.getFlags() & FLAG_START_FOREGROUND) != 0) {
     60             startForeground();
     61         }
     62         notifyServiceLaunched(intent);
     63         return START_STICKY;
     64     }
     65 
     66     @Override
     67     public IBinder onBind(Intent intent) {
     68         Log.d(TAG, "onBind called. myUid=" + Process.myUid());
     69         return null;
     70     }
     71 
     72     @Override
     73     public void onDestroy() {
     74         Log.d(TAG, "onDestroy called. myUid=" + Process.myUid());
     75         removeOverlays();
     76     }
     77 
     78     private void notifyServiceLaunched(Intent intent) {
     79         Common.notifyLaunched(intent, mReceiver.asBinder(), TAG);
     80     }
     81 
     82     private void startForeground() {
     83         final NotificationManager noMan = getSystemService(NotificationManager.class);
     84         noMan.createNotificationChannel(new NotificationChannel(
     85                 NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID,
     86                 NotificationManager.IMPORTANCE_DEFAULT));
     87         Log.d(TAG, "Starting foreground. myUid=" + Process.myUid());
     88         startForeground(NOTIFICATION_ID,
     89                 new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
     90                         .setSmallIcon(R.drawable.ic_dialog_alert)
     91                         .build());
     92     }
     93 
     94     private void removeOverlays() {
     95         if (mOverlay != null) {
     96             final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
     97             wm.removeView(mOverlay);
     98             mOverlay = null;
     99         }
    100     }
    101 
    102     private BaseCmdReceiver mReceiver = new BaseCmdReceiver() {
    103         @Override
    104         public void doSomeWork(int durationMs) {
    105             Common.doSomeWork(durationMs);
    106         }
    107 
    108         @Override
    109         public void showApplicationOverlay() throws RemoteException {
    110             final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
    111             final Point size = new Point();
    112             wm.getDefaultDisplay().getSize(size);
    113 
    114             final WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
    115                     WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
    116                     WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    117                             | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
    118                             | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
    119             wmlp.width = size.x / 2;
    120             wmlp.height = size.y / 2;
    121             wmlp.gravity = Gravity.CENTER | Gravity.LEFT;
    122             wmlp.setTitle(TAG);
    123 
    124             final ViewGroup.LayoutParams vglp = new ViewGroup.LayoutParams(
    125                     ViewGroup.LayoutParams.MATCH_PARENT,
    126                     ViewGroup.LayoutParams.MATCH_PARENT);
    127 
    128             mOverlay = new View(TestService.this);
    129             mOverlay.setBackgroundColor(Color.GREEN);
    130             mOverlay.setLayoutParams(vglp);
    131 
    132             final CountDownLatch latch = new CountDownLatch(1);
    133             final Handler handler = new Handler(TestService.this.getMainLooper());
    134             handler.post(() -> {
    135                 wm.addView(mOverlay, wmlp);
    136                 latch.countDown();
    137             });
    138             try {
    139                 if (!latch.await(TIMEOUT_OVERLAY_SEC, TimeUnit.SECONDS)) {
    140                     throw new RemoteException("Timed out waiting for the overlay");
    141                 }
    142             } catch (InterruptedException e) {
    143                 throw new RemoteException("Error while adding overlay: " + e.toString());
    144             }
    145             Log.d(TAG, "Overlay displayed, myUid=" + Process.myUid());
    146         }
    147 
    148         @Override
    149         public void finishHost() {
    150             removeOverlays();
    151             stopSelf();
    152         }
    153     };
    154 }
    155