Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 509de9c3 authored by Aditya Singh's avatar Aditya Singh Committed by Android (Google) Code Review
Browse files

Merge changes I130cda26,Id5deb79e,I73ed1b39 into main

* changes:
  Introducing private tab in profile tabs and sidebar.
  Implementing cross profile contnet sharing startegy for docsUI.
  Inroducing new UserManagerState class for docsUI.
parents 7d963af0 99f3acaa
Loading
Loading
Loading
Loading
+29 −17
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
    public void registerDisplayStateChangedListener(Runnable l) {
        mDisplayStateChangedListener = l;
    }

    @Override
    public void unregisterDisplayStateChangedListener(Runnable l) {
        if (mDisplayStateChangedListener == l) {
@@ -372,6 +373,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
    }

    // TODO: Make this private and make tests call interface method instead.

    /**
     * Behavior when a document is opened.
     */
@@ -974,24 +976,34 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
            mLoaderSemaphore.release();
        }
    }

    /**
     * A class primarily for the support of isolating our tests
     * from our concrete activity implementations.
     */
    public interface CommonAddons {
        void restoreRootAndDirectory();

        void refreshCurrentRootAndDirectory(@AnimationType int anim);

        void onRootPicked(RootInfo root);

        // TODO: Move this to PickAddons as multi-document picking is exclusive to that activity.
        void onDocumentsPicked(List<DocumentInfo> docs);

        void onDocumentPicked(DocumentInfo doc);

        RootInfo getCurrentRoot();

        DocumentInfo getCurrentDirectory();

        UserId getSelectedUser();

        /**
         * Check whether current directory is root of recent.
         */
        boolean isInRecents();

        void setRootsDrawerOpen(boolean open);

        /**
+28 −9
Original line number Diff line number Diff line
@@ -74,6 +74,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.documentsui.util.FeatureFlagUtils;

import com.google.android.material.appbar.AppBarLayout;

@@ -91,6 +92,7 @@ public abstract class BaseActivity
    protected SearchViewManager mSearchManager;
    protected AppsRowManager mAppsRowManager;
    protected UserIdManager mUserIdManager;
    protected UserManagerState mUserManagerState;
    protected State mState;

    @Injected
@@ -122,8 +124,10 @@ public abstract class BaseActivity
    }

    protected abstract void refreshDirectory(int anim);

    /** Allows sub-classes to include information in a newly created State instance. */
    protected abstract void includeState(State initialState);

    protected abstract void onDirectoryCreated(DocumentInfo doc);

    public abstract Injector<?> getInjector();
@@ -165,8 +169,7 @@ public abstract class BaseActivity
        View profileTabsContainer = findViewById(R.id.tabs_container);
        assert (profileTabsContainer != null);

        mNavigator = new NavigationViewManager(this, mDrawer, mState, this, breadcrumb,
                profileTabsContainer, DocumentsApplication.getUserIdManager(this));
        mNavigator = getNavigationViewManager(breadcrumb, profileTabsContainer);
        AppBarLayout appBarLayout = findViewById(R.id.app_bar);
        if (appBarLayout != null) {
            appBarLayout.addOnOffsetChangedListener(mNavigator);
@@ -264,6 +267,7 @@ public abstract class BaseActivity

        ViewGroup chipGroup = findViewById(R.id.search_chip_group);
        mUserIdManager = DocumentsApplication.getUserIdManager(this);
        mUserManagerState = DocumentsApplication.getUserManagerState(this);
        mSearchManager = new SearchViewManager(searchListener, queryInterceptor,
                chipGroup, savedInstanceState);
        // initialize the chip sets by accept mime types
@@ -329,6 +333,16 @@ public abstract class BaseActivity
        setResult(AppCompatActivity.RESULT_CANCELED);
    }

    private NavigationViewManager getNavigationViewManager(Breadcrumb breadcrumb,
            View profileTabsContainer) {
        if (FeatureFlagUtils.isPrivateSpaceEnabled()) {
            return new NavigationViewManager(this, mDrawer, mState, this, breadcrumb,
                    profileTabsContainer, DocumentsApplication.getUserManagerState(this));
        }
        return new NavigationViewManager(this, mDrawer, mState, this, breadcrumb,
                profileTabsContainer, DocumentsApplication.getUserIdManager(this));
    }

    public void onPreferenceChanged(String pref) {
        // For now, we only work with prefs that we backup. This
        // just limits the scope of what we expect to come flowing
@@ -386,6 +400,7 @@ public abstract class BaseActivity
        mRootsMonitor.stop();
        mPreferencesMonitor.stop();
        mSortController.destroy();
        DocumentsApplication.invalidateUserManagerState(this);
        super.onDestroy();
    }

@@ -544,7 +559,6 @@ public abstract class BaseActivity

    /**
     * Returns true if a directory can be created in the current location.
     * @return
     */
    protected boolean canCreateDirectory() {
        final RootInfo root = getCurrentRoot();
@@ -582,7 +596,6 @@ public abstract class BaseActivity
    /**
     * Refreshes the content of the director and the menu/action bar.
     * The current directory name and selection will get updated.
     * @param anim
     */
    @Override
    public final void refreshCurrentRootAndDirectory(int anim) {
@@ -708,6 +721,11 @@ public abstract class BaseActivity
        }
    }

    /**
     * Updates headerContainer by setting its visibility
     *
     * @param shouldHideHeader whether to hide header container or not
     */
    public void updateHeader(boolean shouldHideHeader) {
        View headerContainer = findViewById(R.id.header_container);
        if (headerContainer == null) {
@@ -809,6 +827,7 @@ public abstract class BaseActivity

    /**
     * Get title string equal to the string action bar displayed.
     *
     * @return current directory title name
     */
    public String getCurrentTitle() {
+9 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.roots.RootCursorWrapper;
import com.android.documentsui.sorting.SortModel;
import com.android.documentsui.util.FeatureFlagUtils;

import java.util.ArrayList;
import java.util.List;
@@ -129,8 +130,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
            if (mSearchMode) {
                queryArgs.putAll(mQueryArgs);
                if (shouldSearchAcrossProfile()) {
                    for (UserId userId : DocumentsApplication.getUserIdManager(
                            getContext()).getUserIds()) {
                    for (UserId userId : getUserIds()) {
                        if (mState.canInteractWith(userId)) {
                            userIds.add(userId);
                        }
@@ -330,4 +330,11 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
        }
        return false;
    }

    private List<UserId> getUserIds() {
        if (FeatureFlagUtils.isPrivateSpaceEnabled()) {
            return DocumentsApplication.getUserManagerState(getContext()).getUserIds();
        }
        return DocumentsApplication.getUserIdManager(getContext()).getUserIds();
    }
}
+0 −1
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ public interface DocumentsAccess {
    public final class RuntimeDocumentAccess implements DocumentsAccess {

        private static final String TAG = "DocumentAccess";

        private final Context mContext;
        private final State mState;

+45 −8
Original line number Diff line number Diff line
@@ -41,10 +41,13 @@ import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.queries.SearchHistoryManager;
import com.android.documentsui.roots.ProvidersCache;
import com.android.documentsui.theme.ThemeOverlayManager;
import com.android.documentsui.util.FeatureFlagUtils;
import com.android.modules.utils.build.SdkLevel;

import com.google.common.collect.Lists;

import java.util.List;
import java.util.Objects;

public class DocumentsApplication extends Application {
    private static final String TAG = "DocumentsApplication";
@@ -57,7 +60,7 @@ public class DocumentsApplication extends Application {
            Intent.ACTION_PACKAGE_DATA_CLEARED
    );

    private static final List<String> MANAGED_PROFILE_FILTER_ACTIONS = Lists.newArrayList(
    private static final List<String> PROFILE_FILTER_ACTIONS = Lists.newArrayList(
            Intent.ACTION_MANAGED_PROFILE_ADDED,
            Intent.ACTION_MANAGED_PROFILE_REMOVED,
            Intent.ACTION_MANAGED_PROFILE_UNLOCKED,
@@ -70,6 +73,7 @@ public class DocumentsApplication extends Application {
    private DocumentClipper mClipper;
    private DragAndDropManager mDragAndDropManager;
    private UserIdManager mUserIdManager;
    private UserManagerState mUserManagerState;
    private Lookup<String, String> mFileTypeLookup;

    public static ProvidersCache getProvidersCache(Context context) {
@@ -104,6 +108,16 @@ public class DocumentsApplication extends Application {
        return ((DocumentsApplication) context.getApplicationContext()).mUserIdManager;
    }

    /**
     * UserManagerState class is used to maintain the list of userIds and other details like
     * cross profile access, label and badge associated with these userIds.
     */
    public static UserManagerState getUserManagerState(Context context) {
        return Objects.requireNonNullElseGet(
                ((DocumentsApplication) context.getApplicationContext()).mUserManagerState,
                () -> UserManagerState.create(context));
    }

    public static DragAndDropManager getDragAndDropManager(Context context) {
        return ((DocumentsApplication) context.getApplicationContext()).mDragAndDropManager;
    }
@@ -112,6 +126,14 @@ public class DocumentsApplication extends Application {
        return ((DocumentsApplication) context.getApplicationContext()).mFileTypeLookup;
    }

    /**
     * Set mUserManagerState as null onDestroy of BaseActivity so that new session uses new instance
     * of mUserManagerState
     */
    public static void invalidateUserManagerState(Context context) {
        ((DocumentsApplication) context.getApplicationContext()).mUserManagerState = null;
    }

    private void onApplyOverlayFinish(boolean result) {
        Log.d(TAG, "OverlayManager.setEnabled() result: " + result);
    }
@@ -132,9 +154,16 @@ public class DocumentsApplication extends Application {
            Log.w(TAG, "Can't obtain OverlayManager from System Service!");
        }

        if (FeatureFlagUtils.isPrivateSpaceEnabled()) {
            mUserManagerState = UserManagerState.create(this);
            mUserIdManager = null;
            mProviders = new ProvidersCache(this, mUserManagerState);
        } else {
            mUserManagerState = null;
            mUserIdManager = UserIdManager.create(this);

            mProviders = new ProvidersCache(this, mUserIdManager);
        }

        mProviders.updateAsync(/* forceRefreshAll= */ false, /* callback= */  null);

        mThumbnailCache = new ThumbnailCache(memoryClassBytes / 4);
@@ -159,11 +188,19 @@ public class DocumentsApplication extends Application {
        localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
        registerReceiver(mCacheReceiver, localeFilter);

        final IntentFilter managedProfileFilter = new IntentFilter();
        for (String managedProfileAction : MANAGED_PROFILE_FILTER_ACTIONS) {
            managedProfileFilter.addAction(managedProfileAction);
        if (SdkLevel.isAtLeastV()) {
            PROFILE_FILTER_ACTIONS.addAll(Lists.newArrayList(
                    Intent.ACTION_PROFILE_ADDED,
                    Intent.ACTION_PROFILE_REMOVED,
                    Intent.ACTION_PROFILE_AVAILABLE,
                    Intent.ACTION_PROFILE_UNAVAILABLE
            ));
        }
        final IntentFilter profileFilter = new IntentFilter();
        for (String profileAction : PROFILE_FILTER_ACTIONS) {
            profileFilter.addAction(profileAction);
        }
        registerReceiver(mCacheReceiver, managedProfileFilter);
        registerReceiver(mCacheReceiver, profileFilter);

        SearchHistoryManager.getInstance(getApplicationContext());
    }
@@ -183,7 +220,7 @@ public class DocumentsApplication extends Application {
            if (PACKAGE_FILTER_ACTIONS.contains(action) && data != null) {
                final String packageName = data.getSchemeSpecificPart();
                mProviders.updatePackageAsync(UserId.DEFAULT_USER, packageName);
            } else if (MANAGED_PROFILE_FILTER_ACTIONS.contains(action)) {
            } else if (PROFILE_FILTER_ACTIONS.contains(action)) {
                // After we have reloaded roots. Resend the broadcast locally so the other
                // components can reload properly after roots are updated.
                mProviders.updateAsync(/* forceRefreshAll= */ true,
Loading