17d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan/* 27d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * Copyright (C) 2016 The Android Open Source Project 37d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * 47d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * Licensed under the Apache License, Version 2.0 (the "License"); 57d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * you may not use this file except in compliance with the License. 67d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * You may obtain a copy of the License at 77d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * 87d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * http://www.apache.org/licenses/LICENSE-2.0 97d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * 107d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * Unless required by applicable law or agreed to in writing, software 117d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * distributed under the License is distributed on an "AS IS" BASIS, 127d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * See the License for the specific language governing permissions and 147d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * limitations under the License. 157d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan */ 167d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 177d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanpackage com.android.documentsui.sidebar; 187d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 198e9125847b29bbb436108c3bfda50a0018c48796Ben Linimport android.annotation.Nullable; 207d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.content.Context; 217d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.provider.DocumentsProvider; 227d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.text.TextUtils; 237d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.text.format.Formatter; 24174fc2e99583c863287eb1f3bcaefd66565f4392Ben Linimport android.view.DragEvent; 257d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.view.Menu; 267d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.view.MenuInflater; 277d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.view.View; 287d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.view.View.OnClickListener; 297d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.widget.ImageView; 307d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport android.widget.TextView; 317d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 32b285b40dedbde396aea8080c3d09577677bc71bcGarfield Tanimport com.android.documentsui.ActionHandler; 337d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport com.android.documentsui.MenuManager; 347d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport com.android.documentsui.R; 358e9125847b29bbb436108c3bfda50a0018c48796Ben Linimport com.android.documentsui.base.DocumentInfo; 367d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanimport com.android.documentsui.base.RootInfo; 377d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 387d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan/** 397d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan * An {@link Item} for each root provided by {@link DocumentsProvider}s. 407d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan */ 417d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tanclass RootItem extends Item { 427d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan private static final String STRING_ID_FORMAT = "RootItem{%s/%s}"; 437d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 447d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan public final RootInfo root; 458e9125847b29bbb436108c3bfda50a0018c48796Ben Lin public @Nullable DocumentInfo docInfo; 467d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 47739f94ba0dc9be264d9596dac551fd63082d2fddSteve McKay private final ActionHandler mActionHandler; 487d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 49739f94ba0dc9be264d9596dac551fd63082d2fddSteve McKay public RootItem(RootInfo root, ActionHandler actionHandler) { 507d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan super(R.layout.item_root, getStringId(root)); 517d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan this.root = root; 527d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan mActionHandler = actionHandler; 537d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 547d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 557d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan private static String getStringId(RootInfo root) { 567d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan // Empty URI authority is invalid, so we can use empty string if root.authority is null. 577d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan // Directly passing null to String.format() will write "null" which can be a valid URI 587d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan // authority. 597d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan String authority = (root.authority == null ? "" : root.authority); 607d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan return String.format(STRING_ID_FORMAT, authority, root.rootId); 617d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 627d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 637d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan @Override 647d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan public void bindView(View convertView) { 657d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 667d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan final TextView title = (TextView) convertView.findViewById(android.R.id.title); 677d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 687d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan final ImageView ejectIcon = (ImageView) convertView.findViewById(R.id.eject_icon); 697d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 707d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan final Context context = convertView.getContext(); 717d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan icon.setImageDrawable(root.loadDrawerIcon(context)); 727d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan title.setText(root.title); 737d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 747d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan if (root.supportsEject()) { 757d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan ejectIcon.setVisibility(View.VISIBLE); 767d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan ejectIcon.setImageDrawable(root.loadEjectIcon(context)); 777d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan ejectIcon.setOnClickListener(new OnClickListener() { 787d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan @Override 797d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan public void onClick(View unmountIcon) { 807d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan RootsFragment.ejectClicked(unmountIcon, root, mActionHandler); 817d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 827d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan }); 837d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } else { 847d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan ejectIcon.setVisibility(View.GONE); 857d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan ejectIcon.setOnClickListener(null); 867d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 877d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan // Show available space if no summary 887d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan String summaryText = root.summary; 897d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan if (TextUtils.isEmpty(summaryText) && root.availableBytes >= 0) { 907d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan summaryText = context.getString(R.string.root_available_bytes, 917d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan Formatter.formatFileSize(context, root.availableBytes)); 927d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 937d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 947d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan summary.setText(summaryText); 957d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE); 967d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 977d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 987d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan @Override 990f7e5878cc33d857170c0bb867628f73d37c4c5dGarfield Tan boolean isRoot() { 100d6a85b92c529d30cb17132f1fa9742b119b3713eBen Lin return true; 1017d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 1027d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 1037d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan @Override 1047d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan void open() { 1056d20d190bc576bea1da48f79d868a5f383d3458bSteve McKay mActionHandler.openRoot(root); 1067d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 1077d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 1087d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan @Override 1090f7e5878cc33d857170c0bb867628f73d37c4c5dGarfield Tan boolean isDropTarget() { 1100f7e5878cc33d857170c0bb867628f73d37c4c5dGarfield Tan return root.supportsCreate(); 1110f7e5878cc33d857170c0bb867628f73d37c4c5dGarfield Tan } 1120f7e5878cc33d857170c0bb867628f73d37c4c5dGarfield Tan 1130f7e5878cc33d857170c0bb867628f73d37c4c5dGarfield Tan @Override 114174fc2e99583c863287eb1f3bcaefd66565f4392Ben Lin boolean dropOn(DragEvent event) { 115174fc2e99583c863287eb1f3bcaefd66565f4392Ben Lin return mActionHandler.dropOn(event, root); 1167d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 1177d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan 1187d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan @Override 1197d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan void createContextMenu(Menu menu, MenuInflater inflater, MenuManager menuManager) { 1207d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan inflater.inflate(R.menu.root_context_menu, menu); 1218e9125847b29bbb436108c3bfda50a0018c48796Ben Lin menuManager.updateRootContextMenu(menu, root, docInfo); 1227d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan } 12398d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay 12498d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay @Override 12598d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay public String toString() { 12698d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay return "RootItem{" 12798d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay + "id=" + stringId 12898d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay + ", root=" + root 12998d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay + ", docInfo=" + docInfo 13098d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay + "}"; 13198d558ea602bdf3388b9f425ce946a7cbe11c2ccSteve McKay } 1327d75f7bbd1693a33abb8de6b472ec1950e33eb8bGarfield Tan} 133