diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/SambaProviderApplication.java b/app/src/main/java/com/google/android/sambadocumentsprovider/SambaProviderApplication.java
index 74294fe..3ad1a44 100644
--- a/app/src/main/java/com/google/android/sambadocumentsprovider/SambaProviderApplication.java
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/SambaProviderApplication.java
@@ -27,6 +27,7 @@ import android.net.NetworkRequest;
import android.util.Log;
import com.google.android.sambadocumentsprovider.SambaConfiguration.OnConfigurationChangedListener;
+import com.google.android.sambadocumentsprovider.browsing.NetworkBrowser;
import com.google.android.sambadocumentsprovider.cache.DocumentCache;
import com.google.android.sambadocumentsprovider.nativefacade.CredentialCache;
import com.google.android.sambadocumentsprovider.nativefacade.SambaMessageLooper;
@@ -42,6 +43,7 @@ public class SambaProviderApplication extends Application {
private SmbFacade mSambaClient;
private ShareManager mShareManager;
+ private NetworkBrowser mNetworkBrowser;
@Override
public void onCreate() {
@@ -64,6 +66,8 @@ public class SambaProviderApplication extends Application {
mShareManager = new ShareManager(context, credentialCache);
+ mNetworkBrowser = new NetworkBrowser(mSambaClient, mTaskManager);
+
registerNetworkCallback(context);
}
@@ -129,6 +133,10 @@ public class SambaProviderApplication extends Application {
return getApplication(context).mTaskManager;
}
+ public static NetworkBrowser getNetworkBrowser(Context context) {
+ return getApplication(context).mNetworkBrowser;
+ }
+
private static SambaProviderApplication getApplication(Context context) {
return ((SambaProviderApplication) context.getApplicationContext());
}
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/TaskManager.java b/app/src/main/java/com/google/android/sambadocumentsprovider/TaskManager.java
index e53176e..4963627 100644
--- a/app/src/main/java/com/google/android/sambadocumentsprovider/TaskManager.java
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/TaskManager.java
@@ -21,8 +21,6 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.util.Log;
-import com.google.android.sambadocumentsprovider.provider.ReadFileTask;
-import com.google.android.sambadocumentsprovider.provider.WriteFileTask;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/base/DirectoryEntry.java b/app/src/main/java/com/google/android/sambadocumentsprovider/base/DirectoryEntry.java
index 5c0b03a..f30ea6d 100644
--- a/app/src/main/java/com/google/android/sambadocumentsprovider/base/DirectoryEntry.java
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/base/DirectoryEntry.java
@@ -29,7 +29,7 @@ public class DirectoryEntry {
@IntDef({WORKGROUP, SERVER, FILE_SHARE, PRINTER_SHARE, COMMS_SHARE, IPC_SHARE, DIR, FILE, LINK})
@Retention(RetentionPolicy.SOURCE)
- @interface Type {}
+ public @interface Type {}
public static final int WORKGROUP = 1;
public static final int SERVER = 2;
public static final int FILE_SHARE = 3;
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/BrowsingException.java b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/BrowsingException.java
new file mode 100644
index 0000000..8fb304b
--- /dev/null
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/BrowsingException.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.google.android.sambadocumentsprovider.browsing;
+
+class BrowsingException extends Exception {
+ BrowsingException(String message) {
+ super("Browsing failed: " + message);
+ }
+}
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/MasterBrowsingProvider.java b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/MasterBrowsingProvider.java
new file mode 100644
index 0000000..d6cc630
--- /dev/null
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/MasterBrowsingProvider.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.google.android.sambadocumentsprovider.browsing;
+
+import com.google.android.sambadocumentsprovider.base.DirectoryEntry;
+import com.google.android.sambadocumentsprovider.nativefacade.SmbClient;
+import com.google.android.sambadocumentsprovider.nativefacade.SmbDir;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+class MasterBrowsingProvider implements NetworkBrowsingProvider {
+ private static final String MASTER_BROWSING_DIR = "smb://";
+
+ private final SmbClient mClient;
+
+ MasterBrowsingProvider(SmbClient client) {
+ mClient = client;
+ }
+
+ @Override
+ public List getServers() throws BrowsingException {
+ List serversList = new ArrayList<>();
+
+ try {
+ SmbDir rootDir = mClient.openDir(MASTER_BROWSING_DIR);
+
+ List workgroups = getDirectoryChildren(rootDir);
+ for (DirectoryEntry workgroup : workgroups) {
+ if (workgroup.getType() == DirectoryEntry.WORKGROUP) {
+ List servers = getDirectoryChildren
+ (mClient.openDir(MASTER_BROWSING_DIR + workgroup.getName()));
+
+ for (DirectoryEntry server : servers) {
+ if (server.getType() == DirectoryEntry.SERVER) {
+ serversList.add(server.getName());
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new BrowsingException(e.getMessage());
+ }
+
+ return serversList;
+ }
+
+ private static List getDirectoryChildren(SmbDir dir) throws IOException {
+ List children = new ArrayList<>();
+
+ DirectoryEntry currentEntry;
+ while ((currentEntry = dir.readDir()) != null) {
+ children.add(currentEntry);
+ }
+
+ return children;
+ }
+}
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/NetworkBrowser.java b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/NetworkBrowser.java
new file mode 100644
index 0000000..0083eeb
--- /dev/null
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/NetworkBrowser.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.google.android.sambadocumentsprovider.browsing;
+
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import com.google.android.sambadocumentsprovider.TaskManager;
+import com.google.android.sambadocumentsprovider.base.DirectoryEntry;
+import com.google.android.sambadocumentsprovider.base.OnTaskFinishedCallback;
+import com.google.android.sambadocumentsprovider.nativefacade.SmbClient;
+import com.google.android.sambadocumentsprovider.nativefacade.SmbDir;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+public class NetworkBrowser {
+ public static final Uri SMB_BROWSING_URI = Uri.parse("smb://");
+
+ private static final String TAG = "NetworkBrowser";
+
+ private final NetworkBrowsingProvider mMasterProvider;
+ private final TaskManager mTaskManager;
+
+ private final Map mTasks = new HashMap<>();
+
+ public NetworkBrowser(SmbClient client, TaskManager taskManager) {
+ mMasterProvider = new MasterBrowsingProvider(client);
+ mTaskManager = taskManager;
+ }
+
+ public AsyncTask getServersAsync(OnTaskFinishedCallback> callback) {
+ AsyncTask> loadServersTask = new LoadServersTask(callback);
+
+ mTaskManager.runTask(SMB_BROWSING_URI, loadServersTask);
+
+ return loadServersTask;
+ }
+
+ private List getServers() throws BrowsingException {
+ return mMasterProvider.getServers();
+ }
+
+ private class LoadServersTask extends AsyncTask> {
+ final OnTaskFinishedCallback> mCallback;
+
+ private BrowsingException mException;
+
+ LoadServersTask(OnTaskFinishedCallback> callback) {
+ mCallback = callback;
+ }
+
+ List loadData() throws BrowsingException {
+ return getServers();
+ }
+
+ @Override
+ protected List doInBackground(Void... voids) {
+ try {
+ return loadData();
+ } catch (BrowsingException e) {
+ Log.e(TAG, "Failed to load data for network browsing: ", e);
+ mException = e;
+ return null;
+ }
+ }
+
+ protected void onPostExecute(List servers) {
+ if (servers != null) {
+ mCallback.onTaskFinished(OnTaskFinishedCallback.SUCCEEDED, servers, null);
+ } else {
+ mCallback.onTaskFinished(OnTaskFinishedCallback.FAILED, null, mException);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/NetworkBrowsingProvider.java b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/NetworkBrowsingProvider.java
new file mode 100644
index 0000000..9aee90a
--- /dev/null
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/browsing/NetworkBrowsingProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.google.android.sambadocumentsprovider.browsing;
+
+import java.util.List;
+
+interface NetworkBrowsingProvider {
+ /**
+ * Returns unresolved host names.
+ */
+ List getServers() throws BrowsingException;
+}
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/document/DocumentMetadata.java b/app/src/main/java/com/google/android/sambadocumentsprovider/document/DocumentMetadata.java
index 81c6f39..5ee55f3 100644
--- a/app/src/main/java/com/google/android/sambadocumentsprovider/document/DocumentMetadata.java
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/document/DocumentMetadata.java
@@ -25,6 +25,8 @@ import android.system.StructStat;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
+
+import com.google.android.sambadocumentsprovider.R;
import com.google.android.sambadocumentsprovider.base.DirectoryEntry;
import com.google.android.sambadocumentsprovider.nativefacade.SmbClient;
import com.google.android.sambadocumentsprovider.nativefacade.SmbDir;
@@ -32,7 +34,6 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -74,6 +75,18 @@ public class DocumentMetadata {
return mEntry.getType() == DirectoryEntry.FILE_SHARE;
}
+ public Integer getIconResourceId() {
+ switch (mEntry.getType()) {
+ case DirectoryEntry.SERVER:
+ return R.drawable.ic_server;
+ case DirectoryEntry.FILE_SHARE:
+ return R.drawable.ic_folder_shared;
+ default:
+ // Tells SAF to use the default icon.
+ return null;
+ }
+ }
+
public Long getLastModified() {
final StructStat stat = mStat.get();
return (stat == null) ? null : TimeUnit.MILLISECONDS.convert(stat.st_mtime, TimeUnit.SECONDS);
@@ -293,6 +306,10 @@ public class DocumentMetadata {
return builder.build();
}
+ public static boolean isServerUri(Uri uri) {
+ return uri.getPathSegments().isEmpty() && !uri.getAuthority().isEmpty();
+ }
+
public static DocumentMetadata fromUri(Uri uri, SmbClient client) throws IOException {
final List pathSegments = uri.getPathSegments();
if (pathSegments.isEmpty()) {
@@ -315,9 +332,17 @@ public class DocumentMetadata {
return createShare(uri);
}
+ public static DocumentMetadata createServer(Uri uri) {
+ return create(uri, DirectoryEntry.SERVER);
+ }
+
public static DocumentMetadata createShare(Uri uri) {
+ return create(uri, DirectoryEntry.FILE_SHARE);
+ }
+
+ private static DocumentMetadata create(Uri uri, @DirectoryEntry.Type int type) {
final DirectoryEntry entry =
- new DirectoryEntry(DirectoryEntry.FILE_SHARE, "", uri.getLastPathSegment());
+ new DirectoryEntry(type, "", uri.getLastPathSegment());
return new DocumentMetadata(uri, entry);
}
}
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/mount/MountServerActivity.java b/app/src/main/java/com/google/android/sambadocumentsprovider/mount/MountServerActivity.java
index 1b692f6..bf0ae0e 100644
--- a/app/src/main/java/com/google/android/sambadocumentsprovider/mount/MountServerActivity.java
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/mount/MountServerActivity.java
@@ -56,6 +56,7 @@ import com.google.android.sambadocumentsprovider.cache.DocumentCache;
import com.google.android.sambadocumentsprovider.document.DocumentMetadata;
import com.google.android.sambadocumentsprovider.nativefacade.SmbClient;
import com.google.android.sambadocumentsprovider.provider.SambaDocumentsProvider;
+
import java.util.List;
public class MountServerActivity extends AppCompatActivity {
diff --git a/app/src/main/java/com/google/android/sambadocumentsprovider/provider/SambaDocumentsProvider.java b/app/src/main/java/com/google/android/sambadocumentsprovider/provider/SambaDocumentsProvider.java
index 3713690..787b143 100644
--- a/app/src/main/java/com/google/android/sambadocumentsprovider/provider/SambaDocumentsProvider.java
+++ b/app/src/main/java/com/google/android/sambadocumentsprovider/provider/SambaDocumentsProvider.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -48,6 +49,7 @@ import com.google.android.sambadocumentsprovider.TaskManager;
import com.google.android.sambadocumentsprovider.base.AuthFailedException;
import com.google.android.sambadocumentsprovider.base.DirectoryEntry;
import com.google.android.sambadocumentsprovider.base.DocumentCursor;
+import com.google.android.sambadocumentsprovider.browsing.NetworkBrowser;
import com.google.android.sambadocumentsprovider.cache.CacheResult;
import com.google.android.sambadocumentsprovider.cache.DocumentCache;
import com.google.android.sambadocumentsprovider.document.DocumentMetadata;
@@ -55,12 +57,11 @@ import com.google.android.sambadocumentsprovider.document.LoadChildrenTask;
import com.google.android.sambadocumentsprovider.base.OnTaskFinishedCallback;
import com.google.android.sambadocumentsprovider.document.LoadDocumentTask;
import com.google.android.sambadocumentsprovider.document.LoadStatTask;
-import com.google.android.sambadocumentsprovider.nativefacade.SmbClient;
import com.google.android.sambadocumentsprovider.nativefacade.SmbFacade;
-import com.google.android.sambadocumentsprovider.nativefacade.SmbFile;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -87,7 +88,8 @@ public class SambaDocumentsProvider extends DocumentsProvider {
Document.COLUMN_FLAGS,
Document.COLUMN_MIME_TYPE,
Document.COLUMN_SIZE,
- Document.COLUMN_LAST_MODIFIED
+ Document.COLUMN_LAST_MODIFIED,
+ Document.COLUMN_ICON
};
private final OnTaskFinishedCallback mLoadDocumentCallback =
@@ -127,6 +129,22 @@ public class SambaDocumentsProvider extends DocumentsProvider {
}
};
+ private final OnTaskFinishedCallback> mLoadSharesFinishedCallback =
+ new OnTaskFinishedCallback>() {
+ @Override
+ public void onTaskFinished(
+ @OnTaskFinishedCallback.Status int status,
+ @Nullable List item,
+ @Nullable Exception exception) {
+ if (BuildConfig.DEBUG) Log.d(TAG, "Browsing callback");
+
+ mBrowsingStorage = item;
+
+ getContext().getContentResolver().notifyChange(
+ toNotifyUri(toUri(NetworkBrowser.SMB_BROWSING_URI.toString())), null, false);
+ }
+ };
+
private final MountedShareChangeListener mShareChangeListener = new MountedShareChangeListener() {
@Override
public void onMountedServerChange() {
@@ -142,6 +160,9 @@ public class SambaDocumentsProvider extends DocumentsProvider {
private DocumentCache mCache;
private TaskManager mTaskManager;
private StorageManager mStorageManager;
+ private NetworkBrowser mNetworkBrowser;
+
+ private List mBrowsingStorage = new ArrayList<>();
@Override
public boolean onCreate() {
@@ -155,6 +176,7 @@ public class SambaDocumentsProvider extends DocumentsProvider {
mShareManager = SambaProviderApplication.getServerManager(context);
mShareManager.addListener(mShareChangeListener);
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+ mNetworkBrowser = SambaProviderApplication.getNetworkBrowser(context);
return mClient != null;
}
@@ -165,6 +187,15 @@ public class SambaDocumentsProvider extends DocumentsProvider {
projection = (projection == null) ? DEFAULT_ROOT_PROJECTION : projection;
MatrixCursor cursor = new MatrixCursor(projection, mShareManager.size());
+
+ cursor.addRow(new Object[] {
+ NetworkBrowser.SMB_BROWSING_URI.toString(),
+ NetworkBrowser.SMB_BROWSING_URI.toString(),
+ getContext().getResources().getString(R.string.browsing_root_name),
+ 0,
+ R.drawable.ic_cloud,
+ });
+
for (String uri : mShareManager) {
final String name;
final Uri parsedUri = Uri.parse(uri);
@@ -204,7 +235,15 @@ public class SambaDocumentsProvider extends DocumentsProvider {
if (BuildConfig.DEBUG) Log.d(TAG, "Querying document: " + documentId);
projection = (projection == null) ? DEFAULT_DOCUMENT_PROJECTION : projection;
+ final MatrixCursor cursor = new MatrixCursor(projection);
final Uri uri = toUri(documentId);
+
+ if (documentId.equals(NetworkBrowser.SMB_BROWSING_URI.toString())) {
+ cursor.addRow(getCursorRowForBrowsingRoot(projection));
+
+ return cursor;
+ }
+
try {
try (CacheResult result = mCache.get(uri)) {
@@ -221,7 +260,6 @@ public class SambaDocumentsProvider extends DocumentsProvider {
metadata = result.getItem();
}
- final MatrixCursor cursor = new MatrixCursor(projection);
cursor.addRow(getDocumentValues(projection, metadata));
return cursor;
@@ -239,13 +277,27 @@ public class SambaDocumentsProvider extends DocumentsProvider {
if (BuildConfig.DEBUG) Log.d(TAG, "Querying children documents under " + documentId);
projection = (projection == null) ? DEFAULT_DOCUMENT_PROJECTION : projection;
+ if (documentId.equals(NetworkBrowser.SMB_BROWSING_URI.toString())) {
+ return getFilesSharesCursor(projection);
+ }
+
final Uri uri = toUri(documentId);
+
try {
+ if (DocumentMetadata.isServerUri(uri)) {
+ try (final CacheResult result = mCache.get(uri)) {
+ if (result.getState() == CacheResult.CACHE_MISS) {
+ DocumentMetadata metadata = DocumentMetadata.createServer(uri);
+ mCache.put(metadata);
+ }
+ }
+ }
+
try (final CacheResult result = mCache.get(uri)) {
boolean isLoading = false;
- final DocumentCursor cursor = new DocumentCursor(projection);
final Bundle extra = new Bundle();
final Uri notifyUri = toNotifyUri(uri);
+ final DocumentCursor cursor = new DocumentCursor(projection);
if (result.getState() == CacheResult.CACHE_MISS) {
// Last loading failed... Just feed the bitter fruit.
@@ -359,11 +411,76 @@ public class SambaDocumentsProvider extends DocumentsProvider {
case Document.COLUMN_LAST_MODIFIED:
row[i] = metadata.getLastModified();
break;
+ case Document.COLUMN_ICON:
+ row[i] = metadata.getIconResourceId();
+ break;
}
}
return row;
}
+ private Object[] getCursorRowForServer(
+ String[] projection,
+ String server) {
+ Object[] row = new Object[projection.length];
+
+ for (int i = 0; i < projection.length; ++i) {
+ switch (projection[i]) {
+ case Document.COLUMN_DOCUMENT_ID:
+ row[i] = NetworkBrowser.SMB_BROWSING_URI.toString() + server;
+ break;
+ case Document.COLUMN_DISPLAY_NAME:
+ row[i] = server.isEmpty()
+ ? getContext().getResources().getString(R.string.browsing_root_name) : server;
+ break;
+ case Document.COLUMN_FLAGS:
+ row[i] = 0;
+ break;
+ case Document.COLUMN_MIME_TYPE:
+ row[i] = Document.MIME_TYPE_DIR;
+ break;
+ case Document.COLUMN_SIZE:
+ case Document.COLUMN_LAST_MODIFIED:
+ row[i] = null;
+ break;
+ case Document.COLUMN_ICON:
+ row[i] = R.drawable.ic_server;
+ break;
+ }
+ }
+
+ return row;
+ }
+
+ private Object[] getCursorRowForBrowsingRoot(String[] projection) {
+ return getCursorRowForServer(projection, "");
+ }
+
+ private Cursor getFilesSharesCursor(String[] projection) {
+ final DocumentCursor cursor = new DocumentCursor(projection);
+
+ final Uri uri = toUri(NetworkBrowser.SMB_BROWSING_URI.toString());
+
+ if (mBrowsingStorage.isEmpty()) {
+ AsyncTask serversTask = mNetworkBrowser.getServersAsync(mLoadSharesFinishedCallback);
+
+ Bundle extra = new Bundle();
+ extra.putBoolean(DocumentsContract.EXTRA_LOADING, true);
+
+ cursor.setNotificationUri(getContext().getContentResolver(), toNotifyUri(uri));
+ cursor.setExtras(extra);
+ cursor.setLoadingTask(serversTask);
+ } else {
+ for (String server : mBrowsingStorage) {
+ cursor.addRow(getCursorRowForServer(projection, server));
+ }
+
+ mBrowsingStorage.clear();
+ }
+
+ return cursor;
+ }
+
@Override
public String createDocument(String parentDocumentId, String mimeType, String displayName)
throws FileNotFoundException {
diff --git a/app/src/main/res/drawable/ic_cloud.xml b/app/src/main/res/drawable/ic_cloud.xml
new file mode 100644
index 0000000..e7a8fed
--- /dev/null
+++ b/app/src/main/res/drawable/ic_cloud.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_server.xml b/app/src/main/res/drawable/ic_server.xml
new file mode 100644
index 0000000..19c8638
--- /dev/null
+++ b/app/src/main/res/drawable/ic_server.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8ff2367..df3fedd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -47,4 +47,6 @@
Send feedback
It needs a web browser to send feedback.
+
+ Samba Shares