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.pm;
18 
19 import static android.content.pm.PackageManager.ONLY_IF_NO_MATCH_FOUND;
20 import static android.content.pm.PackageManager.SKIP_CURRENT_PROFILE;
21 import static android.speech.RecognizerIntent.ACTION_RECOGNIZE_SPEECH;
22 
23 import android.content.Intent;
24 import android.hardware.usb.UsbManager;
25 import android.provider.AlarmClock;
26 import android.provider.MediaStore;
27 
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.List;
31 
32 /**
33  * Utility Class for {@link DefaultCrossProfileIntentFilter}.
34  */
35 public class DefaultCrossProfileIntentFiltersUtils {
36 
DefaultCrossProfileIntentFiltersUtils()37     private DefaultCrossProfileIntentFiltersUtils() {
38     }
39 
40     // Intents from profile to parent user
41     /** Emergency call intent with mime type is always resolved by primary user. */
42     private static final DefaultCrossProfileIntentFilter
43             EMERGENCY_CALL_MIME =
44             new DefaultCrossProfileIntentFilter.Builder(
45                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
46                     SKIP_CURRENT_PROFILE,
47                     /* letsPersonalDataIntoProfile= */ false)
48                     .addAction(Intent.ACTION_CALL_EMERGENCY)
49                     .addAction(Intent.ACTION_CALL_PRIVILEGED)
50                     .addCategory(Intent.CATEGORY_DEFAULT)
51                     .addCategory(Intent.CATEGORY_BROWSABLE)
52                     .addDataType("vnd.android.cursor.item/phone")
53                     .addDataType("vnd.android.cursor.item/phone_v2")
54                     .addDataType("vnd.android.cursor.item/person")
55                     .addDataType("vnd.android.cursor.dir/calls")
56                     .addDataType("vnd.android.cursor.item/calls")
57                     .build();
58 
59     /** Emergency call intent with data schemes is always resolved by primary user. */
60     private static final DefaultCrossProfileIntentFilter
61             EMERGENCY_CALL_DATA =
62             new DefaultCrossProfileIntentFilter.Builder(
63                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
64                     SKIP_CURRENT_PROFILE,
65                     /* letsPersonalDataIntoProfile= */ false)
66                     .addAction(Intent.ACTION_CALL_EMERGENCY)
67                     .addAction(Intent.ACTION_CALL_PRIVILEGED)
68                     .addCategory(Intent.CATEGORY_DEFAULT)
69                     .addCategory(Intent.CATEGORY_BROWSABLE)
70                     .addDataScheme("tel")
71                     .addDataScheme("sip")
72                     .addDataScheme("voicemail")
73                     .build();
74 
75     /** Dial intent with mime type can be handled by either managed profile or its parent user. */
76     private static final DefaultCrossProfileIntentFilter DIAL_MIME =
77             new DefaultCrossProfileIntentFilter.Builder(
78                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
79                     ONLY_IF_NO_MATCH_FOUND,
80                     /* letsPersonalDataIntoProfile= */ false)
81                     .addAction(Intent.ACTION_DIAL)
82                     .addAction(Intent.ACTION_VIEW)
83                     .addCategory(Intent.CATEGORY_DEFAULT)
84                     .addCategory(Intent.CATEGORY_BROWSABLE)
85                     .addDataType("vnd.android.cursor.item/phone")
86                     .addDataType("vnd.android.cursor.item/phone_v2")
87                     .addDataType("vnd.android.cursor.item/person")
88                     .addDataType("vnd.android.cursor.dir/calls")
89                     .addDataType("vnd.android.cursor.item/calls")
90                     .build();
91 
92     /** Dial intent with mime type exclusively handled by managed profile. */
93     private static final DefaultCrossProfileIntentFilter DIAL_MIME_MANAGED_PROFILE =
94             new DefaultCrossProfileIntentFilter.Builder(
95                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
96                     SKIP_CURRENT_PROFILE,
97                     /* letsPersonalDataIntoProfile= */ false)
98                     .addAction(Intent.ACTION_DIAL)
99                     .addAction(Intent.ACTION_VIEW)
100                     .addCategory(Intent.CATEGORY_DEFAULT)
101                     .addCategory(Intent.CATEGORY_BROWSABLE)
102                     .addDataType("vnd.android.cursor.item/phone")
103                     .addDataType("vnd.android.cursor.item/phone_v2")
104                     .addDataType("vnd.android.cursor.item/person")
105                     .addDataType("vnd.android.cursor.dir/calls")
106                     .addDataType("vnd.android.cursor.item/calls")
107                     .build();
108 
109     /** Dial intent with data scheme can be handled by either managed profile or its parent user. */
110     private static final DefaultCrossProfileIntentFilter DIAL_DATA =
111             new DefaultCrossProfileIntentFilter.Builder(
112                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
113                     ONLY_IF_NO_MATCH_FOUND,
114                     /* letsPersonalDataIntoProfile= */ false)
115                     .addAction(Intent.ACTION_DIAL)
116                     .addAction(Intent.ACTION_VIEW)
117                     .addCategory(Intent.CATEGORY_DEFAULT)
118                     .addCategory(Intent.CATEGORY_BROWSABLE)
119                     .addDataScheme("tel")
120                     .addDataScheme("sip")
121                     .addDataScheme("voicemail")
122                     .build();
123 
124     /** Dial intent with data scheme exclusively handled by managed profile. */
125     private static final DefaultCrossProfileIntentFilter DIAL_DATA_MANAGED_PROFILE =
126             new DefaultCrossProfileIntentFilter.Builder(
127                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
128                     SKIP_CURRENT_PROFILE,
129                     /* letsPersonalDataIntoProfile= */ false)
130                     .addAction(Intent.ACTION_DIAL)
131                     .addAction(Intent.ACTION_VIEW)
132                     .addCategory(Intent.CATEGORY_DEFAULT)
133                     .addCategory(Intent.CATEGORY_BROWSABLE)
134                     .addDataScheme("tel")
135                     .addDataScheme("sip")
136                     .addDataScheme("voicemail")
137                     .build();
138 
139     /**
140      * Dial intent with no data scheme or type can be handled by either managed profile or its
141      * parent user.
142      */
143     private static final DefaultCrossProfileIntentFilter DIAL_RAW =
144             new DefaultCrossProfileIntentFilter.Builder(
145                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
146                     ONLY_IF_NO_MATCH_FOUND,
147                     /* letsPersonalDataIntoProfile= */ false)
148                     .addAction(Intent.ACTION_DIAL)
149                     .addCategory(Intent.CATEGORY_DEFAULT)
150                     .addCategory(Intent.CATEGORY_BROWSABLE)
151                     .build();
152 
153     /**
154      * Dial intent with no data scheme or type exclusively handled by managed profile.
155      */
156     private static final DefaultCrossProfileIntentFilter DIAL_RAW_MANAGED_PROFILE =
157             new DefaultCrossProfileIntentFilter.Builder(
158                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
159                     SKIP_CURRENT_PROFILE,
160                     /* letsPersonalDataIntoProfile= */ false)
161                     .addAction(Intent.ACTION_DIAL)
162                     .addCategory(Intent.CATEGORY_DEFAULT)
163                     .addCategory(Intent.CATEGORY_BROWSABLE)
164                     .build();
165 
166     /** Pressing the call button can be handled by either managed profile or its parent user. */
167     private static final DefaultCrossProfileIntentFilter CALL_BUTTON =
168             new DefaultCrossProfileIntentFilter.Builder(
169                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
170                     ONLY_IF_NO_MATCH_FOUND,
171                     /* letsPersonalDataIntoProfile= */ false)
172                     .addAction(Intent.ACTION_CALL_BUTTON)
173                     .addCategory(Intent.CATEGORY_DEFAULT)
174                     .build();
175 
176     /** SMS and MMS are exclusively handled by the primary user. */
177     private static final DefaultCrossProfileIntentFilter SMS_MMS =
178             new DefaultCrossProfileIntentFilter.Builder(
179                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
180                     SKIP_CURRENT_PROFILE,
181                     /* letsPersonalDataIntoProfile= */ false)
182                     .addAction(Intent.ACTION_VIEW)
183                     .addAction(Intent.ACTION_SENDTO)
184                     .addCategory(Intent.CATEGORY_DEFAULT)
185                     .addCategory(Intent.CATEGORY_BROWSABLE)
186                     .addDataScheme("sms")
187                     .addDataScheme("smsto")
188                     .addDataScheme("mms")
189                     .addDataScheme("mmsto")
190                     .build();
191 
192     /** SMS and MMS intent exclusively handled by the managed profile. */
193     private static final DefaultCrossProfileIntentFilter SMS_MMS_MANAGED_PROFILE =
194             new DefaultCrossProfileIntentFilter.Builder(
195                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
196                     SKIP_CURRENT_PROFILE,
197                     /* letsPersonalDataIntoProfile= */ false)
198                     .addAction(Intent.ACTION_VIEW)
199                     .addAction(Intent.ACTION_SENDTO)
200                     .addCategory(Intent.CATEGORY_DEFAULT)
201                     .addCategory(Intent.CATEGORY_BROWSABLE)
202                     .addDataScheme("sms")
203                     .addDataScheme("smsto")
204                     .addDataScheme("mms")
205                     .addDataScheme("mmsto")
206                     .build();
207 
208     /** Mobile network settings is always shown in the primary user. */
209     private static final DefaultCrossProfileIntentFilter
210             MOBILE_NETWORK_SETTINGS =
211             new DefaultCrossProfileIntentFilter.Builder(
212                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
213                     SKIP_CURRENT_PROFILE,
214                     /* letsPersonalDataIntoProfile= */ false)
215                     .addAction(android.provider.Settings.ACTION_DATA_ROAMING_SETTINGS)
216                     .addAction(android.provider.Settings.ACTION_NETWORK_OPERATOR_SETTINGS)
217                     .addCategory(Intent.CATEGORY_DEFAULT)
218                     .build();
219 
220     /** HOME intent is always resolved by the primary user. */
221     static final DefaultCrossProfileIntentFilter HOME =
222             new DefaultCrossProfileIntentFilter.Builder(
223                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
224                     SKIP_CURRENT_PROFILE,
225                     /* letsPersonalDataIntoProfile= */ false)
226                     .addAction(Intent.ACTION_MAIN)
227                     .addCategory(Intent.CATEGORY_DEFAULT)
228                     .addCategory(Intent.CATEGORY_HOME)
229                     .build();
230 
231     /** Get content can be forwarded to parent user. */
232     private static final DefaultCrossProfileIntentFilter GET_CONTENT =
233             new DefaultCrossProfileIntentFilter.Builder(
234                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
235                     /* flags= */0,
236                     /* letsPersonalDataIntoProfile= */ true)
237                     .addAction(Intent.ACTION_GET_CONTENT)
238                     .addCategory(Intent.CATEGORY_DEFAULT)
239                     .addCategory(Intent.CATEGORY_OPENABLE)
240                     .addDataType("*/*")
241                     .build();
242 
243     /** Pick images can be forwarded to parent user. */
244     private static final DefaultCrossProfileIntentFilter ACTION_PICK_IMAGES =
245             new DefaultCrossProfileIntentFilter.Builder(
246                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
247                     /* flags= */ 0,
248                     /* letsPersonalDataIntoProfile= */ true)
249                     .addAction(MediaStore.ACTION_PICK_IMAGES)
250                     .addCategory(Intent.CATEGORY_DEFAULT)
251                     .build();
252     /** Pick images can be forwarded to parent user. */
253     private static final DefaultCrossProfileIntentFilter ACTION_PICK_IMAGES_WITH_DATA_TYPES =
254             new DefaultCrossProfileIntentFilter.Builder(
255                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
256                     /* flags= */ 0,
257                     /* letsPersonalDataIntoProfile= */ true)
258                     .addAction(MediaStore.ACTION_PICK_IMAGES)
259                     .addCategory(Intent.CATEGORY_DEFAULT)
260                     .addDataType("image/*")
261                     .addDataType("video/*")
262                     .build();
263 
264     /** Open document intent can be forwarded to parent user. */
265     private static final DefaultCrossProfileIntentFilter OPEN_DOCUMENT =
266             new DefaultCrossProfileIntentFilter.Builder(
267                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
268                     /* flags= */0,
269                     /* letsPersonalDataIntoProfile= */ true)
270                     .addAction(Intent.ACTION_OPEN_DOCUMENT)
271                     .addCategory(Intent.CATEGORY_DEFAULT)
272                     .addCategory(Intent.CATEGORY_OPENABLE)
273                     .addDataType("*/*")
274                     .build();
275 
276     /** Pick for any data type can be forwarded to parent user. */
277     private static final DefaultCrossProfileIntentFilter ACTION_PICK_DATA =
278             new DefaultCrossProfileIntentFilter.Builder(
279                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
280                     /* flags= */0,
281                     /* letsPersonalDataIntoProfile= */ true)
282                     .addAction(Intent.ACTION_PICK)
283                     .addCategory(Intent.CATEGORY_DEFAULT)
284                     .addDataType("*/*")
285                     .build();
286 
287     /** Pick without data type can be forwarded to parent user. */
288     private static final DefaultCrossProfileIntentFilter ACTION_PICK_RAW =
289             new DefaultCrossProfileIntentFilter.Builder(
290                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
291                     /* flags= */0,
292                     /* letsPersonalDataIntoProfile= */ true)
293                     .addAction(Intent.ACTION_PICK)
294                     .addCategory(Intent.CATEGORY_DEFAULT)
295                     .build();
296 
297     /** Speech recognition can be performed by primary user. */
298     private static final DefaultCrossProfileIntentFilter RECOGNIZE_SPEECH =
299             new DefaultCrossProfileIntentFilter.Builder(
300                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
301                     /* flags= */ ONLY_IF_NO_MATCH_FOUND,
302                     /* letsPersonalDataIntoProfile= */ false)
303                     .addAction(ACTION_RECOGNIZE_SPEECH)
304                     .addCategory(Intent.CATEGORY_DEFAULT)
305                     .build();
306 
307     /** Media capture can be performed by primary user. */
308     private static final DefaultCrossProfileIntentFilter MEDIA_CAPTURE =
309             new DefaultCrossProfileIntentFilter.Builder(
310                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
311                     /* flags= */ ONLY_IF_NO_MATCH_FOUND,
312                     /* letsPersonalDataIntoProfile= */ true)
313                     .addAction(MediaStore.ACTION_IMAGE_CAPTURE)
314                     .addAction(MediaStore.ACTION_IMAGE_CAPTURE_SECURE)
315                     .addAction(MediaStore.ACTION_VIDEO_CAPTURE)
316                     .addAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION)
317                     .addAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
318                     .addAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
319                     .addAction(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
320                     .addCategory(Intent.CATEGORY_DEFAULT)
321                     .build();
322 
323     /** Alarm setting can be performed by primary user. */
324     private static final DefaultCrossProfileIntentFilter SET_ALARM =
325             new DefaultCrossProfileIntentFilter.Builder(
326                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
327                     /* flags= */0,
328                     /* letsPersonalDataIntoProfile= */ false)
329                     .addAction(AlarmClock.ACTION_SET_ALARM)
330                     .addAction(AlarmClock.ACTION_SHOW_ALARMS)
331                     .addAction(AlarmClock.ACTION_SET_TIMER)
332                     .addCategory(Intent.CATEGORY_DEFAULT)
333                     .build();
334 
335     // Intents from parent to profile user
336 
337     /** ACTION_SEND can be forwarded to the managed profile on user's choice. */
338     private static final DefaultCrossProfileIntentFilter ACTION_SEND =
339             new DefaultCrossProfileIntentFilter.Builder(
340                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
341                     /* flags= */0,
342                     /* letsPersonalDataIntoProfile= */ true)
343                     .addAction(Intent.ACTION_SEND)
344                     .addAction(Intent.ACTION_SEND_MULTIPLE)
345                     .addCategory(Intent.CATEGORY_DEFAULT)
346                     .addDataType("*/*")
347                     .build();
348 
349     /** USB devices attached can get forwarded to the profile. */
350     private static final DefaultCrossProfileIntentFilter
351             USB_DEVICE_ATTACHED =
352             new DefaultCrossProfileIntentFilter.Builder(
353                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
354                     /* flags= */0,
355                     /* letsPersonalDataIntoProfile= */ false)
356                     .addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
357                     .addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED)
358                     .addCategory(Intent.CATEGORY_DEFAULT)
359                     .build();
360 
getDefaultManagedProfileFilters()361     public static List<DefaultCrossProfileIntentFilter> getDefaultManagedProfileFilters() {
362         List<DefaultCrossProfileIntentFilter> filters =
363                 new ArrayList<DefaultCrossProfileIntentFilter>();
364         filters.addAll(Arrays.asList(
365                 EMERGENCY_CALL_MIME,
366                 EMERGENCY_CALL_DATA,
367                 CALL_BUTTON,
368                 SET_ALARM,
369                 MEDIA_CAPTURE,
370                 RECOGNIZE_SPEECH,
371                 ACTION_PICK_RAW,
372                 ACTION_PICK_DATA,
373                 ACTION_PICK_IMAGES,
374                 ACTION_PICK_IMAGES_WITH_DATA_TYPES,
375                 OPEN_DOCUMENT,
376                 GET_CONTENT,
377                 USB_DEVICE_ATTACHED,
378                 ACTION_SEND,
379                 HOME,
380                 MOBILE_NETWORK_SETTINGS));
381         filters.addAll(getDefaultCrossProfileTelephonyIntentFilters(false));
382         return filters;
383     }
384 
385     /** Call intent with tel scheme exclusively handled my managed profile.
386      * Note that work profile telephony relies on this intent filter to redirect intents to
387      * the IntentForwarderActivity. Work profile telephony error handling must be updated in
388      * the Telecomm package CallsManager if this filter is changed.
389      */
390     private static final DefaultCrossProfileIntentFilter CALL_MANAGED_PROFILE =
391             new DefaultCrossProfileIntentFilter.Builder(
392                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
393                     SKIP_CURRENT_PROFILE,
394                     /* letsPersonalDataIntoProfile= */ false)
395                     .addAction(Intent.ACTION_CALL)
396                     .addCategory(Intent.CATEGORY_DEFAULT)
397                     .addDataScheme("tel")
398                     .build();
399 
400     /**
401      * Returns default telephony related intent filters for managed profile.
402      */
403     public static List<DefaultCrossProfileIntentFilter>
getDefaultCrossProfileTelephonyIntentFilters(boolean telephonyOnlyInManagedProfile)404             getDefaultCrossProfileTelephonyIntentFilters(boolean telephonyOnlyInManagedProfile) {
405         if (telephonyOnlyInManagedProfile) {
406             return Arrays.asList(
407                     DIAL_DATA_MANAGED_PROFILE,
408                     DIAL_MIME_MANAGED_PROFILE,
409                     DIAL_RAW_MANAGED_PROFILE,
410                     CALL_MANAGED_PROFILE,
411                     SMS_MMS_MANAGED_PROFILE);
412         } else {
413             return Arrays.asList(
414                     DIAL_DATA,
415                     DIAL_MIME,
416                     DIAL_RAW,
417                     SMS_MMS);
418         }
419     }
420 
421     /**
422      * Clone profile's DefaultCrossProfileIntentFilter
423      */
424 
425     /*
426      Allowing media capture from clone to parent profile as clone profile would not have camera
427      */
428     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_MEDIA_CAPTURE =
429             new DefaultCrossProfileIntentFilter.Builder(
430                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
431                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
432                                             // and FLAG_ALLOW_CHAINED_RESOLUTION set
433                     /* letsPersonalDataIntoProfile= */ false)
434                     .addAction(MediaStore.ACTION_IMAGE_CAPTURE)
435                     .addAction(MediaStore.ACTION_IMAGE_CAPTURE_SECURE)
436                     .addAction(MediaStore.ACTION_VIDEO_CAPTURE)
437                     .addAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION)
438                     .addAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
439                     .addAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
440                     .addAction(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
441                     .addCategory(Intent.CATEGORY_DEFAULT)
442                     .build();
443 
444     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_PHOTOPICKER_SELECTION =
445             new DefaultCrossProfileIntentFilter.Builder(
446                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
447                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
448                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
449                     /* letsPersonalDataIntoProfile= */ false)
450                     .addAction(MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP)
451                     .addCategory(Intent.CATEGORY_DEFAULT)
452                     .build();
453 
454     /*
455      Allowing send action from clone to parent profile to share content from clone apps to parent
456      apps
457      */
458     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_SEND_ACTION =
459             new DefaultCrossProfileIntentFilter.Builder(
460                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
461                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
462                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
463                     /* letsPersonalDataIntoProfile= */ false)
464                     .addAction(Intent.ACTION_SEND)
465                     .addAction(Intent.ACTION_SEND_MULTIPLE)
466                     .addAction(Intent.ACTION_SENDTO)
467                     .addDataType("*/*")
468                     .build();
469 
470     /*
471      Allowing send action from parent to clone profile to share content from parent apps to clone
472      apps
473      */
474     private static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_SEND_ACTION =
475             new DefaultCrossProfileIntentFilter.Builder(
476                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
477                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
478                                             // and FLAG_ALLOW_CHAINED_RESOLUTION set
479                     /* letsPersonalDataIntoProfile= */ false)
480                     .addAction(Intent.ACTION_SEND)
481                     .addAction(Intent.ACTION_SEND_MULTIPLE)
482                     .addAction(Intent.ACTION_SENDTO)
483                     .addDataType("*/*")
484                     .build();
485 
486     /*
487      Allowing view action from clone to parent profile to open any app-links or web links
488      */
489     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_WEB_VIEW_ACTION =
490             new DefaultCrossProfileIntentFilter.Builder(
491                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
492                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
493                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
494                     /* letsPersonalDataIntoProfile= */ false)
495                     .addAction(Intent.ACTION_VIEW)
496                     .addDataScheme("https")
497                     .addDataScheme("http")
498                     .build();
499 
500     /*
501      Allowing view action from parent to clone profile to open any app-links or web links
502      */
503     private static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_WEB_VIEW_ACTION =
504             new DefaultCrossProfileIntentFilter.Builder(
505                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
506                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
507                                             // and FLAG_ALLOW_CHAINED_RESOLUTION set
508                     /* letsPersonalDataIntoProfile= */ false)
509                     .addAction(Intent.ACTION_VIEW)
510                     .addDataScheme("https")
511                     .addDataScheme("http")
512                     .build();
513 
514     /*
515      Allowing view action from clone to parent profile to any data type e.g. pdf, including custom
516      content providers.
517      */
518     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_VIEW_ACTION =
519             new DefaultCrossProfileIntentFilter.Builder(
520                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
521                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
522                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
523                     /* letsPersonalDataIntoProfile= */ false)
524                     .addAction(Intent.ACTION_VIEW)
525                     .addDataType("*/*")
526                     .build();
527 
528 
529     /*
530      Allowing pick,insert and edit action from clone to parent profile to open picker or contacts
531      insert/edit.
532      */
533     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_PICK_INSERT_ACTION =
534             new DefaultCrossProfileIntentFilter.Builder(
535                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
536                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
537                                             // and FLAG_ALLOW_CHAINED_RESOLUTION set
538                     /* letsPersonalDataIntoProfile= */ false)
539                     .addAction(Intent.ACTION_PICK)
540                     .addAction(Intent.ACTION_GET_CONTENT)
541                     .addAction(Intent.ACTION_EDIT)
542                     .addAction(Intent.ACTION_INSERT)
543                     .addAction(Intent.ACTION_INSERT_OR_EDIT)
544                     .addAction(Intent.ACTION_OPEN_DOCUMENT)
545                     .addDataType("*/*")
546                     .addCategory(Intent.CATEGORY_DEFAULT)
547                     .addCategory(Intent.CATEGORY_OPENABLE)
548                     .build();
549 
550     /*
551      Allowing pick,insert and edit action from parent to clone profile to open picker
552      */
553     private static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_PICK_INSERT_ACTION =
554             new DefaultCrossProfileIntentFilter.Builder(
555                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
556                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
557                                             // and FLAG_ALLOW_CHAINED_RESOLUTION set
558                     /* letsPersonalDataIntoProfile= */ false)
559                     .addAction(Intent.ACTION_PICK)
560                     .addAction(Intent.ACTION_GET_CONTENT)
561                     .addAction(Intent.ACTION_EDIT)
562                     .addAction(Intent.ACTION_INSERT)
563                     .addAction(Intent.ACTION_INSERT_OR_EDIT)
564                     .addAction(Intent.ACTION_OPEN_DOCUMENT)
565                     .addDataType("*/*")
566                     .addCategory(Intent.CATEGORY_DEFAULT)
567                     .addCategory(Intent.CATEGORY_OPENABLE)
568                     .build();
569 
570     private static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_DIAL_DATA =
571             new DefaultCrossProfileIntentFilter.Builder(
572                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
573                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
574                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
575                     /* letsPersonalDataIntoProfile= */ false)
576                     .addAction(Intent.ACTION_DIAL)
577                     .addAction(Intent.ACTION_VIEW)
578                     .addCategory(Intent.CATEGORY_DEFAULT)
579                     .addCategory(Intent.CATEGORY_BROWSABLE)
580                     .addDataScheme("tel")
581                     .addDataScheme("sip")
582                     .addDataScheme("voicemail")
583                     .build();
584 
585     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_DIAL_DATA =
586             new DefaultCrossProfileIntentFilter.Builder(
587                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
588                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
589                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
590                     /* letsPersonalDataIntoProfile= */ false)
591                     .addAction(Intent.ACTION_DIAL)
592                     .addAction(Intent.ACTION_VIEW)
593                     .addCategory(Intent.CATEGORY_DEFAULT)
594                     .addCategory(Intent.CATEGORY_BROWSABLE)
595                     .addDataScheme("tel")
596                     .addDataScheme("sip")
597                     .addDataScheme("voicemail")
598                     .build();
599 
600     private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_SMS_MMS =
601             new DefaultCrossProfileIntentFilter.Builder(
602                     DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
603                     /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
604                     // and FLAG_ALLOW_CHAINED_RESOLUTION set
605                     /* letsPersonalDataIntoProfile= */ false)
606                     .addAction(Intent.ACTION_VIEW)
607                     .addAction(Intent.ACTION_SENDTO)
608                     .addCategory(Intent.CATEGORY_DEFAULT)
609                     .addCategory(Intent.CATEGORY_BROWSABLE)
610                     .addDataScheme("sms")
611                     .addDataScheme("smsto")
612                     .addDataScheme("mms")
613                     .addDataScheme("mmsto")
614                     .build();
615 
getDefaultCloneProfileFilters()616     public static List<DefaultCrossProfileIntentFilter> getDefaultCloneProfileFilters() {
617         return Arrays.asList(
618                 PARENT_TO_CLONE_SEND_ACTION,
619                 PARENT_TO_CLONE_WEB_VIEW_ACTION,
620                 PARENT_TO_CLONE_PICK_INSERT_ACTION,
621                 PARENT_TO_CLONE_DIAL_DATA,
622                 CLONE_TO_PARENT_MEDIA_CAPTURE,
623                 CLONE_TO_PARENT_SEND_ACTION,
624                 CLONE_TO_PARENT_WEB_VIEW_ACTION,
625                 CLONE_TO_PARENT_VIEW_ACTION,
626                 CLONE_TO_PARENT_PICK_INSERT_ACTION,
627                 CLONE_TO_PARENT_DIAL_DATA,
628                 CLONE_TO_PARENT_SMS_MMS,
629                 CLONE_TO_PARENT_PHOTOPICKER_SELECTION
630         );
631     }
632 }
633