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 17 package com.android.server.cts.device.statsdatom; 18 19 import android.app.Notification; 20 import android.app.NotificationChannel; 21 import android.app.NotificationManager; 22 import android.app.Service; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.Build; 26 import android.os.Handler; 27 import android.os.HandlerThread; 28 import android.os.IBinder; 29 import android.os.Looper; 30 import android.os.Message; 31 import android.os.Process; 32 import android.util.Log; 33 34 import com.android.compatibility.common.util.ApiLevelUtil; 35 36 public class StatsdCtsForegroundService extends Service { 37 private static final String TAG = "SimpleForegroundService"; 38 private static final String NOTIFICATION_CHANNEL_ID = "Foreground Service"; 39 40 // TODO: pass this in from host side. 41 public static final int SLEEP_OF_FOREGROUND_SERVICE = 2_000; 42 43 private Looper mServiceLooper; 44 private ServiceHandler mServiceHandler; 45 private boolean mChannelCreated; 46 47 private final class ServiceHandler extends Handler { ServiceHandler(Looper looper)48 public ServiceHandler(Looper looper) { 49 super(looper); 50 } 51 52 @Override handleMessage(Message msg)53 public void handleMessage(Message msg) { 54 Log.i(TAG, "Handling message."); 55 // Sleep. 56 try { 57 Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE); 58 } catch (InterruptedException e) { 59 // Restore interrupt status. 60 Thread.currentThread().interrupt(); 61 } 62 Log.i(TAG, "Stopping service."); 63 // Stop the service using the startId, so that we don't stop 64 // the service in the middle of handling another job 65 stopSelf(msg.arg1); 66 } 67 } 68 69 @Override onCreate()70 public void onCreate() { 71 // Start up the thread running the service. Note that we create a 72 // separate thread because the service normally runs in the process's 73 // main thread, which we don't want to block. We also make it 74 // background priority so CPU-intensive work will not disrupt our UI. 75 HandlerThread thread = new HandlerThread("ServiceStartArguments", 76 Process.THREAD_PRIORITY_BACKGROUND); 77 thread.start(); 78 79 // Get the HandlerThread's Looper and use it for our Handler 80 mServiceLooper = thread.getLooper(); 81 mServiceHandler = new ServiceHandler(mServiceLooper); 82 83 if (ApiLevelUtil.isBefore(Build.VERSION_CODES.O_MR1)) { 84 return; 85 } 86 // OMR1 requires notification channel to be set 87 NotificationManager notificationManager = 88 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 89 NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, 90 NOTIFICATION_CHANNEL_ID, 91 NotificationManager.IMPORTANCE_HIGH); 92 notificationManager.createNotificationChannel(channel); 93 mChannelCreated = true; 94 } 95 96 @Override onStartCommand(Intent intent, int flags, int startId)97 public int onStartCommand(Intent intent, int flags, int startId) { 98 Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID) 99 .setContentTitle("CTS Foreground") 100 .setSmallIcon(android.R.drawable.ic_secure) 101 .build(); 102 Log.i(TAG, "Starting Foreground."); 103 startForeground(1, notification); 104 105 Message msg = mServiceHandler.obtainMessage(); 106 msg.arg1 = startId; 107 mServiceHandler.sendMessage(msg); 108 109 return START_NOT_STICKY; 110 } 111 112 @Override onBind(Intent intent)113 public IBinder onBind(Intent intent) { 114 return null; 115 } 116 117 @Override onDestroy()118 public void onDestroy () { 119 if (mChannelCreated) { 120 NotificationManager notificationManager = 121 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 122 notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); 123 } 124 } 125 } 126