| /* | |
| * Copyright (C) 2022 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package com.android.intentresolver; | |
| import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; | |
| import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; | |
| import android.annotation.NonNull; | |
| import android.annotation.Nullable; | |
| import android.app.admin.DevicePolicyEventLogger; | |
| import android.app.admin.DevicePolicyManager; | |
| import android.content.Context; | |
| import android.content.pm.ResolveInfo; | |
| import android.os.UserHandle; | |
| import android.stats.devicepolicy.nano.DevicePolicyEnums; | |
| import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyState; | |
| import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyStateProvider; | |
| import com.android.internal.R; | |
| import java.util.List; | |
| /** | |
| * Chooser/ResolverActivity empty state provider that returns empty state which is shown when | |
| * there are no apps available. | |
| */ | |
| public class NoAppsAvailableEmptyStateProvider implements EmptyStateProvider { | |
| @NonNull | |
| private final Context mContext; | |
| @Nullable | |
| private final UserHandle mWorkProfileUserHandle; | |
| @Nullable | |
| private final UserHandle mPersonalProfileUserHandle; | |
| @NonNull | |
| private final String mMetricsCategory; | |
| @NonNull | |
| private final UserHandle mTabOwnerUserHandleForLaunch; | |
| public NoAppsAvailableEmptyStateProvider(Context context, UserHandle workProfileUserHandle, | |
| UserHandle personalProfileUserHandle, String metricsCategory, | |
| UserHandle tabOwnerUserHandleForLaunch) { | |
| mContext = context; | |
| mWorkProfileUserHandle = workProfileUserHandle; | |
| mPersonalProfileUserHandle = personalProfileUserHandle; | |
| mMetricsCategory = metricsCategory; | |
| mTabOwnerUserHandleForLaunch = tabOwnerUserHandleForLaunch; | |
| } | |
| @Nullable | |
| @Override | |
| @SuppressWarnings("ReferenceEquality") | |
| public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { | |
| UserHandle listUserHandle = resolverListAdapter.getUserHandle(); | |
| if (mWorkProfileUserHandle != null | |
| && (mTabOwnerUserHandleForLaunch.equals(listUserHandle) | |
| || !hasAppsInOtherProfile(resolverListAdapter))) { | |
| String title; | |
| if (listUserHandle == mPersonalProfileUserHandle) { | |
| title = mContext.getSystemService( | |
| DevicePolicyManager.class).getResources().getString( | |
| RESOLVER_NO_PERSONAL_APPS, | |
| () -> mContext.getString(R.string.resolver_no_personal_apps_available)); | |
| } else { | |
| title = mContext.getSystemService( | |
| DevicePolicyManager.class).getResources().getString( | |
| RESOLVER_NO_WORK_APPS, | |
| () -> mContext.getString(R.string.resolver_no_work_apps_available)); | |
| } | |
| return new NoAppsAvailableEmptyState( | |
| title, mMetricsCategory, | |
| /* isPersonalProfile= */ listUserHandle == mPersonalProfileUserHandle | |
| ); | |
| } else if (mWorkProfileUserHandle == null) { | |
| // Return default empty state without tracking | |
| return new DefaultEmptyState(); | |
| } | |
| return null; | |
| } | |
| private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) { | |
| if (mWorkProfileUserHandle == null) { | |
| return false; | |
| } | |
| List<ResolvedComponentInfo> resolversForIntent = | |
| adapter.getResolversForUser(mTabOwnerUserHandleForLaunch); | |
| for (ResolvedComponentInfo info : resolversForIntent) { | |
| ResolveInfo resolveInfo = info.getResolveInfoAt(0); | |
| if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| public static class DefaultEmptyState implements EmptyState { | |
| @Override | |
| public boolean useDefaultEmptyView() { | |
| return true; | |
| } | |
| } | |
| public static class NoAppsAvailableEmptyState implements EmptyState { | |
| @NonNull | |
| private String mTitle; | |
| @NonNull | |
| private String mMetricsCategory; | |
| private boolean mIsPersonalProfile; | |
| public NoAppsAvailableEmptyState(String title, String metricsCategory, | |
| boolean isPersonalProfile) { | |
| mTitle = title; | |
| mMetricsCategory = metricsCategory; | |
| mIsPersonalProfile = isPersonalProfile; | |
| } | |
| @Nullable | |
| @Override | |
| public String getTitle() { | |
| return mTitle; | |
| } | |
| @Override | |
| public void onEmptyStateShown() { | |
| DevicePolicyEventLogger.createEvent( | |
| DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED) | |
| .setStrings(mMetricsCategory) | |
| .setBoolean(/*isPersonalProfile*/ mIsPersonalProfile) | |
| .write(); | |
| } | |
| } | |
| } |