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

Commit e934ce6f authored by Steve McKay's avatar Steve McKay
Browse files

Implement a standalone file manager activity.

Change-Id: Iaf86ef416b979cea4ab3890d3a26f09741392c3d
parent 527b4537
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -42,6 +42,17 @@
            </intent-filter>
        </activity>

        <activity
            android:name=".StandaloneActivity"
            android:theme="@style/StandaloneTheme"
            android:icon="@drawable/ic_doc_text"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:name=".RecentsProvider"
            android:authorities="com.android.documentsui.recents"
+18 −0
Original line number Diff line number Diff line
@@ -43,4 +43,22 @@
        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
    </style>

    <style name="StandaloneTheme" parent="android:Theme.Light">
        <item name="android:actionBarWidgetTheme">@null</item>
        <item name="android:actionBarTheme">@*android:style/ThemeOverlay.Material.Dark.ActionBar</item>
        <item name="android:actionBarPopupTheme">@*android:style/ThemeOverlay.Material.Light</item>

        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_900</item>
        <item name="android:colorPrimary">@*android:color/material_blue_grey_800</item>
        <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>

        <item name="android:listDivider">@*android:drawable/list_divider_material</item>

        <item name="android:windowActionBar">false</item>
        <item name="android:windowActionModeOverlay">true</item>
        <item name="android:windowNoTitle">true</item>

        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
    </style>

</resources>
+152 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui;

import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.Fragment;
import android.content.pm.ResolveInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;

import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
import com.google.common.collect.Maps;

abstract class BaseActivity extends Activity {

    public abstract State getDisplayState();
    public abstract RootInfo getCurrentRoot();
    public abstract void onStateChanged();
    public abstract void setRootsDrawerOpen(boolean open);
    public abstract void onDocumentPicked(DocumentInfo doc);
    public abstract void onDocumentsPicked(List<DocumentInfo> docs);
    public abstract DocumentInfo getCurrentDirectory();
    public abstract void setPending(boolean pending);
    public abstract void onStackPicked(DocumentStack stack);
    public abstract void onPickRequested(DocumentInfo pickTarget);
    public abstract void onAppPicked(ResolveInfo info);
    public abstract void onRootPicked(RootInfo root, boolean closeDrawer);
    public abstract void onSaveRequested(DocumentInfo replaceTarget);
    public abstract void onSaveRequested(String mimeType, String displayName);

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

    public static class State implements android.os.Parcelable {
        public int action;
        public String[] acceptMimes;

        /** Explicit user choice */
        public int userMode = MODE_UNKNOWN;
        /** Derived after loader */
        public int derivedMode = MODE_LIST;

        /** Explicit user choice */
        public int userSortOrder = SORT_ORDER_UNKNOWN;
        /** Derived after loader */
        public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;

        public boolean allowMultiple = false;
        public boolean showSize = false;
        public boolean localOnly = false;
        public boolean forceAdvanced = false;
        public boolean showAdvanced = false;
        public boolean stackTouched = false;
        public boolean restored = false;

        /** Current user navigation stack; empty implies recents. */
        public DocumentStack stack = new DocumentStack();
        /** Currently active search, overriding any stack. */
        public String currentSearch;

        /** Instance state for every shown directory */
        public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();

        public static final int ACTION_OPEN = 1;
        public static final int ACTION_CREATE = 2;
        public static final int ACTION_GET_CONTENT = 3;
        public static final int ACTION_OPEN_TREE = 4;
        public static final int ACTION_MANAGE = 5;
        public static final int ACTION_MANAGE_ALL = 6;

        public static final int MODE_UNKNOWN = 0;
        public static final int MODE_LIST = 1;
        public static final int MODE_GRID = 2;

        public static final int SORT_ORDER_UNKNOWN = 0;
        public static final int SORT_ORDER_DISPLAY_NAME = 1;
        public static final int SORT_ORDER_LAST_MODIFIED = 2;
        public static final int SORT_ORDER_SIZE = 3;

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(action);
            out.writeInt(userMode);
            out.writeStringArray(acceptMimes);
            out.writeInt(userSortOrder);
            out.writeInt(allowMultiple ? 1 : 0);
            out.writeInt(showSize ? 1 : 0);
            out.writeInt(localOnly ? 1 : 0);
            out.writeInt(forceAdvanced ? 1 : 0);
            out.writeInt(showAdvanced ? 1 : 0);
            out.writeInt(stackTouched ? 1 : 0);
            out.writeInt(restored ? 1 : 0);
            DurableUtils.writeToParcel(out, stack);
            out.writeString(currentSearch);
            out.writeMap(dirState);
        }

        public static final Creator<State> CREATOR = new Creator<State>() {
            @Override
            public State createFromParcel(Parcel in) {
                final State state = new State();
                state.action = in.readInt();
                state.userMode = in.readInt();
                state.acceptMimes = in.readStringArray();
                state.userSortOrder = in.readInt();
                state.allowMultiple = in.readInt() != 0;
                state.showSize = in.readInt() != 0;
                state.localOnly = in.readInt() != 0;
                state.forceAdvanced = in.readInt() != 0;
                state.showAdvanced = in.readInt() != 0;
                state.stackTouched = in.readInt() != 0;
                state.restored = in.readInt() != 0;
                DurableUtils.readFromParcel(in, state.stack);
                state.currentSearch = in.readString();
                in.readMap(state.dirState, null);
                return state;
            }

            @Override
            public State[] newArray(int size) {
                return new State[size];
            }
        };
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ public class CreateDirectoryFragment extends DialogFragment {
            public void onClick(DialogInterface dialog, int which) {
                final String displayName = text1.getText().toString();

                final DocumentsActivity activity = (DocumentsActivity) getActivity();
                final BaseActivity activity = (BaseActivity) getActivity();
                final DocumentInfo cwd = activity.getCurrentDirectory();

                new CreateDirectoryTask(activity, cwd, displayName).executeOnExecutor(
@@ -83,12 +83,12 @@ public class CreateDirectoryFragment extends DialogFragment {
    }

    private class CreateDirectoryTask extends AsyncTask<Void, Void, DocumentInfo> {
        private final DocumentsActivity mActivity;
        private final BaseActivity mActivity;
        private final DocumentInfo mCwd;
        private final String mDisplayName;

        public CreateDirectoryTask(
                DocumentsActivity activity, DocumentInfo cwd, String displayName) {
                BaseActivity activity, DocumentInfo cwd, String displayName) {
            mActivity = activity;
            mCwd = cwd;
            mDisplayName = displayName;
+13 −13
Original line number Diff line number Diff line
@@ -17,12 +17,12 @@
package com.android.documentsui;

import static com.android.documentsui.DocumentsActivity.TAG;
import static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE;
import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN;
import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN;
import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
import static com.android.documentsui.BaseActivity.State.MODE_GRID;
import static com.android.documentsui.BaseActivity.State.MODE_LIST;
import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
@@ -76,7 +76,7 @@ import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.documentsui.DocumentsActivity.State;
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.ProviderExecutor.Preemptable;
import com.android.documentsui.RecentsProvider.StateColumns;
import com.android.documentsui.model.DocumentInfo;
@@ -301,13 +301,13 @@ public class DirectoryFragment extends Fragment {
                    state.derivedMode = result.mode;
                }
                state.derivedSortOrder = result.sortOrder;
                ((DocumentsActivity) context).onStateChanged();
                ((BaseActivity) context).onStateChanged();

                updateDisplayState();

                // When launched into empty recents, show drawer
                if (mType == TYPE_RECENT_OPEN && mAdapter.isEmpty() && !state.stackTouched) {
                    ((DocumentsActivity) context).setRootsDrawerOpen(true);
                    ((BaseActivity) context).setRootsDrawerOpen(true);
                }

                // Restore any previous instance state
@@ -386,7 +386,7 @@ public class DirectoryFragment extends Fragment {
        // Mode change is just visual change; no need to kick loader, and
        // deliver change event immediately.
        state.derivedMode = state.userMode;
        ((DocumentsActivity) getActivity()).onStateChanged();
        ((BaseActivity) getActivity()).onStateChanged();

        updateDisplayState();
    }
@@ -441,7 +441,7 @@ public class DirectoryFragment extends Fragment {
                final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
                if (isDocumentEnabled(docMimeType, docFlags)) {
                    final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
                    ((DocumentsActivity) getActivity()).onDocumentPicked(doc);
                    ((BaseActivity) getActivity()).onDocumentPicked(doc);
                }
            }
        }
@@ -487,7 +487,7 @@ public class DirectoryFragment extends Fragment {

            final int id = item.getItemId();
            if (id == R.id.menu_open) {
                DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
                BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
                mode.finish();
                return true;

@@ -616,7 +616,7 @@ public class DirectoryFragment extends Fragment {
    }

    private static State getDisplayState(Fragment fragment) {
        return ((DocumentsActivity) fragment.getActivity()).getDisplayState();
        return ((BaseActivity) fragment.getActivity()).getDisplayState();
    }

    private static abstract class Footer {
Loading