diff options
author | 2024-04-15 10:59:39 +0000 | |
---|---|---|
committer | 2024-04-17 16:30:29 +0000 | |
commit | 676fc201538b1e8b64288488ca83acde4b151e95 (patch) | |
tree | 081f5ba666ea51c164ce15320b461064dc63d2e9 | |
parent | 97fe5b16e48909e8c90c5a0304b75d91cbcf6925 (diff) |
Block taking recents screenshot if private profile available
DocsUI shows separate tab when private profile is on.
User can move DocUI to the background and then lock private
profile. Recents preview screen shows screenshot
of the DocUI at the last moment it was in foreground
(when the space was unlocked). As a result Recents preview
can leak whether private profile exists on device.
This change sets setting to show blank
screen in the recents when private profile is avaialble.
Bug: 329241706
Test: manual, https://b.corp.google.com/issues/329241706#comment3
Change-Id: I05914391db7bd15a88c6043d14265682ffd8437c
4 files changed, 66 insertions, 7 deletions
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java index 9e38303e1..514e98f23 100644 --- a/src/com/android/documentsui/BaseActivity.java +++ b/src/com/android/documentsui/BaseActivity.java @@ -75,6 +75,7 @@ import com.android.documentsui.roots.ProvidersCache; import com.android.documentsui.sidebar.RootsFragment; import com.android.documentsui.sorting.SortController; import com.android.documentsui.sorting.SortModel; +import com.android.modules.utils.build.SdkLevel; import com.google.android.material.appbar.AppBarLayout; @@ -376,6 +377,7 @@ public abstract class BaseActivity // Base classes must update result in their onCreate. setResult(AppCompatActivity.RESULT_CANCELED); + updateRecentsSetting(); } private NavigationViewManager getNavigationViewManager(Breadcrumb breadcrumb, @@ -1046,4 +1048,28 @@ public abstract class BaseActivity */ void onDirectoryLoaded(@Nullable Uri uri); } + + /** + * Updates the Recents preview settings based on presence of hidden profiles. Used not to leak + * Private profile existence when it was locked after the app was moved to the Recents. + */ + public void updateRecentsSetting() { + if (!SdkLevel.isAtLeastV()) { + return; + } + + if (mUserManagerState == null) { + Log.e(TAG, "Can't update Recents screenshot setting: User manager state is null."); + return; + } + + if (DEBUG) { + Log.d( + TAG, + "Set recents screenshot to " + + (!mUserManagerState.areHiddenInQuietModeProfilesPresent() ? "enabled" + : "disabled")); + } + setRecentsScreenshotEnabled(!mUserManagerState.areHiddenInQuietModeProfilesPresent()); + } } diff --git a/src/com/android/documentsui/UserManagerState.java b/src/com/android/documentsui/UserManagerState.java index eccc6b00c..2c2046cc4 100644 --- a/src/com/android/documentsui/UserManagerState.java +++ b/src/com/android/documentsui/UserManagerState.java @@ -89,8 +89,9 @@ public interface UserManagerState { * received in broadcast * * @param userId {@link UserId} for the profile for which the availability status changed - * @param action {@link Intent}.ACTION_PROFILE_UNAVAILABLE or - * {@link Intent}.ACTION_PROFILE_AVAILABLE + * @param action {@link Intent}.ACTION_PROFILE_UNAVAILABLE and {@link + * Intent}.ACTION_PROFILE_AVAILABLE, {@link Intent}.ACTION_PROFILE_ADDED} and {@link + * Intent}.ACTION_PROFILE_REMOVED} */ void onProfileActionStatusChange(String action, UserId userId); @@ -99,6 +100,9 @@ public interface UserManagerState { */ void setCurrentStateIntent(Intent intent); + /** Returns true if there are hidden profiles */ + boolean areHiddenInQuietModeProfilesPresent(); + /** * Creates an implementation of {@link UserManagerState}. */ @@ -235,11 +239,13 @@ public interface UserManagerState { if (userProperties.getShowInQuietMode() != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN) { return; } - if (Intent.ACTION_PROFILE_UNAVAILABLE.equals(action)) { + if (Intent.ACTION_PROFILE_UNAVAILABLE.equals(action) + || Intent.ACTION_PROFILE_REMOVED.equals(action)) { synchronized (mUserIds) { mUserIds.remove(userId); } - } else if (Intent.ACTION_PROFILE_AVAILABLE.equals(action)) { + } else if (Intent.ACTION_PROFILE_AVAILABLE.equals(action) + || Intent.ACTION_PROFILE_ADDED.equals(action)) { synchronized (mUserIds) { if (!mUserIds.contains(userId)) { mUserIds.add(userId); @@ -280,6 +286,23 @@ public interface UserManagerState { mCurrentStateIntent = intent; } + @Override + public boolean areHiddenInQuietModeProfilesPresent() { + if (!SdkLevel.isAtLeastV()) { + return false; + } + + for (UserId userId : getUserIds()) { + if (mUserManager + .getUserProperties(UserHandle.of(userId.getIdentifier())) + .getShowInQuietMode() + == UserProperties.SHOW_IN_QUIET_MODE_HIDDEN) { + return true; + } + } + return false; + } + private List<UserId> getUserIdsInternal() { final List<UserId> result = new ArrayList<>(); diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java index bf54e25fd..430540610 100644 --- a/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -262,8 +262,8 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On if (userProperties.getShowInQuietMode() == UserProperties.SHOW_IN_QUIET_MODE_PAUSED) { if (Objects.equal(mActivity.getSelectedUser(), userId)) { - // We only need to refresh the layout when the selected user is equal to the - // received profile user. + // We only need to refresh the layout when the selected user is equal to + // the received profile user. onPausedProfileStatusChange(action, userId); } return; @@ -308,6 +308,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On } private void onHiddenProfileStatusChange(String action, UserId userId) { + mActivity.updateRecentsSetting(); if (Intent.ACTION_PROFILE_UNAVAILABLE.equals(action)) { if (mProviderTestRunnable != null) { mHandler.removeCallbacks(mProviderTestRunnable); @@ -404,7 +405,9 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On private boolean isProfileStatusAction(String action) { if (!SdkLevel.isAtLeastV()) return isManagedProfileAction(action); return Intent.ACTION_PROFILE_AVAILABLE.equals(action) - || Intent.ACTION_PROFILE_UNAVAILABLE.equals(action); + || Intent.ACTION_PROFILE_UNAVAILABLE.equals(action) + || Intent.ACTION_PROFILE_ADDED.equals(action) + || Intent.ACTION_PROFILE_REMOVED.equals(action); } private static boolean isManagedProfileAction(String action) { @@ -642,6 +645,8 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On if (SdkLevel.isAtLeastV()) { filter.addAction(Intent.ACTION_PROFILE_AVAILABLE); filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE); + filter.addAction(Intent.ACTION_PROFILE_ADDED); + filter.addAction(Intent.ACTION_PROFILE_REMOVED); } // DocumentsApplication will resend the broadcast locally after roots are updated. // Register to a local broadcast manager to avoid this fragment from updating before diff --git a/tests/common/com/android/documentsui/TestUserManagerState.java b/tests/common/com/android/documentsui/TestUserManagerState.java index 5f41ce3e0..7b2ea8408 100644 --- a/tests/common/com/android/documentsui/TestUserManagerState.java +++ b/tests/common/com/android/documentsui/TestUserManagerState.java @@ -84,4 +84,9 @@ public class TestUserManagerState implements UserManagerState { @Override public void setCurrentStateIntent(Intent intent) { } + + @Override + public boolean areHiddenInQuietModeProfilesPresent() { + return false; + } } |