summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Anna Zhuravleva <azhura@google.com> 2024-04-15 10:59:39 +0000
committer Anna Zhuravleva <azhura@google.com> 2024-04-17 16:30:29 +0000
commit676fc201538b1e8b64288488ca83acde4b151e95 (patch)
tree081f5ba666ea51c164ce15320b461064dc63d2e9
parent97fe5b16e48909e8c90c5a0304b75d91cbcf6925 (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
-rw-r--r--src/com/android/documentsui/BaseActivity.java26
-rw-r--r--src/com/android/documentsui/UserManagerState.java31
-rw-r--r--src/com/android/documentsui/dirlist/DirectoryFragment.java11
-rw-r--r--tests/common/com/android/documentsui/TestUserManagerState.java5
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;
+ }
}