Android Open Source - remoteyourcam-usb Ptp Camera






From Project

Back to project page remoteyourcam-usb.

License

The source code is released under:

Apache License

If you think the Android project remoteyourcam-usb listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
 *//from   w w  w  .  j a  v a2s  .co m
 * 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.remoteyourcam.usb.ptp;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import android.graphics.Bitmap;
import android.hardware.usb.UsbRequest;
import android.os.Handler;
import android.util.Log;

import org.acra.ErrorReporter;

import com.remoteyourcam.usb.AppConfig;
import com.remoteyourcam.usb.ptp.commands.CloseSessionCommand;
import com.remoteyourcam.usb.ptp.commands.Command;
import com.remoteyourcam.usb.ptp.commands.GetDeviceInfoCommand;
import com.remoteyourcam.usb.ptp.commands.GetDevicePropValueCommand;
import com.remoteyourcam.usb.ptp.commands.GetObjectHandlesCommand;
import com.remoteyourcam.usb.ptp.commands.GetStorageInfosAction;
import com.remoteyourcam.usb.ptp.commands.InitiateCaptureCommand;
import com.remoteyourcam.usb.ptp.commands.OpenSessionCommand;
import com.remoteyourcam.usb.ptp.commands.RetrieveImageAction;
import com.remoteyourcam.usb.ptp.commands.RetrieveImageInfoAction;
import com.remoteyourcam.usb.ptp.commands.RetrievePictureAction;
import com.remoteyourcam.usb.ptp.commands.SetDevicePropValueCommand;
import com.remoteyourcam.usb.ptp.model.DeviceInfo;
import com.remoteyourcam.usb.ptp.model.DevicePropDesc;
import com.remoteyourcam.usb.ptp.model.LiveViewData;

public abstract class PtpCamera implements Camera {

    public interface IO {
        void handleCommand(Command command);
    }

    enum State {
        // initial state
        Starting,
        // open session
        Active,
        // someone has asked to close session
        Stoping,
        // thread has stopped
        Stopped,
        // error happened
        Error
    }

    private static final String TAG = PtpCamera.class.getSimpleName();

    private final WorkerThread workerThread = new WorkerThread();
    private final PtpUsbConnection connection;

    protected final Handler handler = new Handler();
    protected final LinkedBlockingQueue<PtpAction> queue = new LinkedBlockingQueue<PtpAction>();
    protected CameraListener listener;
    protected State state;

    private int transactionId;
    protected DeviceInfo deviceInfo;

    protected boolean histogramSupported;
    protected boolean liveViewSupported;
    protected boolean liveViewAfAreaSupported;
    protected boolean liveViewOpen;

    protected boolean bulbSupported;

    protected boolean driveLensSupported;

    protected boolean autoFocusSupported;

    protected boolean cameraIsCapturing;

    protected final Map<Integer, Integer> virtualToPtpProperty = new HashMap<Integer, Integer>();
    protected final Map<Integer, Integer> ptpToVirtualProperty = new HashMap<Integer, Integer>();

    // current property values and descriptions
    protected final Map<Integer, DevicePropDesc> ptpPropertyDesc = new HashMap<Integer, DevicePropDesc>();
    protected final Map<Integer, Integer> ptpProperties = new HashMap<Integer, Integer>();
    protected final Map<Integer, Integer> properties = new HashMap<Integer, Integer>();
    private final Map<Integer, int[]> propertyDescriptions = new HashMap<Integer, int[]>();
    protected final Set<Integer> ptpInternalProperties = new HashSet<Integer>();

    private final int vendorId;
    protected final int productId;

    private WorkerListener workerListener;
    private int pictureSampleSize;

    public PtpCamera(PtpUsbConnection connection, CameraListener listener, WorkerListener workerListener) {
        this.connection = connection;
        this.listener = listener;
        this.workerListener = workerListener;
        this.pictureSampleSize = 2;
        state = State.Starting;
        vendorId = connection.getVendorId();
        productId = connection.getProductId();
        queue.add(new GetDeviceInfoCommand(this));
        openSession();
        workerThread.start();
        if (AppConfig.LOG) {
            Log.i(TAG, String.format("Starting session for %04x %04x", vendorId, productId));
        }
    }

    protected void addPropertyMapping(int virtual, int ptp) {
        ptpToVirtualProperty.put(ptp, virtual);
        virtualToPtpProperty.put(virtual, ptp);
    }

    protected void addInternalProperty(int ptp) {
        ptpInternalProperties.add(ptp);
    }

    public void setListener(CameraListener listener) {
        this.listener = listener;
    }

    public void shutdown() {
        state = State.Stoping;
        workerThread.lastEventCheck = System.currentTimeMillis() + 1000000L;
        queue.clear();
        if (liveViewOpen) {
            //TODO
            setLiveView(false);
        }
        closeSession();
    }

    public void shutdownHard() {
        state = State.Stopped;
        synchronized (workerThread) {
            workerThread.stop = true;
        }
        if (connection != null) {
            connection.close();
            //TODO possible NPE, need to join workerThread
            //connection = null;
        }
    }

    public State getState() {
        return state;
    }

    public int nextTransactionId() {
        return transactionId++;
    }

    public int currentTransactionId() {
        return transactionId;
    }

    public void resetTransactionId() {
        transactionId = 0;
    }

    public int getProductId() {
        return productId;
    }

    public void setDeviceInfo(DeviceInfo deviceInfo) {
        if (AppConfig.LOG) {
            Log.i(TAG, deviceInfo.toString());
        }
        if (AppConfig.USE_ACRA) {
            try {
                ErrorReporter.getInstance().putCustomData("deviceInfo", deviceInfo.toString());
            } catch (Throwable e) {
                // no fail
            }
        }
        this.deviceInfo = deviceInfo;

        Set<Integer> operations = new HashSet<Integer>();
        for (int i = 0; i < deviceInfo.operationsSupported.length; ++i) {
            operations.add(deviceInfo.operationsSupported[i]);
        }

        onOperationCodesReceived(operations);
    }

    public void enqueue(final Command cmd, int delay) {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (state == State.Active) {
                    queue.add(cmd);
                }
            }
        }, delay);
    }

    /**
     * Deriving classes should override this method to get the set of supported
     * operations of the camera. Based on this information functionality has to
     * be enabled/disabled.
     */
    protected abstract void onOperationCodesReceived(Set<Integer> operations);

    public int getPtpProperty(int property) {
        Integer value = ptpProperties.get(property);
        return value != null ? value : 0;
    }

    public void onSessionOpened() {
        state = State.Active;
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onCameraStarted(PtpCamera.this);
                }
            }
        });
    }

    public void onSessionClosed() {
        shutdownHard();
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onCameraStopped(PtpCamera.this);
                }
            }
        });
    }

    public void onPropertyChanged(int property, final int value) {
        Log.i(TAG, "p " + property + " " + value);
        ptpProperties.put(property, value);
        final Integer virtual = ptpToVirtualProperty.get(property);
        if (AppConfig.LOG) {
            Log.d(TAG, String.format("onPropertyChanged %s %s(%d)", PtpConstants.propertyToString(property),
                    virtual != null ? propertyToString(virtual, value) : "", value));
        }
        if (virtual != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    properties.put(virtual, value);
                    if (listener != null) {
                        listener.onPropertyChanged(virtual, value);
                    }
                }
            });
        }
    }

    public void onPropertyDescChanged(int property, final int[] values) {
        //if (BuildConfig.LOG) {
            Log.d(TAG,
                    String.format("onPropertyDescChanged %s:\n%s", PtpConstants.propertyToString(property),
                            Arrays.toString(values)));
        //}
        final Integer virtual = ptpToVirtualProperty.get(property);
        if (virtual != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    propertyDescriptions.put(virtual, values);
                    if (listener != null) {
                        listener.onPropertyDescChanged(virtual, values);
                    }
                }
            });
        }
    }

    public void onPropertyDescChanged(int property, DevicePropDesc desc) {
        ptpPropertyDesc.put(property, desc);
        onPropertyDescChanged(property, desc.description);
    }

    public void onLiveViewStarted() {
        liveViewOpen = true;
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onLiveViewStarted();
                }
            }
        });
    }

    public void onLiveViewRestarted() {
        liveViewOpen = true;
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onLiveViewStarted();
                }
            }
        });
    }

    public void onLiveViewStopped() {
        liveViewOpen = false;
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onLiveViewStopped();
                }
            }
        });
    }

    public void onLiveViewReceived(final LiveViewData data) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onLiveViewData(data);
                }
            }
        });
    }

    public void onPictureReceived(final int objectHandle, final String filename, final Bitmap thumbnail,
            final Bitmap bitmap) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onCapturedPictureReceived(objectHandle, filename, thumbnail, bitmap);
                }
            }
        });
    }

    public void onEventCameraCapture(boolean started) {
        cameraIsCapturing = started;
        if (isBulbCurrentShutterSpeed()) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    if (listener != null) {
                        if (cameraIsCapturing) {
                            listener.onBulbStarted();
                        } else {
                            listener.onBulbStopped();
                        }
                    }
                }
            });
        }
    }

    public void onEventDevicePropChanged(int property) {
        if ((ptpToVirtualProperty.containsKey(property) || ptpInternalProperties.contains(property))
                && ptpPropertyDesc.containsKey(property)) {
            DevicePropDesc desc = ptpPropertyDesc.get(property);
            queue.add(new GetDevicePropValueCommand(this, property, desc.datatype));
        }
    }

    public void onEventObjectAdded(final int handle, final int format) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onObjectAdded(handle, format);
                }
            }
        });
    }

    public void onBulbExposureTime(final int seconds) {
        if (seconds >= 0 && seconds <= 360000) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    if (listener != null) {
                        listener.onBulbExposureTime(seconds);
                    }
                }
            });
        }
    }

    public void onFocusStarted() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onFocusStarted();
                }
            }
        });
    }

    public void onFocusEnded(final boolean hasFocused) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onFocusEnded(hasFocused);
                }
            }
        });
    }

    public void onDeviceBusy(PtpAction action, boolean requeue) {
        if (AppConfig.LOG) {
            Log.i(TAG, "onDeviceBusy, sleeping a bit");
        }
        if (requeue) {
            action.reset();
            queue.add(action);
        }
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // nop
        }
    }

    public void onPtpWarning(final String message) {
        if (AppConfig.LOG) {
            Log.i(TAG, "onPtpWarning: " + message);
        }
    }

    public void onPtpError(final String message) {
        if (AppConfig.LOG) {
            Log.e(TAG, "onPtpError: " + message);
        }
        state = State.Error;
        if (state == State.Active) {
            shutdown();
        } else {
            shutdownHard();
        }
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onError(message);
                }
            }
        });
    }

    private void onUsbError(final String message) {
        if (AppConfig.LOG) {
            Log.e(TAG, "onUsbError: " + message);
        }
        queue.clear();
        shutdownHard();
        state = State.Error;
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onError(String.format("Error in USB communication: %s", message));
                }
            }
        });
    }

    protected abstract void queueEventCheck();

    protected abstract boolean isBulbCurrentShutterSpeed();

    private class WorkerThread extends Thread implements IO {
        public boolean stop;

        private int maxPacketOutSize;
        private int maxPacketInSize;
        private long lastEventCheck;
        private UsbRequest r1;
        private UsbRequest r2;
        private UsbRequest r3;
        private final int bigInSize = 0x4000;
        // buffers for async data io, size bigInSize
        private ByteBuffer bigIn1;
        private ByteBuffer bigIn2;
        private ByteBuffer bigIn3;
        // buffer for small packets like command and response
        private ByteBuffer smallIn;
        // buffer containing full data out packet for processing
        private int fullInSize = 0x4000;
        private ByteBuffer fullIn;

        @Override
        public void run() {

            notifyWorkStarted();

            maxPacketOutSize = connection.getMaxPacketOutSize();
            maxPacketInSize = connection.getMaxPacketInSize();

            if (maxPacketOutSize <= 0 || maxPacketOutSize > 0xffff) {
                onUsbError(String.format("Usb initialization error: out size invalid %d", maxPacketOutSize));
                return;
            }

            if (maxPacketInSize <= 0 || maxPacketInSize > 0xffff) {
                onUsbError(String.format("usb initialization error: in size invalid %d", maxPacketInSize));
                return;
            }

            smallIn = ByteBuffer.allocate(Math.max(maxPacketInSize, maxPacketOutSize));
            smallIn.order(ByteOrder.LITTLE_ENDIAN);

            bigIn1 = ByteBuffer.allocate(bigInSize);
            bigIn1.order(ByteOrder.LITTLE_ENDIAN);
            bigIn2 = ByteBuffer.allocate(bigInSize);
            bigIn2.order(ByteOrder.LITTLE_ENDIAN);
            bigIn3 = ByteBuffer.allocate(bigInSize);
            bigIn3.order(ByteOrder.LITTLE_ENDIAN);

            fullIn = ByteBuffer.allocate(fullInSize);
            fullIn.order(ByteOrder.LITTLE_ENDIAN);

            r1 = connection.createInRequest();
            r2 = connection.createInRequest();
            r3 = connection.createInRequest();

            while (true) {
                synchronized (this) {
                    if (stop) {
                        break;
                    }
                }

                if (lastEventCheck + AppConfig.EVENTCHECK_PERIOD < System.currentTimeMillis()) {
                    lastEventCheck = System.currentTimeMillis();
                    PtpCamera.this.queueEventCheck();
                }

                PtpAction action = null;
                try {
                    action = queue.poll(1000, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    // nop
                }

                if (action != null) {
                    action.exec(this);
                }
            }
            r3.close();
            r2.close();
            r1.close();

            notifyWorkEnded();
        }

        @Override
        public void handleCommand(Command command) {
            if (AppConfig.LOG) {
                Log.i(TAG, "handling command " + command.getClass().getSimpleName());
            }

            ByteBuffer b = smallIn;
            b.position(0);
            command.encodeCommand(b);

            int outLen = b.position();

            int res = connection.bulkTransferOut(b.array(), outLen, AppConfig.USB_TRANSFER_TIMEOUT);
            if (res < outLen) {
                onUsbError(String.format("Code CP %d %d", res, outLen));
                return;
            }

            if (command.hasDataToSend()) {
                b = ByteBuffer.allocate(connection.getMaxPacketOutSize());
                b.order(ByteOrder.LITTLE_ENDIAN);
                command.encodeData(b);
                outLen = b.position();
                res = connection.bulkTransferOut(b.array(), outLen, AppConfig.USB_TRANSFER_TIMEOUT);
                if (res < outLen) {
                    onUsbError(String.format("Code DP %d %d", res, outLen));
                    return;
                }
            }

            while (!command.hasResponseReceived()) {
                int maxPacketSize = maxPacketInSize;
                ByteBuffer in = smallIn;
                in.position(0);

                res = 0;
                while (res == 0) {
                    res = connection.bulkTransferIn(in.array(), maxPacketSize, AppConfig.USB_TRANSFER_TIMEOUT);
                }
                if (res < 12) {
                    onUsbError(String.format("Couldn't read header, only %d bytes available!", res));
                    return;
                }

                int read = res;
                int length = in.getInt();
                ByteBuffer infull = null;

                if (read < length) {
                    if (length > fullInSize) {
                        fullInSize = (int) (length * 1.5);
                        fullIn = ByteBuffer.allocate(fullInSize);
                        fullIn.order(ByteOrder.LITTLE_ENDIAN);
                    }
                    infull = fullIn;
                    infull.position(0);
                    infull.put(in.array(), 0, read);
                    maxPacketSize = bigInSize;

                    int nextSize = Math.min(maxPacketSize, length - read);
                    int nextSize2 = Math.max(0, Math.min(maxPacketSize, length - read - nextSize));
                    int nextSize3 = 0;

                    r1.queue(bigIn1, nextSize);

                    if (nextSize2 > 0) {
                        r2.queue(bigIn2, nextSize2);
                    }

                    while (read < length) {

                        nextSize3 = Math.max(0, Math.min(maxPacketSize, length - read - nextSize - nextSize2));

                        if (nextSize3 > 0) {
                            bigIn3.position(0);
                            r3.queue(bigIn3, nextSize3);
                        }

                        if (nextSize > 0) {
                            connection.requestWait();
                            System.arraycopy(bigIn1.array(), 0, infull.array(), read, nextSize);
                            read += nextSize;
                        }

                        nextSize = Math.max(0, Math.min(maxPacketSize, length - read - nextSize2 - nextSize3));

                        if (nextSize > 0) {
                            bigIn1.position(0);
                            r1.queue(bigIn1, nextSize);
                        }

                        if (nextSize2 > 0) {
                            connection.requestWait();
                            System.arraycopy(bigIn2.array(), 0, infull.array(), read, nextSize2);
                            read += nextSize2;
                        }

                        nextSize2 = Math.max(0, Math.min(maxPacketSize, length - read - nextSize - nextSize3));

                        if (nextSize2 > 0) {
                            bigIn2.position(0);
                            r2.queue(bigIn2, nextSize2);
                        }

                        if (nextSize3 > 0) {
                            connection.requestWait();
                            System.arraycopy(bigIn3.array(), 0, infull.array(), read, nextSize3);
                            read += nextSize3;
                        }
                    }
                } else {
                    infull = in;
                }

                infull.position(0);
                try {
                    command.receivedRead(infull);
                    infull = null;
                } catch (RuntimeException e) {
                    // TODO user could send us some data here
                    if (AppConfig.LOG) {
                        Log.e(TAG, "Exception " + e.getLocalizedMessage());
                        e.printStackTrace();
                    }
                    onPtpError(String.format("Error parsing %s with length %d", command.getClass().getSimpleName(),
                            length));
                }
            }
        }

        private void notifyWorkStarted() {
            WorkerListener l = workerListener;
            if (l != null) {
                l.onWorkerStarted();
            }
        }

        private void notifyWorkEnded() {
            WorkerListener l = workerListener;
            if (l != null) {
                l.onWorkerEnded();
            }
        }
    }

    protected void openSession() {
        queue.add(new OpenSessionCommand(this));
    }

    protected void closeSession() {
        queue.add(new CloseSessionCommand(this));
    }

    @Override
    public void setWorkerListener(WorkerListener listener) {
        workerListener = listener;
    }

    @Override
    public String getDeviceName() {
        return deviceInfo != null ? deviceInfo.model : "";
    }

    @Override
    public boolean isSessionOpen() {
        return state == State.Active;
    }

    @Override
    public int getProperty(final int property) {
        if (properties.containsKey(property)) {
            return properties.get(property);
        }
        return 0x7fffffff;
    }

    @Override
    public boolean getPropertyEnabledState(int property) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public int[] getPropertyDesc(int property) {
        if (propertyDescriptions.containsKey(property)) {
            return propertyDescriptions.get(property);
        }
        return new int[0];
    }

    @Override
    public void setProperty(int property, int value) {
        final Integer ptpProperty = virtualToPtpProperty.get(property);
        if (ptpProperty != null && ptpPropertyDesc.containsKey(ptpProperty)) {
            queue.add(new SetDevicePropValueCommand(this, ptpProperty, value, ptpPropertyDesc.get(ptpProperty).datatype));
        }
    }

    @Override
    public String propertyToString(int property, int value) {
        Integer ptpProperty = virtualToPtpProperty.get(property);
        if (ptpProperty != null) {
            String text = PtpPropertyHelper.mapToString(productId, ptpProperty, value);
            return text != null ? text : "?";
        } else {
            return "";
        }
    }

    @Override
    public Integer propertyToIcon(int property, int value) {
        Integer ptpProperty = virtualToPtpProperty.get(property);
        if (ptpProperty != null) {
            Integer iconId = PtpPropertyHelper.mapToDrawable(ptpProperty, value);
            return iconId != null ? iconId : null;
        } else {
            return null;
        }
    }

    @Override
    public String getBiggestPropertyValue(int property) {
        Integer ptpProperty = virtualToPtpProperty.get(property);
        if (ptpProperty != null) {
            return PtpPropertyHelper.getBiggestValue(ptpProperty);
        } else {
            return "";
        }
    }

    @Override
    public void capture() {
        queue.add(new InitiateCaptureCommand(this));
    }

    @Override
    public boolean isAutoFocusSupported() {
        return autoFocusSupported;
    }

    @Override
    public boolean isLiveViewSupported() {
        return liveViewSupported;
    }

    @Override
    public boolean isLiveViewAfAreaSupported() {
        return liveViewAfAreaSupported;
    }

    @Override
    public boolean isHistogramSupported() {
        return histogramSupported;
    }

    @Override
    public boolean isLiveViewOpen() {
        return liveViewOpen;
    }

    @Override
    public boolean isDriveLensSupported() {
        return driveLensSupported;
    }

    @Override
    public String getDeviceInfo() {
        return deviceInfo != null ? deviceInfo.toString() : "unknown";
    }

    @Override
    public void writeDebugInfo(File out) {
        try {
            FileWriter writer = new FileWriter(out);
            writer.append(deviceInfo.toString());
            writer.close();
        } catch (IOException e) {
        }
    }

    @Override
    public void retrievePicture(int objectHandle) {
        queue.add(new RetrievePictureAction(this, objectHandle, pictureSampleSize));
    }

    @Override
    public void retrieveStorages(StorageInfoListener listener) {
        queue.add(new GetStorageInfosAction(this, listener));
    }

    @Override
    public void retrieveImageHandles(StorageInfoListener listener, int storageId, int objectFormat) {
        queue.add(new GetObjectHandlesCommand(this, listener, storageId, objectFormat));
    }

    @Override
    public void retrieveImageInfo(RetrieveImageInfoListener listener, int objectHandle) {
        queue.add(new RetrieveImageInfoAction(this, listener, objectHandle));
    }

    @Override
    public void retrieveImage(RetrieveImageListener listener, int objectHandle) {
        queue.add(new RetrieveImageAction(this, listener, objectHandle, pictureSampleSize));
    }

    @Override
    public void setCapturedPictureSampleSize(int sampleSize) {
        this.pictureSampleSize = sampleSize;
    }

}




Java Source Code List

com.remoteyourcam.usb.AbstractRycApplication.java
com.remoteyourcam.usb.AppConfig.java
com.remoteyourcam.usb.AppSettings.java
com.remoteyourcam.usb.GestureDetector.java
com.remoteyourcam.usb.MainActivity.java
com.remoteyourcam.usb.PictureView.java
com.remoteyourcam.usb.PropertyAdapter.java
com.remoteyourcam.usb.PropertyData.java
com.remoteyourcam.usb.PropertyDisplayer.java
com.remoteyourcam.usb.PropertyToggle.java
com.remoteyourcam.usb.RycApplication.java
com.remoteyourcam.usb.activities.AppSettingsActivity.java
com.remoteyourcam.usb.ptp.Camera.java
com.remoteyourcam.usb.ptp.EosCamera.java
com.remoteyourcam.usb.ptp.EosConstants.java
com.remoteyourcam.usb.ptp.FocusPoint.java
com.remoteyourcam.usb.ptp.NikonCamera.java
com.remoteyourcam.usb.ptp.PacketUtil.java
com.remoteyourcam.usb.ptp.PtpAction.java
com.remoteyourcam.usb.ptp.PtpCamera.java
com.remoteyourcam.usb.ptp.PtpConstants.java
com.remoteyourcam.usb.ptp.PtpPropertyHelper.java
com.remoteyourcam.usb.ptp.PtpService.java
com.remoteyourcam.usb.ptp.PtpUsbConnection.java
com.remoteyourcam.usb.ptp.PtpUsbService.java
com.remoteyourcam.usb.ptp.WorkerNotifier.java
com.remoteyourcam.usb.ptp.commands.CloseSessionCommand.java
com.remoteyourcam.usb.ptp.commands.Command.java
com.remoteyourcam.usb.ptp.commands.GetDeviceInfoCommand.java
com.remoteyourcam.usb.ptp.commands.GetDevicePropDescCommand.java
com.remoteyourcam.usb.ptp.commands.GetDevicePropValueCommand.java
com.remoteyourcam.usb.ptp.commands.GetObjectCommand.java
com.remoteyourcam.usb.ptp.commands.GetObjectHandlesCommand.java
com.remoteyourcam.usb.ptp.commands.GetObjectInfoCommand.java
com.remoteyourcam.usb.ptp.commands.GetStorageIdsCommand.java
com.remoteyourcam.usb.ptp.commands.GetStorageInfoCommand.java
com.remoteyourcam.usb.ptp.commands.GetStorageInfosAction.java
com.remoteyourcam.usb.ptp.commands.GetThumb.java
com.remoteyourcam.usb.ptp.commands.InitiateCaptureCommand.java
com.remoteyourcam.usb.ptp.commands.OpenSessionCommand.java
com.remoteyourcam.usb.ptp.commands.RetrieveAddedObjectInfoAction.java
com.remoteyourcam.usb.ptp.commands.RetrieveImageAction.java
com.remoteyourcam.usb.ptp.commands.RetrieveImageInfoAction.java
com.remoteyourcam.usb.ptp.commands.RetrievePictureAction.java
com.remoteyourcam.usb.ptp.commands.SetDevicePropValueCommand.java
com.remoteyourcam.usb.ptp.commands.SimpleCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosEventCheckCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosGetLiveViewPictureCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosOpenSessionAction.java
com.remoteyourcam.usb.ptp.commands.eos.EosSetExtendedEventInfoCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosSetLiveViewAction.java
com.remoteyourcam.usb.ptp.commands.eos.EosSetPcModeCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosSetPropertyCommand.java
com.remoteyourcam.usb.ptp.commands.eos.EosTakePictureCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonAfDriveCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonAfDriveDeviceReadyCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonCloseSessionAction.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonEventCheckCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonGetLiveViewImageAction.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonGetLiveViewImageCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonGetVendorPropCodesCommand.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonOpenSessionAction.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonStartLiveViewAction.java
com.remoteyourcam.usb.ptp.commands.nikon.NikonStopLiveViewAction.java
com.remoteyourcam.usb.ptp.model.DeviceInfo.java
com.remoteyourcam.usb.ptp.model.DevicePropDesc.java
com.remoteyourcam.usb.ptp.model.LiveViewData.java
com.remoteyourcam.usb.ptp.model.ObjectInfo.java
com.remoteyourcam.usb.ptp.model.StorageInfo.java
com.remoteyourcam.usb.util.DimenUtil.java
com.remoteyourcam.usb.util.NotificationIds.java
com.remoteyourcam.usb.util.PackageUtil.java
com.remoteyourcam.usb.view.AspectRatioImageView.java
com.remoteyourcam.usb.view.BaseFragment.java
com.remoteyourcam.usb.view.GalleryAdapter.java
com.remoteyourcam.usb.view.GalleryFragment.java
com.remoteyourcam.usb.view.PictureFragment.java
com.remoteyourcam.usb.view.SessionActivity.java
com.remoteyourcam.usb.view.SessionFragment.java
com.remoteyourcam.usb.view.SessionView.java
com.remoteyourcam.usb.view.StorageAdapter.java
com.remoteyourcam.usb.view.TabletSessionFragment.java
com.remoteyourcam.usb.view.ThumbnailAdapter.java
com.remoteyourcam.usb.view.WebViewDialogFragment.java