• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 android.jobscheduler.cts.shareduidtests;
17 
18 import android.annotation.TargetApi;
19 import android.app.Instrumentation;
20 import android.app.job.JobScheduler;
21 import android.content.ClipData;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.jobscheduler.MockJobService;
27 import android.jobscheduler.TriggerContentJobService;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.os.Process;
31 import android.os.SystemClock;
32 import android.test.InstrumentationTestCase;
33 import android.util.Log;
34 
35 import com.android.compatibility.common.util.SystemUtil;
36 
37 import java.io.IOException;
38 
39 /**
40  * Common functionality from which the other test case classes derive.
41  */
42 @TargetApi(21)
43 public abstract class ConstraintTest extends InstrumentationTestCase {
44     /** Force the scheduler to consider the device to be on stable charging. */
45     private static final Intent EXPEDITE_STABLE_CHARGING =
46             new Intent("com.android.server.task.controllers.BatteryController.ACTION_CHARGING_STABLE");
47 
48     /** Environment that notifies of JobScheduler callbacks. */
49     static MockJobService.TestEnvironment kTestEnvironment =
50             MockJobService.TestEnvironment.getTestEnvironment();
51     static TriggerContentJobService.TestEnvironment kTriggerTestEnvironment =
52             TriggerContentJobService.TestEnvironment.getTestEnvironment();
53     /** Handle for the service which receives the execution callbacks from the JobScheduler. */
54     static ComponentName kJobServiceComponent;
55     static ComponentName kTriggerContentServiceComponent;
56     JobScheduler mJobScheduler;
57 
58     Context mContext;
59 
60     static final String MY_PACKAGE = "android.jobscheduler.cts.shareduidtests";
61 
62     static final String JOBPERM_PACKAGE = "android.jobscheduler.cts.shareduid.jobperm";
63     static final String JOBPERM_AUTHORITY = "android.jobscheduler.cts.shareduid.jobperm.provider";
64     static final String JOBPERM_PERM = "android.jobscheduler.cts.jobperm.perm";
65 
66     Uri mFirstUri;
67     Bundle mFirstUriBundle;
68     Uri mSecondUri;
69     Bundle mSecondUriBundle;
70     ClipData mFirstClipData;
71     ClipData mSecondClipData;
72 
73     boolean mStorageStateChanged;
74 
75     @Override
injectInstrumentation(Instrumentation instrumentation)76     public void injectInstrumentation(Instrumentation instrumentation) {
77         super.injectInstrumentation(instrumentation);
78         mContext = instrumentation.getContext();
79         kJobServiceComponent = new ComponentName(getContext(), MockJobService.class);
80         kTriggerContentServiceComponent = new ComponentName(getContext(),
81                 TriggerContentJobService.class);
82         mJobScheduler = (JobScheduler) getContext().getSystemService(Context.JOB_SCHEDULER_SERVICE);
83         mFirstUri = Uri.parse("content://" + JOBPERM_AUTHORITY + "/protected/foo");
84         mFirstUriBundle = new Bundle();
85         mFirstUriBundle.putParcelable("uri", mFirstUri);
86         mSecondUri = Uri.parse("content://" + JOBPERM_AUTHORITY + "/protected/bar");
87         mSecondUriBundle = new Bundle();
88         mSecondUriBundle.putParcelable("uri", mSecondUri);
89         mFirstClipData = new ClipData("JobPerm1", new String[] { "application/*" },
90                 new ClipData.Item(mFirstUri));
91         mSecondClipData = new ClipData("JobPerm2", new String[] { "application/*" },
92                 new ClipData.Item(mSecondUri));
93         try {
94             SystemUtil.runShellCommand(getInstrumentation(), "cmd activity set-inactive "
95                     + mContext.getPackageName() + " false");
96         } catch (IOException e) {
97             Log.w("ConstraintTest", "Failed setting inactive false", e);
98         }
99     }
100 
getContext()101     public Context getContext() {
102         return mContext;
103     }
104 
105     @Override
setUp()106     public void setUp() throws Exception {
107         super.setUp();
108         kTestEnvironment.setUp();
109         kTriggerTestEnvironment.setUp();
110         mJobScheduler.cancelAll();
111     }
112 
113     @Override
tearDown()114     public void tearDown() throws Exception {
115         if (mStorageStateChanged) {
116             // Put storage service back in to normal operation.
117             SystemUtil.runShellCommand(getInstrumentation(), "cmd devicestoragemonitor reset");
118             mStorageStateChanged = false;
119         }
120     }
121 
122     /**
123      * The scheduler will usually only flush its queue of unexpired jobs when the device is
124      * considered to be on stable power - that is, plugged in for a period of 2 minutes.
125      * Rather than wait for this to happen, we cheat and send this broadcast instead.
126      */
sendExpediteStableChargingBroadcast()127     protected void sendExpediteStableChargingBroadcast() {
128         getContext().sendBroadcast(EXPEDITE_STABLE_CHARGING);
129     }
130 
assertHasUriPermission(Uri uri, int grantFlags)131     public void assertHasUriPermission(Uri uri, int grantFlags) {
132         if ((grantFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
133             assertEquals(PackageManager.PERMISSION_GRANTED,
134                     getContext().checkUriPermission(uri, Process.myPid(),
135                             Process.myUid(), Intent.FLAG_GRANT_READ_URI_PERMISSION));
136         }
137         if ((grantFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
138             assertEquals(PackageManager.PERMISSION_GRANTED,
139                     getContext().checkUriPermission(uri, Process.myPid(),
140                             Process.myUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
141         }
142     }
143 
waitPermissionRevoke(Uri uri, int access, long timeout)144     void waitPermissionRevoke(Uri uri, int access, long timeout) {
145         long startTime = SystemClock.elapsedRealtime();
146         while (getContext().checkUriPermission(uri, Process.myPid(), Process.myUid(), access)
147                 != PackageManager.PERMISSION_DENIED) {
148             try {
149                 Thread.sleep(50);
150             } catch (InterruptedException e) {
151             }
152             if ((SystemClock.elapsedRealtime()-startTime) >= timeout) {
153                 fail("Timed out waiting for permission revoke");
154             }
155         }
156     }
157 
158     // Note we are just using storage state as a way to control when the job gets executed.
setStorageState(boolean low)159     void setStorageState(boolean low) throws Exception {
160         mStorageStateChanged = true;
161         String res;
162         if (low) {
163             res = SystemUtil.runShellCommand(getInstrumentation(),
164                     "cmd devicestoragemonitor force-low -f");
165         } else {
166             res = SystemUtil.runShellCommand(getInstrumentation(),
167                     "cmd devicestoragemonitor force-not-low -f");
168         }
169         int seq = Integer.parseInt(res.trim());
170         long startTime = SystemClock.elapsedRealtime();
171 
172         // Wait for the storage update to be processed by job scheduler before proceeding.
173         int curSeq;
174         do {
175             curSeq = Integer.parseInt(SystemUtil.runShellCommand(getInstrumentation(),
176                     "cmd jobscheduler get-storage-seq").trim());
177             if (curSeq == seq) {
178                 return;
179             }
180         } while ((SystemClock.elapsedRealtime()-startTime) < 1000);
181 
182         fail("Timed out waiting for job scheduler: expected seq=" + seq + ", cur=" + curSeq);
183     }
184 
getJobState(int jobId)185     String getJobState(int jobId) throws Exception {
186         return SystemUtil.runShellCommand(getInstrumentation(),
187                 "cmd jobscheduler get-job-state --user cur "
188                         + kJobServiceComponent.getPackageName() + " " + jobId).trim();
189     }
190 
assertJobReady(int jobId)191     void assertJobReady(int jobId) throws Exception {
192         String state = getJobState(jobId);
193         assertTrue("Job unexpectedly not ready, in state: " + state, state.contains("ready"));
194     }
195 
assertJobWaiting(int jobId)196     void assertJobWaiting(int jobId) throws Exception {
197         String state = getJobState(jobId);
198         assertTrue("Job unexpectedly not waiting, in state: " + state, state.contains("waiting"));
199     }
200 
assertJobNotReady(int jobId)201     void assertJobNotReady(int jobId) throws Exception {
202         String state = getJobState(jobId);
203         assertTrue("Job unexpectedly ready, in state: " + state, !state.contains("ready"));
204     }
205 }
206