• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.documentsui.inspector;
17 
18 import android.content.Context;
19 import android.content.res.Resources;
20 import android.os.AsyncTask;
21 import android.os.Bundle;
22 import android.provider.DocumentsContract;
23 import android.util.AttributeSet;
24 import android.widget.TextView;
25 
26 import androidx.annotation.StringRes;
27 
28 import com.android.documentsui.R;
29 import com.android.documentsui.base.DocumentInfo;
30 import com.android.documentsui.base.Lookup;
31 import com.android.documentsui.base.StubLookup;
32 import com.android.documentsui.inspector.InspectorController.DebugDisplay;
33 
34 import java.text.NumberFormat;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Collections;
38 import java.util.List;
39 import java.util.concurrent.Executor;
40 
41 /**
42  * Organizes and Displays the debug information about a file. This view
43  * should only be made visible when build is debuggable and system policies
44  * allow debug "stuff".
45  */
46 public class DebugView extends TableView implements DebugDisplay {
47 
48     private final Context mContext;
49     private final Resources mRes;
50     private Lookup<String, Executor> mExecutors = new StubLookup<>();
51 
DebugView(Context context)52     public DebugView(Context context) {
53         this(context, null);
54     }
55 
DebugView(Context context, AttributeSet attrs)56     public DebugView(Context context, AttributeSet attrs) {
57         this(context, attrs, 0);
58     }
59 
DebugView(Context context, AttributeSet attrs, int defStyleAttr)60     public DebugView(Context context, AttributeSet attrs, int defStyleAttr) {
61         super(context, attrs, defStyleAttr);
62         mContext = context;
63         mRes = context.getResources();
64     }
65 
init(Lookup<String, Executor> executors)66     void init(Lookup<String, Executor> executors) {
67         assert executors != null;
68         mExecutors = executors;
69     }
70 
71     @Override
accept(DocumentInfo info)72     public void accept(DocumentInfo info) {
73         setTitle(R.string.inspector_debug_section, true);
74 
75         put(R.string.debug_user_id, info.userId.toString());
76         put(R.string.debug_content_uri, info.derivedUri.toString());
77         put(R.string.debug_document_id, info.documentId);
78         put(R.string.debug_raw_mimetype, info.mimeType);
79         put(R.string.debug_stream_types, "-");
80         put(R.string.debug_raw_size, NumberFormat.getInstance().format(info.size));
81         put(R.string.debug_is_archive, info.isArchive());
82         put(R.string.debug_is_blocked_from_tree, info.isBlockedFromTree());
83         put(R.string.debug_is_container, info.isContainer());
84         put(R.string.debug_is_partial, info.isPartial());
85         put(R.string.debug_is_virtual, info.isVirtual());
86         put(R.string.debug_supports_create, info.isCreateSupported());
87         put(R.string.debug_supports_delete, info.isDeleteSupported());
88         put(R.string.debug_supports_metadata, info.isMetadataSupported());
89         put(R.string.debug_supports_move, info.isMoveSupported());
90         put(R.string.debug_supports_remove, info.isRemoveSupported());
91         put(R.string.debug_supports_rename, info.isRenameSupported());
92         put(R.string.debug_supports_settings, info.isSettingsSupported());
93         put(R.string.debug_supports_thumbnail, info.isThumbnailSupported());
94         put(R.string.debug_supports_weblink, info.isWeblinkSupported());
95         put(R.string.debug_supports_write, info.isWriteSupported());
96 
97         // Load Document stream types of the file. For virtual files, this should be
98         // something other than the primary type of the file.
99         Executor executor = mExecutors.lookup(info.derivedUri.getAuthority());
100         if (executor != null) {
101             new AsyncTask<Void, Void, String[]>() {
102                 @Override
103                 protected String[] doInBackground(Void... params) {
104                     return mContext.getContentResolver().getStreamTypes(info.derivedUri, "*/*");
105                 }
106 
107                 @Override
108                 protected void onPostExecute(String[] streamTypes) {
109                     put(R.string.debug_stream_types,
110                             streamTypes != null ? Arrays.toString(streamTypes) : "[]");
111                 }
112             }.executeOnExecutor(executor, (Void[]) null);
113         }
114     }
115 
116     @Override
accept(Bundle metadata)117     public void accept(Bundle metadata) {
118         if (metadata == null) {
119             return;
120         }
121 
122         String[] types = metadata.getStringArray(DocumentsContract.METADATA_TYPES);
123         if (types == null) {
124             return;
125         }
126 
127         for (String type : types) {
128             dumpMetadata(type, metadata.getBundle(type));
129         }
130     }
131 
dumpMetadata(String type, Bundle bundle)132     private void dumpMetadata(String type, Bundle bundle) {
133         String title = mContext.getResources().getString(
134                 R.string.inspector_debug_metadata_section);
135         putTitle(String.format(title, type), true);
136         List<String> keys = new ArrayList<>(bundle.keySet());
137         Collections.sort(keys);
138         for (String key : keys) {
139             put(key, String.valueOf(bundle.get(key)));
140         }
141     }
142 
put(@tringRes int key, boolean value)143     private void put(@StringRes int key, boolean value) {
144         KeyValueRow row = put(mRes.getString(key), String.valueOf(value));
145         TextView valueView = ((TextView) row.findViewById(R.id.table_row_value));
146         valueView.setTextColor(value ? 0xFF006400 : 0xFF9A2020);
147     }
148 }
149