1 /* 2 * Copyright (C) 2022 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.intentresolver; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.StringRes; 22 import android.app.admin.DevicePolicyEventLogger; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.Context; 25 import android.os.UserHandle; 26 27 import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; 28 import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyState; 29 import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyStateProvider; 30 import com.android.intentresolver.AbstractMultiProfilePagerAdapter.MyUserIdProvider; 31 32 /** 33 * Empty state provider that does not allow cross profile sharing, it will return a blocker 34 * in case if the profile of the current tab is not the same as the profile of the calling app. 35 */ 36 public class NoCrossProfileEmptyStateProvider implements EmptyStateProvider { 37 38 private final UserHandle mPersonalProfileUserHandle; 39 private final EmptyState mNoWorkToPersonalEmptyState; 40 private final EmptyState mNoPersonalToWorkEmptyState; 41 private final CrossProfileIntentsChecker mCrossProfileIntentsChecker; 42 private final MyUserIdProvider mUserIdProvider; 43 NoCrossProfileEmptyStateProvider(UserHandle personalUserHandle, EmptyState noWorkToPersonalEmptyState, EmptyState noPersonalToWorkEmptyState, CrossProfileIntentsChecker crossProfileIntentsChecker, MyUserIdProvider myUserIdProvider)44 public NoCrossProfileEmptyStateProvider(UserHandle personalUserHandle, 45 EmptyState noWorkToPersonalEmptyState, 46 EmptyState noPersonalToWorkEmptyState, 47 CrossProfileIntentsChecker crossProfileIntentsChecker, 48 MyUserIdProvider myUserIdProvider) { 49 mPersonalProfileUserHandle = personalUserHandle; 50 mNoWorkToPersonalEmptyState = noWorkToPersonalEmptyState; 51 mNoPersonalToWorkEmptyState = noPersonalToWorkEmptyState; 52 mCrossProfileIntentsChecker = crossProfileIntentsChecker; 53 mUserIdProvider = myUserIdProvider; 54 } 55 56 @Nullable 57 @Override getEmptyState(ResolverListAdapter resolverListAdapter)58 public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { 59 boolean shouldShowBlocker = 60 mUserIdProvider.getMyUserId() != resolverListAdapter.getUserHandle().getIdentifier() 61 && !mCrossProfileIntentsChecker 62 .hasCrossProfileIntents(resolverListAdapter.getIntents(), 63 mUserIdProvider.getMyUserId(), 64 resolverListAdapter.getUserHandle().getIdentifier()); 65 66 if (!shouldShowBlocker) { 67 return null; 68 } 69 70 if (resolverListAdapter.getUserHandle().equals(mPersonalProfileUserHandle)) { 71 return mNoWorkToPersonalEmptyState; 72 } else { 73 return mNoPersonalToWorkEmptyState; 74 } 75 } 76 77 78 /** 79 * Empty state that gets strings from the device policy manager and tracks events into 80 * event logger of the device policy events. 81 */ 82 public static class DevicePolicyBlockerEmptyState implements EmptyState { 83 84 @NonNull 85 private final Context mContext; 86 private final String mDevicePolicyStringTitleId; 87 @StringRes 88 private final int mDefaultTitleResource; 89 private final String mDevicePolicyStringSubtitleId; 90 @StringRes 91 private final int mDefaultSubtitleResource; 92 private final int mEventId; 93 @NonNull 94 private final String mEventCategory; 95 DevicePolicyBlockerEmptyState(Context context, String devicePolicyStringTitleId, @StringRes int defaultTitleResource, String devicePolicyStringSubtitleId, @StringRes int defaultSubtitleResource, int devicePolicyEventId, String devicePolicyEventCategory)96 public DevicePolicyBlockerEmptyState(Context context, String devicePolicyStringTitleId, 97 @StringRes int defaultTitleResource, String devicePolicyStringSubtitleId, 98 @StringRes int defaultSubtitleResource, 99 int devicePolicyEventId, String devicePolicyEventCategory) { 100 mContext = context; 101 mDevicePolicyStringTitleId = devicePolicyStringTitleId; 102 mDefaultTitleResource = defaultTitleResource; 103 mDevicePolicyStringSubtitleId = devicePolicyStringSubtitleId; 104 mDefaultSubtitleResource = defaultSubtitleResource; 105 mEventId = devicePolicyEventId; 106 mEventCategory = devicePolicyEventCategory; 107 } 108 109 @Nullable 110 @Override getTitle()111 public String getTitle() { 112 return mContext.getSystemService(DevicePolicyManager.class).getResources().getString( 113 mDevicePolicyStringTitleId, 114 () -> mContext.getString(mDefaultTitleResource)); 115 } 116 117 @Nullable 118 @Override getSubtitle()119 public String getSubtitle() { 120 return mContext.getSystemService(DevicePolicyManager.class).getResources().getString( 121 mDevicePolicyStringSubtitleId, 122 () -> mContext.getString(mDefaultSubtitleResource)); 123 } 124 125 @Override onEmptyStateShown()126 public void onEmptyStateShown() { 127 DevicePolicyEventLogger.createEvent(mEventId) 128 .setStrings(mEventCategory) 129 .write(); 130 } 131 132 @Override shouldSkipDataRebuild()133 public boolean shouldSkipDataRebuild() { 134 return true; 135 } 136 } 137 } 138