<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.REMOVE_TASKS" />
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
<application
android:name=".DocumentsApplication"
</activity>
<activity
- android:name=".FilesActivity"
- android:theme="@style/FilesTheme"
+ android:name=".LauncherActivity"
+ android:theme="@android:style/Theme.NoDisplay"
android:icon="@drawable/ic_files_app"
android:label="@string/files_label"
android:enabled="@bool/productivity_device">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
+ </activity>
+
+ <activity
+ android:name=".FilesActivity"
+ android:theme="@style/FilesTheme"
+ android:icon="@drawable/ic_files_app"
+ android:label="@string/files_label"
+ android:documentLaunchMode="intoExisting">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
<intent-filter>
<action android:name="android.provider.action.BROWSE_DOCUMENT_ROOT" />
<category android:name="android.intent.category.DEFAULT" />
android:id="@+id/menu_create_dir"
android:title="@string/menu_create_dir"
android:icon="@drawable/ic_menu_new_folder"
+ android:alphabeticShortcut="e"
android:showAsAction="always"
android:visible="false" />
<item
android:icon="@drawable/ic_menu_view_list"
android:showAsAction="never" />
<item
+ android:id="@+id/menu_new_window"
+ android:title="@string/menu_new_window"
+ android:alphabeticShortcut="n"
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
android:id="@+id/menu_paste_from_clipboard"
android:title="@string/menu_paste_from_clipboard"
android:alphabeticShortcut="v"
android:showAsAction="never"
android:visible="false" />
+ <!-- Copy action is defined in mode_directory.xml -->
<item
android:id="@+id/menu_advanced"
android:showAsAction="never"
<!-- Menu item title that moves the selected documents [CHAR LIMIT=24] -->
<string name="menu_move">Move to\u2026</string>
+ <!-- Menu item title that creates a new window in the activity [CHAR LIMIT=24] -->
+ <string name="menu_new_window">New window</string>
<!-- Menu item title that copies the selected documents to clipboard [CHAR LIMIT=24] -->
<string name="menu_copy_to_clipboard">Copy</string>
<!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] -->
RootsCache mRoots;
SearchManager mSearchManager;
DrawerController mDrawer;
+ boolean mProductivityDevice;
+ private final String mTag;
@LayoutRes
private int mLayoutId;
- private final String mTag;
private DirectoryContainerView mDirectoryContainer;
public abstract void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings);
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ mProductivityDevice = getResources().getBoolean(R.bool.productivity_device);
mState = (icicle != null)
? icicle.<State>getParcelable(EXTRA_STATE)
: buildState();
switch (item.getItemId()) {
case R.id.menu_advanced:
case R.id.menu_file_size:
+ case R.id.menu_new_window:
break;
default:
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.Shared.DEBUG;
import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkState;
import android.app.Activity;
import android.app.FragmentManager;
RootsFragment.show(getFragmentManager(), null);
if (!mState.restored) {
- Uri rootUri = getIntent().getData();
+ Intent intent = getIntent();
+ Uri rootUri = intent.getData();
// If we've got a specific root to display, restore that root using a dedicated
// authority. That way a misbehaving provider won't result in an ANR.
- if (rootUri != null) {
+ if (rootUri != null && !LauncherActivity.isLaunchUri(rootUri)) {
new RestoreRootTask(rootUri).executeOnExecutor(
ProviderExecutor.forAuthority(rootUri.getAuthority()));
} else {
}
// Show a failure dialog if there was a failed operation.
- final Intent intent = getIntent();
final DocumentStack dstStack = intent.getParcelableExtra(CopyService.EXTRA_STACK);
final int failure = intent.getIntExtra(CopyService.EXTRA_FAILURE, 0);
final int transferMode = intent.getIntExtra(CopyService.EXTRA_TRANSFER_MODE,
public boolean onPrepareOptionsMenu(Menu menu) {
boolean shown = super.onPrepareOptionsMenu(menu);
- final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
+ menu.findItem(R.id.menu_file_size).setVisible(true);
+ menu.findItem(R.id.menu_advanced).setVisible(true);
+
final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
+ final MenuItem newWindow = menu.findItem(R.id.menu_new_window);
+ final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
boolean canCreateDir = canCreateDirectory();
createDir.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
createDir.setVisible(canCreateDir);
+ createDir.setEnabled(canCreateDir);
+
+ newWindow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ newWindow.setVisible(mProductivityDevice);
+ newWindow.setEnabled(mProductivityDevice);
- pasteFromCb.setVisible(true);
pasteFromCb.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ pasteFromCb.setVisible(true);
pasteFromCb.setEnabled(mClipper.hasItemsToPaste());
return shown;
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- final int id = item.getItemId();
- if (id == R.id.menu_paste_from_clipboard) {
- DirectoryFragment dir = DirectoryFragment.get(getFragmentManager());
- dir = DirectoryFragment.get(getFragmentManager());
- dir.pasteFromClipboard();
- return true;
+ switch (item.getItemId()) {
+ case R.id.menu_create_dir:
+ checkState(canCreateDirectory());
+ showCreateDirectoryDialog();
+ return true;
+ case R.id.menu_new_window:
+ startActivity(LauncherActivity.createLaunchIntent(this));
+ return true;
+ case R.id.menu_paste_from_clipboard:
+ DirectoryFragment dir = DirectoryFragment.get(getFragmentManager());
+ dir = DirectoryFragment.get(getFragmentManager());
+ dir.pasteFromClipboard();
+ return true;
}
return super.onOptionsItemSelected(item);
dir = DirectoryFragment.get(getFragmentManager());
dir.selectAllFiles();
return true;
- case KeyEvent.KEYCODE_N:
- if (event.isShiftPressed() && canCreateDirectory()) {
- showCreateDirectoryDialog();
- return true;
- }
case KeyEvent.KEYCODE_C:
// TODO: Should be statically bound using alphabeticShortcut. See b/21330356.
dir = DirectoryFragment.get(getFragmentManager());
dir.copySelectedToClipboard();
- // TODO: Cancel action mode in directory fragment.
}
- return super.onKeyUp(keyCode, event);
+ return super.onKeyShortcut(keyCode, event);
}
@Override
--- /dev/null
+/*
+ * 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 android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityManager.AppTask;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Provides FilesActivity task grouping support. This allows multiple FilesActivities to be
+ * launched (a behavior imparted by way of {@code documentLaunchMode="intoExisting"} and
+ * our use of pseudo document {@link Uri}s. This also lets us move an existing task
+ * to the foreground when a suitable task exists.
+ *
+ * Requires that {@code documentLaunchMode="intoExisting"} be set on target activity.
+ *
+ */
+public class LauncherActivity extends Activity {
+
+ public static final String LAUNCH_CONTROL_AUTHORITY = "com.android.documentsui.launchControl";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActivityManager activities = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+ List<AppTask> tasks = activities.getAppTasks();
+
+ AppTask raiseTask = null;
+ for (AppTask task : tasks) {
+ Uri taskUri = task.getTaskInfo().baseIntent.getData();
+ if (taskUri != null && isLaunchUri(taskUri)) {
+ raiseTask = task;
+ }
+ }
+
+ if (raiseTask == null) {
+ launchFilesTask();
+ } else {
+ raiseFilesTask(activities, raiseTask.getTaskInfo());
+ }
+
+ finish();
+ }
+
+ private void launchFilesTask() {
+ Intent intent = createLaunchIntent(this);
+ startActivity(intent);
+ }
+
+ private void raiseFilesTask(ActivityManager activities, RecentTaskInfo task) {
+ activities.moveTaskToFront(task.id, 0);
+ }
+
+ static Intent createLaunchIntent(Context context) {
+ Intent intent = new Intent(context, FilesActivity.class);
+ intent.setData(buildLaunchUri());
+ return intent;
+ }
+
+ private static Uri buildLaunchUri() {
+ return new Uri.Builder()
+ .authority(LAUNCH_CONTROL_AUTHORITY)
+ .fragment(String.valueOf(System.currentTimeMillis()))
+ .build();
+ }
+
+ static boolean isLaunchUri(@Nullable Uri uri) {
+ return uri != null && LAUNCH_CONTROL_AUTHORITY.equals(uri.getAuthority());
+ }
+}
public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
public boolean allowMultiple;
- public boolean forceSize ;
+ public boolean forceSize;
public boolean showSize;
- public boolean localOnly ;
- public boolean forceAdvanced ;
- public boolean showAdvanced ;
- public boolean stackTouched ;
- public boolean restored ;
- public boolean directoryCopy ;
+ public boolean localOnly;
+ public boolean forceAdvanced;
+ public boolean showAdvanced;
+ public boolean stackTouched;
+ public boolean restored;
+ public boolean directoryCopy;
/** Transfer mode for file copy/move operations. */
public int transferMode;