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

Commit ec19b4b6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move Injector impl into separate class." into nyc-andromeda-dev

parents 166c5c6f 92ae43d5
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.dirlist.DocumentDetails;
import com.android.documentsui.dirlist.Model;

public interface ActionHandler {

@@ -82,4 +83,10 @@ public interface ActionHandler {
     * app.
     */
    void initLocation(Intent intent);

    /**
     * Allow action handler to be initialized in a new scope.
     * @return
     */
    <T extends ActionHandler> T reset(Model model, boolean searchMode);
}
+19 −25
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.view.MenuItem;
import android.view.View;

import com.android.documentsui.AbstractActionHandler.CommonAddons;
import com.android.documentsui.Injector.Injected;
import com.android.documentsui.NavigationViewManager.Breadcrumb;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.LocalPreferences;
@@ -60,39 +61,38 @@ import com.android.documentsui.selection.Selection;
import com.android.documentsui.sidebar.RootsFragment;
import com.android.documentsui.sorting.SortController;
import com.android.documentsui.sorting.SortModel;
import com.android.documentsui.ui.MessageBuilder;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;

public abstract class BaseActivity<T extends ActionHandler>
        extends Activity
        implements CommonAddons, Injector, NavigationViewManager.Environment {
public abstract class BaseActivity
        extends Activity implements CommonAddons, NavigationViewManager.Environment {

    private static final String BENCHMARK_TESTING_PACKAGE = "com.android.documentsui.appperftests";

    protected SearchViewManager mSearchManager;
    protected State mState;

    @Injected
    protected Injector<?> mInjector;

    protected @Nullable RetainedState mRetainedState;
    protected RootsCache mRoots;
    protected DocumentsAccess mDocs;
    protected MessageBuilder mMessages;
    protected DrawerController mDrawer;

    protected NavigationViewManager mNavigator;
    protected SortController mSortController;

    protected T mActions;

    private final List<EventListener> mEventListeners = new ArrayList<>();
    private final String mTag;

    @LayoutRes
    private int mLayoutId;

    private RootsMonitor<BaseActivity<?>> mRootsMonitor;
    private RootsMonitor<BaseActivity> mRootsMonitor;

    private long mStartTime;

@@ -107,13 +107,7 @@ public abstract class BaseActivity<T extends ActionHandler>
    protected abstract void includeState(State initialState);
    protected abstract void onDirectoryCreated(DocumentInfo doc);

    // Get ref to to focus manager without reset. Presumes it has had scrope vars initialized.
    protected abstract FocusManager getFocusManager();

    public final MessageBuilder getMessages() {
        assert(mMessages != null);
        return mMessages;
    }
    public abstract Injector<?> getInjector();

    @CallSuper
    @Override
@@ -129,8 +123,9 @@ public abstract class BaseActivity<T extends ActionHandler>

        setContentView(mLayoutId);

        mInjector = getInjector();
        mState = getState(icicle);
        mDrawer = DrawerController.create(this, getActivityConfig());
        mDrawer = DrawerController.create(this, mInjector.config);
        Metrics.logActivityLaunch(this, mState, intent);

        // we're really interested in retainining state in our very complex
@@ -139,7 +134,6 @@ public abstract class BaseActivity<T extends ActionHandler>
        mRetainedState = (RetainedState) getLastNonConfigurationInstance();
        mRoots = DocumentsApplication.getRootsCache(this);
        mDocs = DocumentsAccess.create(this);
        mMessages = new MessageBuilder(this);

        DocumentsToolbar toolbar = (DocumentsToolbar) findViewById(R.id.toolbar);
        setActionBar(toolbar);
@@ -186,7 +180,7 @@ public abstract class BaseActivity<T extends ActionHandler>

        mRootsMonitor = new RootsMonitor<>(
                this,
                mActions,
                mInjector.actions,
                mRoots,
                mDocs,
                mState,
@@ -238,8 +232,8 @@ public abstract class BaseActivity<T extends ActionHandler>

        includeState(state);

        state.showAdvanced =
                Shared.mustShowDeviceRoot(intent) || getScopedPreferences().getShowDeviceRoot();
        state.showAdvanced = Shared.mustShowDeviceRoot(intent)
                || mInjector.prefs.getShowDeviceRoot();

        // Only show the toggle if advanced isn't forced enabled.
        state.showDeviceStorageOption = !Shared.mustShowDeviceRoot(intent);
@@ -285,7 +279,7 @@ public abstract class BaseActivity<T extends ActionHandler>
            new GetRootDocumentTask(
                    root,
                    this,
                    mActions::openContainerDocument)
                    mInjector.actions::openContainerDocument)
                    .executeOnExecutor(getExecutorForCurrentDirectory());
        }
    }
@@ -417,8 +411,8 @@ public abstract class BaseActivity<T extends ActionHandler>
        return (root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
    }

    public static BaseActivity<?> get(Fragment fragment) {
        return (BaseActivity<?>) fragment.getActivity();
    public static BaseActivity get(Fragment fragment) {
        return (BaseActivity) fragment.getActivity();
    }

    public State getDisplayState() {
@@ -437,7 +431,7 @@ public abstract class BaseActivity<T extends ActionHandler>
        Metrics.logUserAction(this,
                display ? Metrics.USER_ACTION_SHOW_ADVANCED : Metrics.USER_ACTION_HIDE_ADVANCED);

        getScopedPreferences().setShowDeviceRoot(display);
        mInjector.prefs.setShowDeviceRoot(display);
        mState.showAdvanced = display;
        RootsFragment.get(getFragmentManager()).onDisplayStateChanged();
        invalidateOptionsMenu();
@@ -590,7 +584,7 @@ public abstract class BaseActivity<T extends ActionHandler>
        return false;
    }

    protected boolean focusRoots() {
    protected boolean focusSidebar() {
        RootsFragment rf = RootsFragment.get(getFragmentManager());
        assert (rf != null);
        return rf.requestFocus();
+6 −10
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/** A class that handles navigation and focus within the DirectoryFragment. */
public final class FocusManager implements FocusHandler {
    private static final String TAG = "FocusManager";

@@ -82,16 +81,16 @@ public final class FocusManager implements FocusHandler {

    @Override
    public boolean advanceFocusArea() {
        boolean toogleHappened = false;
        boolean focusChanged = false;
        if (mNavDrawerHasFocus) {
            mDrawer.setOpen(false);
            focusDirectoryList();
        } else {
            mDrawer.setOpen(true);
            toogleHappened = mRootsFocuser.run();
            focusChanged = mRootsFocuser.run();
        }

        if (toogleHappened) {
        if (focusChanged) {
            mNavDrawerHasFocus = !mNavDrawerHasFocus;
            return true;
        }
@@ -131,8 +130,7 @@ public final class FocusManager implements FocusHandler {
    @Override
    public boolean focusDirectoryList() {
        if (mScope.adapter.getItemCount() == 0) {
            if (DEBUG)
                Log.v(TAG, "Nothing to focus.");
            if (DEBUG) Log.v(TAG, "Nothing to focus.");
            return false;
        }

@@ -141,8 +139,7 @@ public final class FocusManager implements FocusHandler {
        // vs. Cut focused
        // item)
        if (mSelectionMgr.hasSelection()) {
            if (DEBUG)
                Log.v(TAG, "Existing selection found. No focus will be done.");
            if (DEBUG) Log.v(TAG, "Existing selection found. No focus will be done.");
            return false;
        }

@@ -341,8 +338,7 @@ public final class FocusManager implements FocusHandler {
     * @param pos
     * @param callback A callback to call after the given item has been focused.
     */
    private void focusItem(final int pos, @Nullable
    final FocusCallback callback) {
    private void focusItem(final int pos, @Nullable final FocusCallback callback) {
        if (mScope.pendingFocusId != null) {
            Log.v(TAG, "clearing pending focus id: " + mScope.pendingFocusId);
            mScope.pendingFocusId = null;
+87 −11
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package com.android.documentsui;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.MenuItem;
@@ -28,19 +31,92 @@ import com.android.documentsui.dirlist.Model;
import com.android.documentsui.selection.SelectionManager;
import com.android.documentsui.selection.SelectionManager.SelectionPredicate;
import com.android.documentsui.ui.DialogController;
import com.android.documentsui.ui.MessageBuilder;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * Provides access to runtime dependencies.
 */
public interface Injector {

    ActivityConfig getActivityConfig();
    ScopedPreferences getScopedPreferences();
    SelectionManager getSelectionManager(DocumentsAdapter adapter, SelectionPredicate canSetState);
    MenuManager getMenuManager();
    DialogController getDialogController();
    ActionHandler getActionHandler(@Nullable Model model, boolean searchMode);
    ActionModeController getActionModeController(
            SelectionDetails selectionDetails, EventHandler<MenuItem> menuItemClicker, View view);
    FocusManager getFocusManager(RecyclerView view, Model model);
public class Injector<T extends ActionHandler> {

    public final ActivityConfig config;
    public final ScopedPreferences prefs;
    public final MessageBuilder messages;

    public MenuManager menuManager;
    public DialogController dialogs;

    @ContentScoped
    public ActionModeController actionModeController;

    @ContentScoped
    public T actions;

    @ContentScoped
    public FocusManager focusManager;

    @ContentScoped
    public SelectionManager selectionMgr;

    // must be initialized before calling super.onCreate because prefs
    // are used in State initialization.
    public Injector(
            ActivityConfig config,
            ScopedPreferences prefs,
            MessageBuilder messages,
            DialogController dialogs) {

        this.config = config;
        this.prefs = prefs;
        this.messages = messages;
        this.dialogs = dialogs;
    }

    public FocusManager getFocusManager(RecyclerView view, Model model) {
        assert (focusManager != null);
        return focusManager.reset(view, model);
    }

    public SelectionManager getSelectionManager(
            DocumentsAdapter adapter, SelectionPredicate canSetState) {
        return selectionMgr.reset(adapter, canSetState);
    }

    public final ActionModeController getActionModeController(
            SelectionDetails selectionDetails, EventHandler<MenuItem> menuItemClicker, View view) {
        return actionModeController.reset(selectionDetails, menuItemClicker, view);
    }

    public T getActionHandler(
            @Nullable Model model, boolean searchMode) {

        // provide our friend, RootsFragment, early access to this special feature!
        if (model == null) {
            return actions;
        }

        return actions.reset(model, searchMode);
    }

    /**
     * Decorates a field that that is injected.
     */
    @Retention(SOURCE)
    @Target(FIELD)
    public @interface Injected {

    }

    /**
     * Decorates a field that holds an object that must be reset in the current content scope
     * (i.e. DirectoryFragment). Fields decorated with this must have an associated
     * accessor on Injector that, when call, reset the object for the calling context.
     */
    @Retention(SOURCE)
    @Target(FIELD)
    public @interface ContentScoped {

    }
}
+10 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.documentsui;

import android.app.Fragment;
import android.view.KeyboardShortcutGroup;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -27,10 +28,14 @@ import com.android.documentsui.base.Menus;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.files.FilesActivity;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.sidebar.RootsFragment;
import com.android.internal.annotations.VisibleForTesting;

import java.util.List;
import java.util.function.IntFunction;

public abstract class MenuManager {

    final protected SearchViewManager mSearchManager;
@@ -196,6 +201,9 @@ public abstract class MenuManager {
        updateSettings(settings, root);
    }

    public abstract void updateKeyboardShortcutsMenu(
            List<KeyboardShortcutGroup> data, IntFunction<String> stringSupplier);

    protected void updateModePicker(MenuItem grid, MenuItem list) {
        grid.setVisible(mState.derivedMode != State.MODE_GRID);
        list.setVisible(mState.derivedMode != State.MODE_LIST);
@@ -296,9 +304,9 @@ public abstract class MenuManager {
    }

    public static class DirectoryDetails {
        private final BaseActivity<?> mActivity;
        private final BaseActivity mActivity;

        public DirectoryDetails(BaseActivity<?> activity) {
        public DirectoryDetails(BaseActivity activity) {
            mActivity = activity;
        }

Loading