Loading Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ java_defaults { "apache-commons-compress", "com.google.android.material_material", "guava", "modules-utils-build_system", ], libs: [ Loading Loading @@ -136,6 +137,7 @@ android_library { static_libs: [ "androidx.appcompat_appcompat", "com.google.android.material_material", "modules-utils-build_system", ], resource_dirs: [ Loading res/layout/item_photo_grid.xml +1 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,7 @@ android:pointerIcon="hand"> <ImageView android:id="@+id/icon_id" android:layout_height="@dimen/briefcase_icon_size_photo" android:layout_width="@dimen/briefcase_icon_size_photo" android:src="@drawable/ic_briefcase_white" Loading src/com/android/documentsui/DevicePolicyResources.java 0 → 100644 +194 −0 Original line number Diff line number Diff line /* * 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.documentsui; import android.app.admin.DevicePolicyManager; /** * Class containing the required identifiers to update device management resources. * * <p>See {@link DevicePolicyManager#getDrawable} and {@link DevicePolicyManager#getString}. */ public class DevicePolicyResources { /** * Class containing the identifiers used to update device management-related system strings. */ public static final class Strings { private static final String PREFIX = "DocumentsUi."; /** * An ID for any string that can't be updated. */ public static final String UNDEFINED = "UNDEFINED"; /** * Title for error message shown when work profile is turned off. */ public static final String WORK_PROFILE_OFF_ERROR_TITLE = PREFIX + "WORK_PROFILE_OFF_ERROR_TITLE"; /** * Button text shown when work profile is turned off. */ public static final String WORK_PROFILE_OFF_ENABLE_BUTTON = PREFIX + "WORK_PROFILE_OFF_ENABLE_BUTTON"; /** * Title for error message shown when a user's IT admin does not allow the user to * select work files from a personal app. */ public static final String CANT_SELECT_WORK_FILES_TITLE = PREFIX + "CANT_SELECT_WORK_FILES_TITLE"; /** * Message shown when a user's IT admin does not allow the user to select work files * from a personal app. */ public static final String CANT_SELECT_WORK_FILES_MESSAGE = PREFIX + "CANT_SELECT_WORK_FILES_MESSAGE"; /** * Title for error message shown when a user's IT admin does not allow the user to * select personal files from a work app. */ public static final String CANT_SELECT_PERSONAL_FILES_TITLE = PREFIX + "CANT_SELECT_PERSONAL_FILES_TITLE"; /** * Message shown when a user's IT admin does not allow the user to select personal files * from a work app. */ public static final String CANT_SELECT_PERSONAL_FILES_MESSAGE = PREFIX + "CANT_SELECT_PERSONAL_FILES_MESSAGE"; /** * Title for error message shown when a user's IT admin does not allow the user to save * files from their personal profile to their work profile. */ public static final String CANT_SAVE_TO_WORK_TITLE = PREFIX + "CANT_SAVE_TO_WORK_TITLE"; /** * Message shown when a user's IT admin does not allow the user to save files from their * personal profile to their work profile. */ public static final String CANT_SAVE_TO_WORK_MESSAGE = PREFIX + "CANT_SAVE_TO_WORK_MESSAGE"; /** * Title for error message shown when a user's IT admin does not allow the user to save * files from their work profile to their personal profile. */ public static final String CANT_SAVE_TO_PERSONAL_TITLE = PREFIX + "CANT_SAVE_TO_PERSONAL_TITLE"; /** * Message shown when a user's IT admin does not allow the user to save files from their * work profile to their personal profile. */ public static final String CANT_SAVE_TO_PERSONAL_MESSAGE = PREFIX + "CANT_SAVE_TO_PERSONAL_MESSAGE"; /** * Title for error message shown when a user tries to do something on their work * device, but that action isn't allowed by their IT admin. */ public static final String CROSS_PROFILE_NOT_ALLOWED_TITLE = PREFIX + "CROSS_PROFILE_NOT_ALLOWED_TITLE"; /** * Message shown when a user tries to do something on their work device, but that action * isn't allowed by their IT admin. */ public static final String CROSS_PROFILE_NOT_ALLOWED_MESSAGE = PREFIX + "CROSS_PROFILE_NOT_ALLOWED_MESSAGE"; /** * Content description text that's spoken by a screen reader for previewing a work file * before opening it. Accepts file name as a param. */ public static final String PREVIEW_WORK_FILE_ACCESSIBILITY = PREFIX + "PREVIEW_WORK_FILE_ACCESSIBILITY"; /** * Label for tab and sidebar to indicate personal content. */ public static final String PERSONAL_TAB = PREFIX + "PERSONAL_TAB"; /** * Label for tab and sidebar tab to indicate work content */ public static final String WORK_TAB = PREFIX + "WORK_TAB"; } /** * Class containing the identifiers used to update device management-related system drawable. */ public static final class Drawables { /** * Specifically used to badge work profile app icons. */ public static final String WORK_PROFILE_ICON_BADGE = "WORK_PROFILE_ICON_BADGE"; /** * General purpose work profile icon (i.e. generic icon badging). For badging app icons * specifically, see {@link #WORK_PROFILE_ICON_BADGE}. */ public static final String WORK_PROFILE_ICON = "WORK_PROFILE_ICON"; /** * General purpose icon representing the work profile off state. */ public static final String WORK_PROFILE_OFF_ICON = "WORK_PROFILE_OFF_ICON"; /** * General purpose icon for the work profile user avatar. */ public static final String WORK_PROFILE_USER_ICON = "WORK_PROFILE_USER_ICON"; /** * Class containing the style identifiers used to update device management-related system * drawable. */ public static final class Style { /** * A style identifier indicating that the updatable drawable should use the default * style. */ public static final String DEFAULT = "DEFAULT"; /** * A style identifier indicating that the updatable drawable has a solid color fill. */ public static final String SOLID_COLORED = "SOLID_COLORED"; /** * A style identifier indicating that the updatable drawable has a solid non-colored * fill. */ public static final String SOLID_NOT_COLORED = "SOLID_NOT_COLORED"; /** * A style identifier indicating that the updatable drawable is an outline. */ public static final String OUTLINE = "OUTLINE"; } } } src/com/android/documentsui/ProfileTabs.java +30 −4 Original line number Diff line number Diff line Loading @@ -18,14 +18,21 @@ package com.android.documentsui; import static androidx.core.util.Preconditions.checkNotNull; import static com.android.documentsui.DevicePolicyResources.Strings.PERSONAL_TAB; import static com.android.documentsui.DevicePolicyResources.Strings.WORK_TAB; import android.app.admin.DevicePolicyManager; import android.os.Build; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.State; import com.android.documentsui.base.UserId; import com.android.modules.utils.build.SdkLevel; import com.google.android.material.tabs.TabLayout; import com.google.common.base.Objects; Loading Loading @@ -112,14 +119,33 @@ public class ProfileTabs implements ProfileTabsAddons { mTabs.removeAllTabs(); if (mUserIds.size() > 1) { // set setSelected to false otherwise it will trigger callback. mTabs.addTab(createTab(R.string.personal_tab, mTabs.addTab(createTab( getEnterpriseString(PERSONAL_TAB, R.string.personal_tab), mUserIdManager.getSystemUser()), /* setSelected= */false); mTabs.addTab(createTab(R.string.work_tab, mTabs.addTab(createTab( getEnterpriseString(WORK_TAB, R.string.work_tab), mUserIdManager.getManagedUser()), /* setSelected= */false); } } } private String getEnterpriseString(String updatableStringId, int defaultStringId) { if (SdkLevel.isAtLeastT()) { return getUpdatableEnterpriseString(updatableStringId, defaultStringId); } else { return mTabsContainer.getContext().getString(defaultStringId); } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) private String getUpdatableEnterpriseString(String updatableStringId, int defaultStringId) { DevicePolicyManager dpm = mTabsContainer.getContext().getSystemService( DevicePolicyManager.class); return dpm.getResources().getString( updatableStringId, () -> mTabsContainer.getContext().getString(defaultStringId)); } /** * Returns the user represented by the selected tab. If there is no tab, return the * current user. Loading @@ -145,8 +171,8 @@ public class ProfileTabs implements ProfileTabsAddons { && mState.stack.getRoot() != null && mState.stack.getRoot().supportsCrossProfile(); } private TabLayout.Tab createTab(int resId, UserId userId) { return mTabs.newTab().setText(resId).setTag(userId); private TabLayout.Tab createTab(String text, UserId userId) { return mTabs.newTab().setText(text).setTag(userId); } @Override Loading src/com/android/documentsui/dirlist/DocumentHolder.java +31 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,13 @@ package com.android.documentsui.dirlist; import static com.android.documentsui.DevicePolicyResources.Strings.PREVIEW_WORK_FILE_ACCESSIBILITY; import static com.android.documentsui.DevicePolicyResources.Strings.UNDEFINED; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.database.Cursor; import android.os.Build; import android.os.Bundle; import android.view.KeyEvent; import android.view.LayoutInflater; Loading @@ -27,11 +32,14 @@ import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.widget.ImageView; import androidx.annotation.RequiresApi; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.R; import com.android.documentsui.base.Shared; import com.android.documentsui.base.State; import com.android.modules.utils.build.SdkLevel; import java.util.function.Function; Loading Loading @@ -171,6 +179,29 @@ public abstract class DocumentHolder return view.animate().setDuration(Shared.CHECK_ANIMATION_DURATION).alpha(alpha); } protected String getPreviewIconContentDescription(boolean isWorkProfile, String fileName) { if (SdkLevel.isAtLeastT()) { return getUpdatablePreviewIconContentDescription(isWorkProfile, fileName); } else { return itemView.getResources().getString( isWorkProfile ? R.string.preview_work_file : R.string.preview_file, fileName); } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) private String getUpdatablePreviewIconContentDescription( boolean isWorkProfile, String fileName) { DevicePolicyManager dpm = itemView.getContext().getSystemService( DevicePolicyManager.class); String updatableStringId = isWorkProfile ? PREVIEW_WORK_FILE_ACCESSIBILITY : UNDEFINED; int defaultStringId = isWorkProfile ? R.string.preview_work_file : R.string.preview_file; return dpm.getResources().getString( updatableStringId, () -> itemView.getResources().getString(defaultStringId, fileName), /* formatArgs= */ fileName); } protected static class PreviewAccessibilityDelegate extends View.AccessibilityDelegate { private Function<View, Boolean> mCallback; Loading Loading
Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ java_defaults { "apache-commons-compress", "com.google.android.material_material", "guava", "modules-utils-build_system", ], libs: [ Loading Loading @@ -136,6 +137,7 @@ android_library { static_libs: [ "androidx.appcompat_appcompat", "com.google.android.material_material", "modules-utils-build_system", ], resource_dirs: [ Loading
res/layout/item_photo_grid.xml +1 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,7 @@ android:pointerIcon="hand"> <ImageView android:id="@+id/icon_id" android:layout_height="@dimen/briefcase_icon_size_photo" android:layout_width="@dimen/briefcase_icon_size_photo" android:src="@drawable/ic_briefcase_white" Loading
src/com/android/documentsui/DevicePolicyResources.java 0 → 100644 +194 −0 Original line number Diff line number Diff line /* * 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.documentsui; import android.app.admin.DevicePolicyManager; /** * Class containing the required identifiers to update device management resources. * * <p>See {@link DevicePolicyManager#getDrawable} and {@link DevicePolicyManager#getString}. */ public class DevicePolicyResources { /** * Class containing the identifiers used to update device management-related system strings. */ public static final class Strings { private static final String PREFIX = "DocumentsUi."; /** * An ID for any string that can't be updated. */ public static final String UNDEFINED = "UNDEFINED"; /** * Title for error message shown when work profile is turned off. */ public static final String WORK_PROFILE_OFF_ERROR_TITLE = PREFIX + "WORK_PROFILE_OFF_ERROR_TITLE"; /** * Button text shown when work profile is turned off. */ public static final String WORK_PROFILE_OFF_ENABLE_BUTTON = PREFIX + "WORK_PROFILE_OFF_ENABLE_BUTTON"; /** * Title for error message shown when a user's IT admin does not allow the user to * select work files from a personal app. */ public static final String CANT_SELECT_WORK_FILES_TITLE = PREFIX + "CANT_SELECT_WORK_FILES_TITLE"; /** * Message shown when a user's IT admin does not allow the user to select work files * from a personal app. */ public static final String CANT_SELECT_WORK_FILES_MESSAGE = PREFIX + "CANT_SELECT_WORK_FILES_MESSAGE"; /** * Title for error message shown when a user's IT admin does not allow the user to * select personal files from a work app. */ public static final String CANT_SELECT_PERSONAL_FILES_TITLE = PREFIX + "CANT_SELECT_PERSONAL_FILES_TITLE"; /** * Message shown when a user's IT admin does not allow the user to select personal files * from a work app. */ public static final String CANT_SELECT_PERSONAL_FILES_MESSAGE = PREFIX + "CANT_SELECT_PERSONAL_FILES_MESSAGE"; /** * Title for error message shown when a user's IT admin does not allow the user to save * files from their personal profile to their work profile. */ public static final String CANT_SAVE_TO_WORK_TITLE = PREFIX + "CANT_SAVE_TO_WORK_TITLE"; /** * Message shown when a user's IT admin does not allow the user to save files from their * personal profile to their work profile. */ public static final String CANT_SAVE_TO_WORK_MESSAGE = PREFIX + "CANT_SAVE_TO_WORK_MESSAGE"; /** * Title for error message shown when a user's IT admin does not allow the user to save * files from their work profile to their personal profile. */ public static final String CANT_SAVE_TO_PERSONAL_TITLE = PREFIX + "CANT_SAVE_TO_PERSONAL_TITLE"; /** * Message shown when a user's IT admin does not allow the user to save files from their * work profile to their personal profile. */ public static final String CANT_SAVE_TO_PERSONAL_MESSAGE = PREFIX + "CANT_SAVE_TO_PERSONAL_MESSAGE"; /** * Title for error message shown when a user tries to do something on their work * device, but that action isn't allowed by their IT admin. */ public static final String CROSS_PROFILE_NOT_ALLOWED_TITLE = PREFIX + "CROSS_PROFILE_NOT_ALLOWED_TITLE"; /** * Message shown when a user tries to do something on their work device, but that action * isn't allowed by their IT admin. */ public static final String CROSS_PROFILE_NOT_ALLOWED_MESSAGE = PREFIX + "CROSS_PROFILE_NOT_ALLOWED_MESSAGE"; /** * Content description text that's spoken by a screen reader for previewing a work file * before opening it. Accepts file name as a param. */ public static final String PREVIEW_WORK_FILE_ACCESSIBILITY = PREFIX + "PREVIEW_WORK_FILE_ACCESSIBILITY"; /** * Label for tab and sidebar to indicate personal content. */ public static final String PERSONAL_TAB = PREFIX + "PERSONAL_TAB"; /** * Label for tab and sidebar tab to indicate work content */ public static final String WORK_TAB = PREFIX + "WORK_TAB"; } /** * Class containing the identifiers used to update device management-related system drawable. */ public static final class Drawables { /** * Specifically used to badge work profile app icons. */ public static final String WORK_PROFILE_ICON_BADGE = "WORK_PROFILE_ICON_BADGE"; /** * General purpose work profile icon (i.e. generic icon badging). For badging app icons * specifically, see {@link #WORK_PROFILE_ICON_BADGE}. */ public static final String WORK_PROFILE_ICON = "WORK_PROFILE_ICON"; /** * General purpose icon representing the work profile off state. */ public static final String WORK_PROFILE_OFF_ICON = "WORK_PROFILE_OFF_ICON"; /** * General purpose icon for the work profile user avatar. */ public static final String WORK_PROFILE_USER_ICON = "WORK_PROFILE_USER_ICON"; /** * Class containing the style identifiers used to update device management-related system * drawable. */ public static final class Style { /** * A style identifier indicating that the updatable drawable should use the default * style. */ public static final String DEFAULT = "DEFAULT"; /** * A style identifier indicating that the updatable drawable has a solid color fill. */ public static final String SOLID_COLORED = "SOLID_COLORED"; /** * A style identifier indicating that the updatable drawable has a solid non-colored * fill. */ public static final String SOLID_NOT_COLORED = "SOLID_NOT_COLORED"; /** * A style identifier indicating that the updatable drawable is an outline. */ public static final String OUTLINE = "OUTLINE"; } } }
src/com/android/documentsui/ProfileTabs.java +30 −4 Original line number Diff line number Diff line Loading @@ -18,14 +18,21 @@ package com.android.documentsui; import static androidx.core.util.Preconditions.checkNotNull; import static com.android.documentsui.DevicePolicyResources.Strings.PERSONAL_TAB; import static com.android.documentsui.DevicePolicyResources.Strings.WORK_TAB; import android.app.admin.DevicePolicyManager; import android.os.Build; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.State; import com.android.documentsui.base.UserId; import com.android.modules.utils.build.SdkLevel; import com.google.android.material.tabs.TabLayout; import com.google.common.base.Objects; Loading Loading @@ -112,14 +119,33 @@ public class ProfileTabs implements ProfileTabsAddons { mTabs.removeAllTabs(); if (mUserIds.size() > 1) { // set setSelected to false otherwise it will trigger callback. mTabs.addTab(createTab(R.string.personal_tab, mTabs.addTab(createTab( getEnterpriseString(PERSONAL_TAB, R.string.personal_tab), mUserIdManager.getSystemUser()), /* setSelected= */false); mTabs.addTab(createTab(R.string.work_tab, mTabs.addTab(createTab( getEnterpriseString(WORK_TAB, R.string.work_tab), mUserIdManager.getManagedUser()), /* setSelected= */false); } } } private String getEnterpriseString(String updatableStringId, int defaultStringId) { if (SdkLevel.isAtLeastT()) { return getUpdatableEnterpriseString(updatableStringId, defaultStringId); } else { return mTabsContainer.getContext().getString(defaultStringId); } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) private String getUpdatableEnterpriseString(String updatableStringId, int defaultStringId) { DevicePolicyManager dpm = mTabsContainer.getContext().getSystemService( DevicePolicyManager.class); return dpm.getResources().getString( updatableStringId, () -> mTabsContainer.getContext().getString(defaultStringId)); } /** * Returns the user represented by the selected tab. If there is no tab, return the * current user. Loading @@ -145,8 +171,8 @@ public class ProfileTabs implements ProfileTabsAddons { && mState.stack.getRoot() != null && mState.stack.getRoot().supportsCrossProfile(); } private TabLayout.Tab createTab(int resId, UserId userId) { return mTabs.newTab().setText(resId).setTag(userId); private TabLayout.Tab createTab(String text, UserId userId) { return mTabs.newTab().setText(text).setTag(userId); } @Override Loading
src/com/android/documentsui/dirlist/DocumentHolder.java +31 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,13 @@ package com.android.documentsui.dirlist; import static com.android.documentsui.DevicePolicyResources.Strings.PREVIEW_WORK_FILE_ACCESSIBILITY; import static com.android.documentsui.DevicePolicyResources.Strings.UNDEFINED; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.database.Cursor; import android.os.Build; import android.os.Bundle; import android.view.KeyEvent; import android.view.LayoutInflater; Loading @@ -27,11 +32,14 @@ import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.widget.ImageView; import androidx.annotation.RequiresApi; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.R; import com.android.documentsui.base.Shared; import com.android.documentsui.base.State; import com.android.modules.utils.build.SdkLevel; import java.util.function.Function; Loading Loading @@ -171,6 +179,29 @@ public abstract class DocumentHolder return view.animate().setDuration(Shared.CHECK_ANIMATION_DURATION).alpha(alpha); } protected String getPreviewIconContentDescription(boolean isWorkProfile, String fileName) { if (SdkLevel.isAtLeastT()) { return getUpdatablePreviewIconContentDescription(isWorkProfile, fileName); } else { return itemView.getResources().getString( isWorkProfile ? R.string.preview_work_file : R.string.preview_file, fileName); } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) private String getUpdatablePreviewIconContentDescription( boolean isWorkProfile, String fileName) { DevicePolicyManager dpm = itemView.getContext().getSystemService( DevicePolicyManager.class); String updatableStringId = isWorkProfile ? PREVIEW_WORK_FILE_ACCESSIBILITY : UNDEFINED; int defaultStringId = isWorkProfile ? R.string.preview_work_file : R.string.preview_file; return dpm.getResources().getString( updatableStringId, () -> itemView.getResources().getString(defaultStringId, fileName), /* formatArgs= */ fileName); } protected static class PreviewAccessibilityDelegate extends View.AccessibilityDelegate { private Function<View, Boolean> mCallback; Loading