1 /*
2  * Copyright (C) 2016 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.systemintents.cts;
18 
19 import static org.junit.Assert.assertTrue;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.content.res.Configuration;
26 import android.net.Uri;
27 import android.provider.Settings;
28 
29 import androidx.test.filters.MediumTest;
30 import androidx.test.platform.app.InstrumentationRegistry;
31 import androidx.test.runner.AndroidJUnit4;
32 
33 import com.google.common.truth.Expect;
34 
35 import org.junit.Before;
36 import org.junit.Rule;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 @MediumTest
41 @RunWith(AndroidJUnit4.class)
42 public class TestSystemIntents {
43     private static final int EXCLUDE_TV = 1 << 0;
44     private static final int EXCLUDE_WATCH = 1 << 1;
45     private static final int EXCLUDE_NON_TELEPHONY = 1 << 2;
46     private static final int EXCLUDE_NON_INSTALLABLE_IME = 1 << 3;
47 
48     private static class IntentEntry {
49         public int flags;
50         public Intent intent;
51 
IntentEntry(int f, Intent i)52         public IntentEntry(int f, Intent i) {
53             flags = f;
54             intent = i;
55         }
56     }
57 
58     @Rule public final Expect mExpect = Expect.create();
59 
60     private Context mContext;
61     private PackageManager mPackageManager;
62 
63     /*
64      * List of activity intents defined by the system.  Activities to handle each of these
65      * intents must all exist.
66      *
67      * They are Intents here rather than simply action strings so that the test can
68      * easily accommodate data URIs or similar for correct resolution.
69      *
70      * The flags associated with each intent indicate kinds of device on which the given
71      * UI intent is *not* applicable.
72      */
73     private final IntentEntry[] mTestIntents = {
74             /* Settings-namespace intent actions */
75             new IntentEntry(0, new Intent(Settings.ACTION_SETTINGS)),
76             new IntentEntry(0, new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)),
77             new IntentEntry(0, new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)),
78             new IntentEntry(0, new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
79                     .setData(Uri.parse("package:android.systemintents.cts"))),
80             new IntentEntry(0, new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS)
81                     .setData(Uri.parse("package:android.systemintents.cts"))),
82             new IntentEntry(0, new Intent(Settings.ACTION_HOME_SETTINGS)),
83             new IntentEntry(EXCLUDE_NON_TELEPHONY,
84                     new Intent(Settings.ACTION_APN_SETTINGS)),
85             new IntentEntry(EXCLUDE_TV|EXCLUDE_WATCH,
86                     new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)),
87             new IntentEntry(EXCLUDE_NON_INSTALLABLE_IME,
88                     new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
89     };
90 
91     @Before
setUp()92     public void setUp() throws Exception {
93         mContext = InstrumentationRegistry.getInstrumentation().getContext();
94         mPackageManager = mContext.getPackageManager();
95     }
96 
97     @Test
testSystemIntents()98     public void testSystemIntents() {
99         int productFlags = 0;
100 
101         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
102             productFlags |= EXCLUDE_TV;
103         }
104 
105         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
106             productFlags |= EXCLUDE_NON_TELEPHONY;
107         }
108 
109         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
110             productFlags |= EXCLUDE_NON_INSTALLABLE_IME;
111         }
112 
113         final Configuration config = mContext.getResources().getConfiguration();
114         if ((config.uiMode & Configuration.UI_MODE_TYPE_WATCH) != 0) {
115             productFlags |= EXCLUDE_WATCH;
116         }
117 
118         for (IntentEntry e : mTestIntents) {
119             if ((productFlags & e.flags) == 0) {
120                 final ResolveInfo ri = mPackageManager.resolveActivity(e.intent,
121                         PackageManager.MATCH_DEFAULT_ONLY);
122                 mExpect.withMessage("API intent %s not implemented by any activity", e.intent)
123                         .that(ri).isNotNull();
124             }
125         }
126     }
127 
128     @Test
testActionInputMethodSettings_resolvedBy_highPriorityComponent()129     public void testActionInputMethodSettings_resolvedBy_highPriorityComponent() {
130         final ResolveInfo resolveInfo = mPackageManager.resolveActivity(
131                 new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0);
132         final int actualPriority = resolveInfo.priority;
133         assertTrue(
134                 "ACTION_INPUT_METHOD_SETTINGS must be resolved by a component with priority > 0! "
135                         + "(Got priority " + actualPriority + " from " + resolveInfo + ")",
136                 actualPriority > 0);
137     }
138 }
139