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 android.jobscheduler.cts.jobtestapp;
18 
19 import static android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver.EXTRA_REQUEST_JOB_UID_STATE;
20 
21 import android.app.ActivityManager;
22 import android.app.job.JobParameters;
23 import android.app.job.JobService;
24 import android.content.Intent;
25 import android.os.Bundle;
26 import android.os.Process;
27 import android.util.Log;
28 
29 import java.io.BufferedReader;
30 import java.io.FileReader;
31 import java.io.IOException;
32 
33 public class TestJobService extends JobService {
34     private static final String TAG = TestJobService.class.getSimpleName();
35     private static final String PACKAGE_NAME = "android.jobscheduler.cts.jobtestapp";
36     public static final String ACTION_JOB_STARTED = PACKAGE_NAME + ".action.JOB_STARTED";
37     public static final String ACTION_JOB_STOPPED = PACKAGE_NAME + ".action.JOB_STOPPED";
38     public static final String JOB_PARAMS_EXTRA_KEY = PACKAGE_NAME + ".extra.JOB_PARAMETERS";
39     public static final String JOB_PROC_STATE_KEY = PACKAGE_NAME + ".extra.PROC_STATE";
40     public static final String JOB_CAPABILITIES_KEY = PACKAGE_NAME + ".extra.CAPABILITIES";
41     public static final String JOB_OOM_SCORE_ADJ_KEY = PACKAGE_NAME + ".extra.OOM_SCORE_ADJ";
42 
43     // TODO: Move ProcessList.INVALID_ADJ to an app-accessible location and mark it @TestApi
44     public static final int INVALID_ADJ = -10000; // ProcessList.INVALID_ADJ
45 
46     @Override
onStartJob(JobParameters params)47     public boolean onStartJob(JobParameters params) {
48         Log.i(TAG, "Test job executing: " + params.getJobId());
49         final Bundle transientExtras = params.getTransientExtras();
50         final Intent reportJobStartIntent = new Intent(ACTION_JOB_STARTED);
51         reportJobStartIntent.putExtra(JOB_PARAMS_EXTRA_KEY, params);
52         final boolean requestJobUidState = transientExtras != null
53                 ? transientExtras.getBoolean(EXTRA_REQUEST_JOB_UID_STATE) : false;
54         if (requestJobUidState) {
55             reportJobStartIntent.putExtra(EXTRA_REQUEST_JOB_UID_STATE, true);
56             reportJobStartIntent.putExtras(getJobUidStateExtras());
57         }
58         sendBroadcast(reportJobStartIntent);
59         return true;
60     }
61 
62     @Override
onStopJob(JobParameters params)63     public boolean onStopJob(JobParameters params) {
64         Log.i(TAG, "Test job stopped executing: " + params.getJobId());
65         final Intent reportJobStopIntent = new Intent(ACTION_JOB_STOPPED);
66         reportJobStopIntent.putExtra(JOB_PARAMS_EXTRA_KEY, params);
67         sendBroadcast(reportJobStopIntent);
68         return true;
69     }
70 
getJobUidStateExtras()71     private Bundle getJobUidStateExtras() {
72         final Bundle extras = new Bundle();
73         extras.putInt(JOB_PROC_STATE_KEY, getProcState());
74         extras.putInt(JOB_CAPABILITIES_KEY, getCapabilities());
75         extras.putInt(JOB_OOM_SCORE_ADJ_KEY, getOomScoreAdj());
76         return extras;
77     }
78 
getProcState()79     private int getProcState() {
80         final ActivityManager activityManager = getSystemService(ActivityManager.class);
81         return activityManager.getUidProcessState(Process.myUid());
82     }
83 
getCapabilities()84     private int getCapabilities() {
85         final ActivityManager activityManager = getSystemService(ActivityManager.class);
86         return activityManager.getUidProcessCapabilities(Process.myUid());
87     }
88 
getOomScoreAdj()89     private int getOomScoreAdj() {
90         try (BufferedReader reader = new BufferedReader(
91                 new FileReader("/proc/self/oom_score_adj"))) {
92             return Integer.parseInt(reader.readLine().trim());
93         } catch (IOException | NumberFormatException e) {
94             Log.e(TAG, "Error reading oom_score_adj", e);
95             return INVALID_ADJ;
96         }
97     }
98 }
99