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

Commit b1a45a54 authored by Aditya's avatar Aditya
Browse files

Implementing cross profile contnet sharing startegy for docsUI.

The new strategy is based on the user property that dictates whether
cross profile contnet sharing is to be delegated from parent or not.

Bug: 313471319
Test: DocumentsUIGoogleTests:com.android.documentsui.UserManagerStateTest
Change-Id: Id5deb79e3837c9571b82c1e6ff72cd134c832dfd
Merged-In: Id5deb79e3837c9571b82c1e6ff72cd134c832dfd
parent b91e6f07
Loading
Loading
Loading
Loading
+60 −53
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ 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.android.documentsui.util.VersionUtils;
import com.google.android.material.appbar.AppBarLayout;

import java.util.ArrayList;
@@ -92,6 +92,7 @@ public abstract class BaseActivity
    protected SearchViewManager mSearchManager;
    protected AppsRowManager mAppsRowManager;
    protected UserIdManager mUserIdManager;
    protected UserManagerState mUserManagerState;
    protected State mState;

    @Injected
@@ -123,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();
@@ -166,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);
@@ -265,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
@@ -330,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
@@ -387,6 +400,7 @@ public abstract class BaseActivity
        mRootsMonitor.stop();
        mPreferencesMonitor.stop();
        mSortController.destroy();
        DocumentsApplication.invalidateUserManagerState(this);
        super.onDestroy();
    }

@@ -504,50 +518,39 @@ public abstract class BaseActivity
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
        final int id = item.getItemId();
        if (id == android.R.id.home) {
            onBackPressed();
            return true;

            case R.id.option_menu_create_dir:
        } else if (id == R.id.option_menu_create_dir) {
            getInjector().actions.showCreateDirectoryDialog();
            return true;

            case R.id.option_menu_search:
        } else if (id == R.id.option_menu_search) {
            // SearchViewManager listens for this directly.
            return false;

            case R.id.option_menu_select_all:
        } else if (id == R.id.option_menu_select_all) {
            getInjector().actions.selectAllFiles();
            return true;

            case R.id.option_menu_debug:
        } else if (id == R.id.option_menu_debug) {
            getInjector().actions.showDebugMessage();
            return true;

            case R.id.option_menu_sort:
        } else if (id == R.id.option_menu_sort) {
            getInjector().actions.showSortDialog();
            return true;

            case R.id.option_menu_launcher:
        } else if (id == R.id.option_menu_launcher) {
            getInjector().actions.switchLauncherIcon();
            return true;

            case R.id.option_menu_show_hidden_files:
        } else if (id == R.id.option_menu_show_hidden_files) {
            onClickedShowHiddenFiles();
            return true;

            case R.id.sub_menu_grid:
                setViewMode(State.MODE_GRID);
        } else if (id == R.id.sub_menu_grid) {
            setViewMode(MODE_GRID);
            return true;

            case R.id.sub_menu_list:
        } else if (id == R.id.sub_menu_list) {
            setViewMode(State.MODE_LIST);
            return true;

            default:
                return super.onOptionsItemSelected(item);
        }
        return super.onOptionsItemSelected(item);
    }

    protected final @Nullable DirectoryFragment getDirectoryFragment() {
@@ -556,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();
@@ -594,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) {
@@ -720,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) {
@@ -821,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,
+33 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.util.FeatureFlagUtils;
import com.android.documentsui.util.VersionUtils;
import com.android.modules.utils.build.SdkLevel;

@@ -80,6 +81,29 @@ public class NavigationViewManager implements AppBarLayout.OnOffsetChangedListen
            Breadcrumb breadcrumb,
            View tabLayoutContainer,
            UserIdManager userIdManager) {
        this(activity, drawer, state, env, breadcrumb, tabLayoutContainer, userIdManager, null);
    }

    public NavigationViewManager(
            BaseActivity activity,
            DrawerController drawer,
            State state,
            NavigationViewManager.Environment env,
            Breadcrumb breadcrumb,
            View tabLayoutContainer,
            UserManagerState userManagerState) {
        this(activity, drawer, state, env, breadcrumb, tabLayoutContainer, null, userManagerState);
    }

    public NavigationViewManager(
            BaseActivity activity,
            DrawerController drawer,
            State state,
            NavigationViewManager.Environment env,
            Breadcrumb breadcrumb,
            View tabLayoutContainer,
            UserIdManager userIdManager,
            UserManagerState userManagerState) {

        mActivity = activity;
        mToolbar = activity.findViewById(R.id.toolbar);
@@ -89,7 +113,8 @@ public class NavigationViewManager implements AppBarLayout.OnOffsetChangedListen
        mEnv = env;
        mBreadcrumb = breadcrumb;
        mBreadcrumb.setup(env, state, this::onNavigationItemSelected);
        mProfileTabs = new ProfileTabs(tabLayoutContainer, mState, userIdManager, mEnv, activity);
        mProfileTabs =
                getProfileTabs(tabLayoutContainer, userIdManager, userManagerState, activity);

        mToolbar.setNavigationOnClickListener(
                new View.OnClickListener() {
@@ -128,6 +153,13 @@ public class NavigationViewManager implements AppBarLayout.OnOffsetChangedListen
        };
    }

    private ProfileTabs getProfileTabs(View tabLayoutContainer, UserIdManager userIdManager,
            UserManagerState userManagerState, BaseActivity activity) {
        return FeatureFlagUtils.isPrivateSpaceEnabled()
                ? new ProfileTabs(tabLayoutContainer, mState, userManagerState, mEnv, activity)
                : new ProfileTabs(tabLayoutContainer, mState, userIdManager, mEnv, activity);
    }

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
        if (!VersionUtils.isAtLeastS()) {
Loading