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

Commit 608c5b77 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android Git Automerger
Browse files

am 21de56a9: Add directory selection to DocumentsProvider.

* commit '21de56a94668e0fda1b8bb4ee4f99a09b40d28fd':
  Add directory selection to DocumentsProvider.
parents 1f0ae2aa 6e565ffa
Loading
Loading
Loading
Loading
+6 −12
Original line number Original line Diff line number Diff line
@@ -9,18 +9,17 @@
        android:label="@string/app_label"
        android:label="@string/app_label"
        android:supportsRtl="true">
        android:supportsRtl="true">


        <!-- TODO: allow rotation when state saving is in better shape -->
        <activity
        <activity
            android:name=".DocumentsActivity"
            android:name=".DocumentsActivity"
            android:theme="@style/Theme"
            android:theme="@style/Theme"
            android:icon="@drawable/ic_doc_text">
            android:icon="@drawable/ic_doc_text">
            <intent-filter android:priority="100">
            <intent-filter>
                <action android:name="android.intent.action.OPEN_DOCUMENT" />
                <action android:name="android.intent.action.OPEN_DOCUMENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.OPENABLE" />
                <category android:name="android.intent.category.OPENABLE" />
                <data android:mimeType="*/*" />
                <data android:mimeType="*/*" />
            </intent-filter>
            </intent-filter>
            <intent-filter android:priority="100">
            <intent-filter>
                <action android:name="android.intent.action.CREATE_DOCUMENT" />
                <action android:name="android.intent.action.CREATE_DOCUMENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.OPENABLE" />
                <category android:name="android.intent.category.OPENABLE" />
@@ -32,6 +31,10 @@
                <category android:name="android.intent.category.OPENABLE" />
                <category android:name="android.intent.category.OPENABLE" />
                <data android:mimeType="*/*" />
                <data android:mimeType="*/*" />
            </intent-filter>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK_DIRECTORY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
            <intent-filter>
                <action android:name="android.provider.action.MANAGE_ROOT" />
                <action android:name="android.provider.action.MANAGE_ROOT" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.DEFAULT" />
@@ -57,14 +60,5 @@
                <data android:scheme="package" />
                <data android:scheme="package" />
            </intent-filter>
            </intent-filter>
        </receiver>
        </receiver>

        <!-- TODO: remove when we have real clients -->
        <activity android:name=".TestActivity" android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    </application>
</manifest>
</manifest>
+48 −0
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <!-- Le sigh, this really should be an asset -->
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#ccc" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:baselineAligned="false"
        android:gravity="center_vertical"
        android:background="#ddd"
        android:minHeight="?android:attr/listPreferredItemHeightSmall">

        <Button
            android:id="@android:id/button1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?android:attr/selectableItemBackground"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textAllCaps="false"
            android:padding="8dp" />

    </LinearLayout>

</LinearLayout>
+2 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,8 @@
    <string name="menu_share">Share</string>
    <string name="menu_share">Share</string>
    <!-- Menu item title that deletes the selected documents [CHAR LIMIT=24] -->
    <!-- Menu item title that deletes the selected documents [CHAR LIMIT=24] -->
    <string name="menu_delete">Delete</string>
    <string name="menu_delete">Delete</string>
    <!-- Menu item title that selects the current directory [CHAR LIMIT=48] -->
    <string name="menu_select">Select \"<xliff:g id="directory" example="My Directory">^1</xliff:g>\"</string>


    <!-- Action mode title summarizing the number of documents selected [CHAR LIMIT=32] -->
    <!-- Action mode title summarizing the number of documents selected [CHAR LIMIT=32] -->
    <string name="mode_selected_count"><xliff:g id="count" example="3">%1$d</xliff:g> selected</string>
    <string name="mode_selected_count"><xliff:g id="count" example="3">%1$d</xliff:g> selected</string>
+56 −7
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE;
import static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT;
import static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT;
import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
import static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN;
import static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN;
import static com.android.documentsui.DocumentsActivity.State.ACTION_PICK_DIRECTORY;
import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
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_LIST;


@@ -202,6 +203,8 @@ public class DocumentsActivity extends Activity {
            final String mimeType = getIntent().getType();
            final String mimeType = getIntent().getType();
            final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
            final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
            SaveFragment.show(getFragmentManager(), mimeType, title);
            SaveFragment.show(getFragmentManager(), mimeType, title);
        } else if (mState.action == ACTION_PICK_DIRECTORY) {
            PickFragment.show(getFragmentManager());
        }
        }


        if (mState.action == ACTION_GET_CONTENT) {
        if (mState.action == ACTION_GET_CONTENT) {
@@ -209,7 +212,8 @@ public class DocumentsActivity extends Activity {
            moreApps.setComponent(null);
            moreApps.setComponent(null);
            moreApps.setPackage(null);
            moreApps.setPackage(null);
            RootsFragment.show(getFragmentManager(), moreApps);
            RootsFragment.show(getFragmentManager(), moreApps);
        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_CREATE) {
        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_CREATE
                || mState.action == ACTION_PICK_DIRECTORY) {
            RootsFragment.show(getFragmentManager(), null);
            RootsFragment.show(getFragmentManager(), null);
        }
        }


@@ -236,6 +240,8 @@ public class DocumentsActivity extends Activity {
            mState.action = ACTION_CREATE;
            mState.action = ACTION_CREATE;
        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
            mState.action = ACTION_GET_CONTENT;
            mState.action = ACTION_GET_CONTENT;
        } else if (Intent.ACTION_PICK_DIRECTORY.equals(action)) {
            mState.action = ACTION_PICK_DIRECTORY;
        } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
        } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
            mState.action = ACTION_MANAGE;
            mState.action = ACTION_MANAGE;
        }
        }
@@ -434,7 +440,8 @@ public class DocumentsActivity extends Activity {
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            actionBar.setIcon(new ColorDrawable());
            actionBar.setIcon(new ColorDrawable());


            if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
            if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT
                    || mState.action == ACTION_PICK_DIRECTORY) {
                actionBar.setTitle(R.string.title_open);
                actionBar.setTitle(R.string.title_open);
            } else if (mState.action == ACTION_CREATE) {
            } else if (mState.action == ACTION_CREATE) {
                actionBar.setTitle(R.string.title_save);
                actionBar.setTitle(R.string.title_save);
@@ -576,7 +583,7 @@ public class DocumentsActivity extends Activity {
        sortSize.setVisible(mState.showSize);
        sortSize.setVisible(mState.showSize);


        final boolean searchVisible;
        final boolean searchVisible;
        if (mState.action == ACTION_CREATE) {
        if (mState.action == ACTION_CREATE || mState.action == ACTION_PICK_DIRECTORY) {
            createDir.setVisible(cwd != null && cwd.isCreateSupported());
            createDir.setVisible(cwd != null && cwd.isCreateSupported());
            searchVisible = false;
            searchVisible = false;


@@ -586,7 +593,9 @@ public class DocumentsActivity extends Activity {
                list.setVisible(false);
                list.setVisible(false);
            }
            }


            if (mState.action == ACTION_CREATE) {
                SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
                SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
            }
        } else {
        } else {
            createDir.setVisible(false);
            createDir.setVisible(false);


@@ -819,7 +828,7 @@ public class DocumentsActivity extends Activity {


        if (cwd == null) {
        if (cwd == null) {
            // No directory means recents
            // No directory means recents
            if (mState.action == ACTION_CREATE) {
            if (mState.action == ACTION_CREATE || mState.action == ACTION_PICK_DIRECTORY) {
                RecentsCreateFragment.show(fm);
                RecentsCreateFragment.show(fm);
            } else {
            } else {
                DirectoryFragment.showRecentsOpen(fm, anim);
                DirectoryFragment.showRecentsOpen(fm, anim);
@@ -848,6 +857,15 @@ public class DocumentsActivity extends Activity {
            }
            }
        }
        }


        if (mState.action == ACTION_PICK_DIRECTORY) {
            final PickFragment pick = PickFragment.get(fm);
            if (pick != null) {
                final CharSequence displayName = (mState.stack.size() <= 1) ? root.title
                        : cwd.displayName;
                pick.setPickTarget(cwd, displayName);
            }
        }

        final RootsFragment roots = RootsFragment.get(fm);
        final RootsFragment roots = RootsFragment.get(fm);
        if (roots != null) {
        if (roots != null) {
            roots.onCurrentRootChanged();
            roots.onCurrentRootChanged();
@@ -1002,12 +1020,18 @@ public class DocumentsActivity extends Activity {
        new CreateFinishTask(mimeType, displayName).executeOnExecutor(getCurrentExecutor());
        new CreateFinishTask(mimeType, displayName).executeOnExecutor(getCurrentExecutor());
    }
    }


    public void onPickRequested(DocumentInfo pickTarget) {
        final Uri viaUri = DocumentsContract.buildViaUri(pickTarget.authority,
                pickTarget.documentId);
        new PickFinishTask(viaUri).executeOnExecutor(getCurrentExecutor());
    }

    private void saveStackBlocking() {
    private void saveStackBlocking() {
        final ContentResolver resolver = getContentResolver();
        final ContentResolver resolver = getContentResolver();
        final ContentValues values = new ContentValues();
        final ContentValues values = new ContentValues();


        final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
        final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
        if (mState.action == ACTION_CREATE) {
        if (mState.action == ACTION_CREATE || mState.action == ACTION_PICK_DIRECTORY) {
            // Remember stack for last create
            // Remember stack for last create
            values.clear();
            values.clear();
            values.put(RecentColumns.KEY, mState.stack.buildKey());
            values.put(RecentColumns.KEY, mState.stack.buildKey());
@@ -1040,6 +1064,11 @@ public class DocumentsActivity extends Activity {


        if (mState.action == ACTION_GET_CONTENT) {
        if (mState.action == ACTION_GET_CONTENT) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else if (mState.action == ACTION_PICK_DIRECTORY) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
        } else {
        } else {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
@@ -1121,6 +1150,25 @@ public class DocumentsActivity extends Activity {
        }
        }
    }
    }


    private class PickFinishTask extends AsyncTask<Void, Void, Void> {
        private final Uri mUri;

        public PickFinishTask(Uri uri) {
            mUri = uri;
        }

        @Override
        protected Void doInBackground(Void... params) {
            saveStackBlocking();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            onFinished(mUri);
        }
    }

    public static class State implements android.os.Parcelable {
    public static class State implements android.os.Parcelable {
        public int action;
        public int action;
        public String[] acceptMimes;
        public String[] acceptMimes;
@@ -1154,7 +1202,8 @@ public class DocumentsActivity extends Activity {
        public static final int ACTION_OPEN = 1;
        public static final int ACTION_OPEN = 1;
        public static final int ACTION_CREATE = 2;
        public static final int ACTION_CREATE = 2;
        public static final int ACTION_GET_CONTENT = 3;
        public static final int ACTION_GET_CONTENT = 3;
        public static final int ACTION_MANAGE = 4;
        public static final int ACTION_PICK_DIRECTORY = 4;
        public static final int ACTION_MANAGE = 5;


        public static final int MODE_UNKNOWN = 0;
        public static final int MODE_UNKNOWN = 0;
        public static final int MODE_LIST = 1;
        public static final int MODE_LIST = 1;
+89 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2014 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 android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.android.documentsui.model.DocumentInfo;

import java.util.Locale;

/**
 * Display pick confirmation bar, usually for selecting a directory.
 */
public class PickFragment extends Fragment {
    public static final String TAG = "PickFragment";

    private DocumentInfo mPickTarget;

    private View mContainer;
    private Button mPick;

    public static void show(FragmentManager fm) {
        final PickFragment fragment = new PickFragment();

        final FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.container_save, fragment, TAG);
        ft.commitAllowingStateLoss();
    }

    public static PickFragment get(FragmentManager fm) {
        return (PickFragment) fm.findFragmentByTag(TAG);
    }

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContainer = inflater.inflate(R.layout.fragment_pick, container, false);

        mPick = (Button) mContainer.findViewById(android.R.id.button1);
        mPick.setOnClickListener(mPickListener);

        setPickTarget(null, null);

        return mContainer;
    }

    private View.OnClickListener mPickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final DocumentsActivity activity = DocumentsActivity.get(PickFragment.this);
            activity.onPickRequested(mPickTarget);
        }
    };

    public void setPickTarget(DocumentInfo pickTarget, CharSequence displayName) {
        mPickTarget = pickTarget;

        if (mPickTarget != null) {
            mContainer.setVisibility(View.VISIBLE);
            final Locale locale = getResources().getConfiguration().locale;
            final String raw = getString(R.string.menu_select).toUpperCase(locale);
            mPick.setText(TextUtils.expandTemplate(raw, displayName));
        } else {
            mContainer.setVisibility(View.GONE);
        }
    }
}
Loading