Skip to content

Commit

Permalink
Merge branch 'release/1.5.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
janseeger committed Jan 14, 2015
2 parents be81c00 + 66d7233 commit 1fb2231
Show file tree
Hide file tree
Showing 53 changed files with 169 additions and 110 deletions.
25 changes: 9 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
language: java
jdk: openjdk7
before_install:
# Install base Android SDK
- sudo apt-get update -qq
- if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm lib32z1 lib32stdc++6; fi
- wget http://dl.google.com/android/android-sdk_r23-linux.tgz
- tar xzf android-sdk_r23-linux.tgz
- export ANDROID_HOME=$PWD/android-sdk-linux
- export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
language: android
android:
components:
- platform-tools
- tools
- build-tools-19.1.0
- android-19
- extra-android-support
- extra-android-m2repository

# Install required Android components.
#- echo "y" | android update sdk -a --filter build-tools-19.1.0,android-19,platform-tools,extra-android-support,extra-android-m2repository --no-ui --force
- ( sleep 5 && while [ 1 ]; do sleep 1; echo y; done ) | android update sdk --no-ui --all --force --filter build-tools-21.1.1,android-21,platform-tools,extra-android-support,extra-android-m2repository

install: echo "Installation done"
script:
- ./gradlew assemble -S -q
- ./gradlew --info test
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

[![Build Status](https://travis-ci.org/alphadev-net/drive-mount.svg?branch=dev)](https://travis-ci.org/alphadev-net/drive-mount)

This app aims to provide access to USB Mass Storage devices on Android devices without requiring root permissions.
This app provides access to USB Mass Storage devices on Android devices **without requiring root permissions**.

![SAF UsbDocProvider](https://cloud.githubusercontent.com/assets/1467318/5219580/0696d7ac-765a-11e4-9cfe-a53727d4323e.png)

This is achieved in pure Java, which trades performance for portability. *Better slow access, than having no access at all.*
This is achieved in pure Java, which trades performance for portability.

## Requirements

Expand All @@ -18,7 +18,7 @@ This is achieved in pure Java, which trades performance for portability. *Better

## Roadmap

For now it is planned to support common USB drive file formats like FAT32 and NTFS. However I'd like to support HFS and Linux file systems, sometime.
At the moment, I have planned to support common USB drive file formats like FAT32 and NTFS. However I'd like to support HFS+ and Linux filesystems, sometime.

Please refer to the [Milestones](https://github.com/alphaDev-net/drive-mount/milestones) for a more detailed look ahead.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* Copyright © 2014-2015 Jan Seeger
*
* 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 net.alphadev.usbstorage.api.filesystem;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,6 @@
package net.alphadev.usbstorage.api.filesystem;

import net.alphadev.usbstorage.api.Identifiable;
import net.alphadev.usbstorage.api.filesystem.FileSystemProvider;

import java.io.Closeable;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ android {
applicationId "net.alphadev.usbstorage"
minSdkVersion 19
targetSdkVersion 21
versionCode 4
versionName "1.5.1"
versionCode 6
versionName "1.5.2"
}

compileOptions {
Expand Down
15 changes: 5 additions & 10 deletions app/src/main/java/net/alphadev/usbstorage/DeviceManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,7 +27,6 @@

public final class DeviceManager {
private static final String ACTION_USB_PERMISSION = "net.alphadev.usbstorage.ACTION_USB_PERMISSION";
private static final String LOG_TAG = "Drive Mount";
private final UsbManager mUsbManager;
private final Context mContext;
private final StorageManager mStorageManager;
Expand Down Expand Up @@ -73,20 +72,16 @@ public void onReceive(Context context, Intent intent) {
private void unmountRemovedDevices(UsbDevice device) {
String deviceId = Integer.valueOf(device.getDeviceId()).toString();
mStorageManager.unmount(deviceId);
notifyStorageChanged();
mStorageManager.notifyStorageChanged();
}

private void tryMount(UsbDevice device) {
BulkDevice usbBulkDevice = new UsbBulkDevice(mContext, device);
if (mStorageManager.tryMount(usbBulkDevice)) {
notifyStorageChanged();
final BulkDevice usbBulkDevice = UsbBulkDevice.read(mContext, device);
if (usbBulkDevice != null && mStorageManager.tryMount(usbBulkDevice)) {
mStorageManager.notifyStorageChanged();
}
}

private void notifyStorageChanged() {
mStorageManager.notifyStorageChanged();
}

private void enumerateDevices() {
for (UsbDevice device : mUsbManager.getDeviceList().values()) {
if (!mUsbManager.hasPermission(device)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/net/alphadev/usbstorage/StorageManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -108,25 +108,25 @@ private void postStorageNotification(StorageDevice device) {
device.getType());
final String unmountInfo = mContext.getString(R.string.notification_subtext);

Notification.Builder notification = new Notification.Builder(mContext)
Notification.Builder builder = new Notification.Builder(mContext)
.setContentTitle(deviceName)
.setContentText(deviceInfo)
.setSubText(unmountInfo)
.setSmallIcon(R.drawable.drive_icon_gen)
.setOngoing(true);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
notification.setLocalOnly(true)
builder.setLocalOnly(true)
.setGroup(AUTHORITY);
}

final Intent intent = new Intent(ACTION_UNMOUNT_DEVICE);
intent.putExtra("deviceId", device.getId());

notification.setContentIntent(
builder.setContentIntent(
PendingIntent.getBroadcast(mContext, 0, intent, 0));

mNotificationManager.notify(device.getId(), 0, notification.build());
mNotificationManager.notify(device.getId(), 0, builder.build());
}

private StorageDevice firstTry(Partition device) {
Expand Down Expand Up @@ -163,7 +163,7 @@ public StorageDevice getDevice(Path path) {
}

public void unmount(String deviceId) {
for (Map.Entry<String, StorageDevice> set: mMountedDevices.entrySet()) {
for (Map.Entry<String, StorageDevice> set : mMountedDevices.entrySet()) {
if (set.getKey().startsWith(deviceId)) {
try {
set.getValue().close();
Expand Down
76 changes: 51 additions & 25 deletions app/src/main/java/net/alphadev/usbstorage/UsbBulkDevice.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2014 Jan Seeger
* Copyright © 2014-2015 Jan Seeger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -43,54 +43,80 @@ public class UsbBulkDevice implements BulkDevice {
private int mDeviceId;
private boolean closed;

public UsbBulkDevice(Context ctx, UsbDevice device) {
final UsbManager manager = (UsbManager) ctx.getSystemService(Context.USB_SERVICE);
private UsbBulkDevice(UsbDevice device, UsbDeviceConnection connection,
UsbInterface dataInterface, UsbEndpoint in, UsbEndpoint out) {
mDeviceId = device.getDeviceId();
mConnection = connection;
mDataInterface = dataInterface;
mReadEndpoint = in;
mWriteEndpoint = out;
closed = false;
}

public static UsbBulkDevice read(Context ctx, UsbDevice device) {
final UsbManager manager = (UsbManager) ctx.getSystemService(Context.USB_SERVICE);
if (!manager.hasPermission(device)) {
throw new IllegalStateException("You don't have the permission to access this device!");
return null;
}

mDeviceId = device.getDeviceId();
findUsableInterface(device);
findUsableEndpoints();
openAndLockDevice(device, manager);
final UsbInterface dataInterface = findUsableInterface(device);
if (dataInterface == null) {
return null;
}

final UsbEndpoint in = findUsableEndpoints(dataInterface, UsbConstants.USB_DIR_IN);
if (in == null) {
return null;
}

final UsbEndpoint out = findUsableEndpoints(dataInterface, UsbConstants.USB_DIR_OUT);
if (out == null) {
return null;
}

final UsbDeviceConnection connection = openAndLockDevice(manager, device, dataInterface);
if (connection == null) {
return null;
}

return new UsbBulkDevice(device, connection, dataInterface, in, out);
}

private void openAndLockDevice(UsbDevice device, UsbManager manager) {
mConnection = manager.openDevice(device);
if (mConnection.claimInterface(mDataInterface, true)) {
closed = false;
private static UsbDeviceConnection openAndLockDevice(UsbManager manager, UsbDevice device, UsbInterface dataInterface) {
final UsbDeviceConnection connection = manager.openDevice(device);
if (connection.claimInterface(dataInterface, true)) {
return connection;
}

return null;
}

private void findUsableEndpoints() {
for (int i = 0; i < mDataInterface.getEndpointCount(); i++) {
UsbEndpoint endpointProbe = mDataInterface.getEndpoint(i);
private static UsbEndpoint findUsableEndpoints(UsbInterface usbInterface, int direction) {
for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
UsbEndpoint endpointProbe = usbInterface.getEndpoint(i);
if (endpointProbe.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (endpointProbe.getDirection() == UsbConstants.USB_DIR_IN) {
mReadEndpoint = endpointProbe;
} else {
mWriteEndpoint = endpointProbe;
if (endpointProbe.getDirection() == direction) {
return endpointProbe;
}
}
}

return null;
}

private void findUsableInterface(UsbDevice device) {
private static UsbInterface findUsableInterface(UsbDevice device) {
for (int i = 0; i < device.getInterfaceCount(); i++) {
UsbInterface interfaceProbe = device.getInterface(i);
if (interfaceProbe.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE) {
if (interfaceProbe.getInterfaceSubclass() == 0x6) {
if (interfaceProbe.getInterfaceProtocol() == 0x50) {
mDataInterface = device.getInterface(i);
} else {
throw new UnsupportedOperationException("Cannot talk to this USB device!");
return device.getInterface(i);
}
} else {
throw new UnsupportedOperationException("Cannot talk to this USB device!");
}
}
}

return null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* Copyright © unknown year Mark Murphy
* 2014-2015 Jan Seeger
*
* 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 net.alphadev.usbstorage.util;

import android.os.ParcelFileDescriptor;
Expand Down
Loading

0 comments on commit 1fb2231

Please sign in to comment.