• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.wm;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.app.ActivityOptions;
23 import android.app.TaskInfo;
24 import android.content.Intent;
25 import android.content.pm.ActivityInfo;
26 import android.content.pm.ResolveInfo;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 
31 /**
32  * Callback to intercept activity starts and possibly block/redirect them. The callback methods will
33  * be called with the WindowManagerGlobalLock held.
34  */
35 public abstract class ActivityInterceptorCallback {
36     /**
37      * Intercept the launch intent based on various signals. If an interception happened, returns
38      * a new/existing non-null {@link ActivityInterceptResult} which may redirect to another
39      * activity or with new {@link ActivityOptions}.
40      *
41      * @return null if no interception occurred, or a non-null result which replaces the existing
42      * intent and activity options.
43      */
intercept(ActivityInterceptorInfo info)44     public abstract @Nullable ActivityInterceptResult intercept(ActivityInterceptorInfo info);
45 
46     /**
47      * Called when an activity is successfully launched. The intent included in the
48      * ActivityInterceptorInfo may have changed from the one sent in
49      * {@link #intercept(ActivityInterceptorInfo)}, due to the return from
50      * {@link #intercept(ActivityInterceptorInfo)}.
51      */
onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo, ActivityInterceptorInfo info)52     public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo,
53             ActivityInterceptorInfo info) {
54     }
55 
56     /**
57      * The unique id of each interceptor which determines the order it will execute in.
58      */
59     @IntDef(suffix = { "_ORDERED_ID" }, value = {
60             FIRST_ORDERED_ID,
61             PERMISSION_POLICY_ORDERED_ID,
62             VIRTUAL_DEVICE_SERVICE_ORDERED_ID,
63             DREAM_MANAGER_ORDERED_ID,
64             LAST_ORDERED_ID // Update this when adding new ids
65     })
66     @Retention(RetentionPolicy.SOURCE)
67     public @interface OrderedId {}
68 
69     /**
70      * The first id, used by the framework to determine the valid range of ids.
71      */
72     static final int FIRST_ORDERED_ID = 0;
73 
74     /**
75      * The identifier for {@link com.android.server.policy.PermissionPolicyService} interceptor
76      */
77     public static final int PERMISSION_POLICY_ORDERED_ID = 1;
78 
79     /**
80      * The identifier for {@link com.android.server.companion.virtual.VirtualDeviceManagerService}
81      * interceptor.
82      */
83     public static final int VIRTUAL_DEVICE_SERVICE_ORDERED_ID = 3;
84 
85     /**
86      * The identifier for {@link com.android.server.dreams.DreamManagerService} interceptor.
87      */
88     public static final int DREAM_MANAGER_ORDERED_ID = 4;
89 
90     /**
91      * The final id, used by the framework to determine the valid range of ids. Update this when
92      * adding new ids.
93      */
94     static final int LAST_ORDERED_ID = DREAM_MANAGER_ORDERED_ID;
95 
96     /**
97      * Data class for storing the various arguments needed for activity interception.
98      */
99     public static final class ActivityInterceptorInfo {
100         public final int realCallingUid;
101         public final int realCallingPid;
102         public final int userId;
103         public final String callingPackage;
104         public final String callingFeatureId;
105         public final Intent intent;
106         public final ResolveInfo rInfo;
107         public final ActivityInfo aInfo;
108         public final String resolvedType;
109         public final int callingPid;
110         public final int callingUid;
111         public final ActivityOptions checkedOptions;
112         public final @Nullable Runnable clearOptionsAnimation;
113 
ActivityInterceptorInfo(int realCallingUid, int realCallingPid, int userId, String callingPackage, String callingFeatureId, Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, int callingPid, int callingUid, ActivityOptions checkedOptions, @Nullable Runnable clearOptionsAnimation)114         public ActivityInterceptorInfo(int realCallingUid, int realCallingPid, int userId,
115                 String callingPackage, String callingFeatureId, Intent intent,
116                 ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, int callingPid,
117                 int callingUid, ActivityOptions checkedOptions,
118                 @Nullable Runnable clearOptionsAnimation) {
119             this.realCallingUid = realCallingUid;
120             this.realCallingPid = realCallingPid;
121             this.userId = userId;
122             this.callingPackage = callingPackage;
123             this.callingFeatureId = callingFeatureId;
124             this.intent = intent;
125             this.rInfo = rInfo;
126             this.aInfo = aInfo;
127             this.resolvedType = resolvedType;
128             this.callingPid = callingPid;
129             this.callingUid = callingUid;
130             this.checkedOptions = checkedOptions;
131             this.clearOptionsAnimation = clearOptionsAnimation;
132         }
133     }
134 
135     /**
136      * Data class for storing the intercept result.
137      */
138     public static final class ActivityInterceptResult {
139         @NonNull public final Intent intent;
140         @NonNull public final ActivityOptions activityOptions;
141 
ActivityInterceptResult( @onNull Intent intent, @NonNull ActivityOptions activityOptions)142         public ActivityInterceptResult(
143                 @NonNull Intent intent,
144                 @NonNull ActivityOptions activityOptions) {
145             this.intent = intent;
146             this.activityOptions = activityOptions;
147         }
148     }
149 }
150