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.storaged; 18 19 import android.app.Service; 20 import android.content.Intent; 21 import android.os.Handler; 22 import android.os.HandlerThread; 23 import android.os.IBinder; 24 import android.os.Looper; 25 import android.os.Message; 26 import android.os.Process; 27 import android.util.Log; 28 29 import java.io.BufferedReader; 30 import java.io.File; 31 import java.io.FileReader; 32 import java.io.FileWriter; 33 import java.io.IOException; 34 35 public class SimpleIOService extends Service { 36 private Looper mServiceLooper; 37 private ServiceHandler mServiceHandler; 38 39 private final class ServiceHandler extends Handler { 40 private String getCgroupCpuset() { 41 File cgroup = new File("/proc/self/cgroup"); 42 try (BufferedReader br = new BufferedReader(new FileReader(cgroup))) { 43 String line; 44 while ((line = br.readLine()) != null) { 45 String[] parts = line.split(":"); 46 if (parts.length >= 3 && parts[1].equals("cpuset")) { 47 return parts[2]; 48 } 49 } 50 } catch (IOException e) { 51 } 52 return null; 53 } 54 55 public ServiceHandler(Looper looper) { 56 super(looper); 57 58 // Spin for 20 seconds until we are not in the foreground. (Note 59 // that UsageStatsService considers "foreground" to be in the 60 // background - only top and persistent processes are reported as 61 // foreground for uid_io). 62 for (int i = 1; i <= 200; i++) { 63 String cpuset = getCgroupCpuset(); 64 if (cpuset == null || !cpuset.equals("/top")) { 65 break; 66 } 67 try { 68 Thread.sleep(100); 69 } catch (InterruptedException e) { 70 } 71 } 72 73 Log.i("SimpleIOService", "cgroup:" + getCgroupCpuset()); 74 } 75 76 @Override 77 public void handleMessage(Message msg) { 78 File testFile = new File(getFilesDir(), "StoragedTest_Temp_BG"); 79 try { 80 char data[] = new char[4096]; 81 FileWriter w = new FileWriter(testFile); 82 w.write(data); 83 w.flush(); 84 w.close(); 85 } catch (IOException e) { 86 throw new RuntimeException(e); 87 } finally { 88 // Stop the service using the startId, so that we don't stop 89 // the service in the middle of handling another job 90 stopSelf(msg.arg1); 91 } 92 } 93 } 94 95 @Override 96 public void onCreate() { 97 // Start up the thread running the service. Note that we create a 98 // separate thread because the service normally runs in the process's 99 // main thread, which we don't want to block. We also make it 100 // background priority so CPU-intensive work will not disrupt our UI. 101 HandlerThread thread = new HandlerThread("ServiceStartArguments", 102 Process.THREAD_PRIORITY_BACKGROUND); 103 thread.start(); 104 105 // Get the HandlerThread's Looper and use it for our Handler 106 mServiceLooper = thread.getLooper(); 107 mServiceHandler = new ServiceHandler(mServiceLooper); 108 } 109 110 @Override 111 public int onStartCommand(Intent intent, int flags, int startId) { 112 Message msg = mServiceHandler.obtainMessage(); 113 msg.arg1 = startId; 114 mServiceHandler.sendMessage(msg); 115 116 return START_NOT_STICKY; 117 } 118 119 @Override 120 public IBinder onBind(Intent intent) { 121 return null; 122 } 123 } 124