com.dslr.dashboard.PtpService.java Source code

Java tutorial

Introduction

Here is the source code for com.dslr.dashboard.PtpService.java

Source

/*
   <DslrDashboard - controling DSLR camera with Android phone/tablet>
Copyright (C) <2012>  <Zoltan Hubai>
    
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 <http://www.gnu.org/licenses/>.
    
 */

package com.dslr.dashboard;

import java.util.HashMap;
import java.util.Iterator;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;

public class PtpService extends ServiceBase {

    public interface OnPtpServiceEventListener {
        public void ServiceEvent(PtpServiceEvent event);
    }

    private OnPtpServiceEventListener mOnPtpServiceEventListener = null;

    public void setOnPtpServiceEventListener(OnPtpServiceEventListener listener) {
        mOnPtpServiceEventListener = listener;
    }

    private static final String TAG = "PtpService";

    private void sendPtpServiceEvent(PtpServiceEvent event) {
        if (mOnPtpServiceEventListener != null && mIsBind) {
            mOnPtpServiceEventListener.ServiceEvent(event);
        }
    }

    private UsbManager mUsbManager;
    private UsbDevice mUsbDevice;
    private UsbDeviceConnection mUsbConnection = null;
    private UsbInterface mUsbIntf = null;
    private UsbEndpoint mUsbWriteEp = null;
    private UsbEndpoint mUsbReadEp = null;
    private UsbEndpoint mUsbInterruptEp = null;

    private boolean mIsUsbDevicePresent = false;
    private boolean mIsUsbDeviceInitialized = false;
    private boolean mIsUsbInterfaceClaimed = false;

    private PtpDevice mPtpDevice = null;
    private GpsLocationHelper mGpsHelper = null;

    // preferences
    private SharedPreferences mPrefs = null;

    public boolean getIsUsbDevicePresent() {
        return mIsUsbDevicePresent;
    }

    public boolean getIsUsbDeviceInitialized() {
        return mIsUsbDeviceInitialized;
    }

    public PtpDevice getPtpDevice() {
        return mPtpDevice;
    }

    public GpsLocationHelper getGpsLocationHelper() {
        return mGpsHelper;
    }

    @Override
    public IBinder onBind(Intent intent) {
        cancelNotification();
        return super.onBind(intent);
    }

    @Override
    public void onRebind(Intent intent) {
        Log.d(TAG, "onRebind");
        super.onRebind(intent);
    }

    private static final String ACTION_USB_PERMISSION = "com.dslr.dashboard.USB_PERMISSION";
    PendingIntent mPermissionIntent;

    private final BroadcastReceiver mUsbPermissionReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "Intent received " + action);
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        Log.d(TAG, "USB device permission granted");
                        mUsbDevice = usbDevice;
                        mIsUsbDevicePresent = true;
                        initUsbConnection();
                    }
                }
            }
        }
    };

    private final BroadcastReceiver mUsbDeviceDetached = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                if (mUsbDevice == usbDevice) {
                    Log.d(PtpService.TAG, "DSLR USB device detached");
                    usbDeviceDetached();
                }
            }
        }
    };

    private void usbDeviceDetached() {
        Log.d(TAG, "Usb device removed, stoping the service");
        sendPtpServiceEvent(PtpServiceEvent.UsbDeviceRemoved);
        closeUsbConnection(true);
        mIsUsbDevicePresent = false;

        if (!mIsBind)
            stopSelf();
    }

    public void closeUsbConnection() {
        closeUsbConnection(false);
    }

    public void closeUsbConnection(boolean isUsbUnpluged) {
        Log.d(TAG, "closeUsbConnection");

        mPtpDevice.stop(isUsbUnpluged);

        if (mUsbConnection != null) {
            if (mIsUsbInterfaceClaimed) {
                Log.d(TAG, "Releasing USB interface");
                mUsbConnection.releaseInterface(mUsbIntf);
            }
            Log.d(TAG, "USB connection present, closing");
            mUsbConnection.close();
        }
        mIsUsbDevicePresent = false;
        mUsbIntf = null;
        mUsbReadEp = null;
        mUsbWriteEp = null;
        mUsbInterruptEp = null;
        mUsbConnection = null;
        mUsbDevice = null;
        mIsUsbInterfaceClaimed = false;
        mIsUsbDeviceInitialized = false;
        sendPtpServiceEvent(PtpServiceEvent.UsbDeviceRemoved);
    }

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate");
        super.onCreate();

        mGpsHelper = new GpsLocationHelper(this);

        IntentFilter usbDetachedFilter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
        registerReceiver(mUsbDeviceDetached, usbDetachedFilter);

        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbPermissionReceiver, filter);

        // get the shared preferences
        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);

        // create the ptpdevice
        mPtpDevice = new PtpDevice(this);

        try {
            mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        } catch (Exception e) {
            Log.d(TAG, "UsbManager not available: " + e.getMessage());
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");

        return START_STICKY; //super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");

        if (mGpsHelper != null) {
            mGpsHelper.stopGpsLocator();
            mGpsHelper = null;
        }

        unregisterReceiver(mUsbDeviceDetached);
        unregisterReceiver(mUsbPermissionReceiver);

        super.onDestroy();
    }

    @Override
    public void onLowMemory() {
        Log.d(TAG, "onLowMemory");
        super.onLowMemory();
    }

    public void stopPtpService(boolean keepAliveIfUsbConnected) {
        Log.d(TAG, "stopPtpService");
        cancelNotification();
        if (mIsUsbDeviceInitialized) {
            if (!keepAliveIfUsbConnected) {
                closeUsbConnection();
                stopSelf();
            } else {
                createNotification();
            }
        } else {
            stopSelf();
        }
    }

    private static int mId = 0x0001;

    private void cancelNotification() {
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        mNotificationManager.cancel(mId);
    }

    private void createNotification() {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.dslrlauncher).setContentTitle("DslrDashboard")
                .setContentText("Running in background");
        // Creates an explicit intent for an Activity in your app
        Intent resultIntent = new Intent(this, MainActivity.class);

        // The stack builder object will contain an artificial back stack for the
        // started Activity.
        // This ensures that navigating backward from the Activity leads out of
        // your application to the Home screen.
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        // Adds the back stack for the Intent (but not the Intent itself)
        stackBuilder.addParentStack(MainActivity.class);
        // Adds the Intent that starts the Activity to the top of the stack
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        // mId allows you to update the notification later on.
        mNotificationManager.notify(mId, mBuilder.build());
    }

    public void searchForUsbCamera() {
        boolean deviceFound = false;
        try {
            if (mUsbDevice == null) {
                Log.d(TAG, "Ptp service usb device not initialized, search for one");

                if (mUsbManager != null) {
                    HashMap<String, UsbDevice> devices = mUsbManager.getDeviceList();
                    Log.d(TAG, "Found USB devices count: " + devices.size());
                    Iterator<UsbDevice> iterator = devices.values().iterator();
                    while (iterator.hasNext()) {
                        UsbDevice usbDevice = iterator.next();
                        Log.d(TAG,
                                "USB Device: " + usbDevice.getDeviceName() + " Product ID: "
                                        + usbDevice.getProductId() + " Vendor ID: " + usbDevice.getVendorId()
                                        + " Interface count: " + usbDevice.getInterfaceCount());
                        for (int i = 0; i < usbDevice.getInterfaceCount(); i++) {
                            UsbInterface intf = usbDevice.getInterface(i);
                            Log.d(TAG, "Interface class: " + intf.getInterfaceClass());
                            if (intf.getInterfaceClass() == android.hardware.usb.UsbConstants.USB_CLASS_STILL_IMAGE) {
                                //mUsbDevice = usbDevice;
                                Log.d(TAG, "Ptp Service imaging usb device found requesting permission");
                                mUsbManager.requestPermission(usbDevice, mPermissionIntent);
                                deviceFound = true;
                                break;
                            }
                        }
                        if (deviceFound)
                            break;
                    }
                } else
                    Log.d(TAG, "USB Manager is unavailable");

            } else {
                Log.d(TAG, "Ptp service usb imaging device already present");
                //_usbManager.requestPermission(_usbDevice, mPermissionIntent);
            }
        } catch (Exception e) {
            Log.d(TAG, "PtpService search for USB camrea exception: " + e.getMessage());
        }

    }

    private void initUsbConnection() {

        try {
            if (mUsbDevice != null) {
                if (mUsbIntf == null) {
                    for (int i = 0; i < mUsbDevice.getInterfaceCount(); i++) {
                        UsbInterface uintf = mUsbDevice.getInterface(i);
                        if (uintf.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE) {
                            // we have a still image interface
                            // Log.d(MainActivity.TAG, "Imaging USB interface found");
                            mUsbIntf = uintf;
                            break;
                        }
                    }
                    if (mUsbIntf != null) {
                        // get the endpoints
                        for (int i = 0; i < mUsbIntf.getEndpointCount(); i++) {
                            UsbEndpoint ep = mUsbIntf.getEndpoint(i);
                            if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                                    mUsbWriteEp = ep;
                                    // Log.d(MainActivity.TAG, "write endpoint found");
                                }
                            } else {
                                switch (ep.getType()) {
                                case UsbConstants.USB_ENDPOINT_XFER_BULK:
                                    mUsbReadEp = ep;
                                    // Log.d(MainActivity.TAG, "read endpoint found");
                                    break;
                                case UsbConstants.USB_ENDPOINT_XFER_INT:
                                    mUsbInterruptEp = ep;
                                    // Log.d(MainActivity.TAG, "interrupt endpoint found");
                                    break;
                                }
                            }
                        }
                    } else
                        Log.d(TAG, "No compatible USB interface found");
                } else
                    Log.d(TAG, "USB interface found");
                // if we have read and write endpoints then we good to go
                if (mUsbReadEp != null && mUsbWriteEp != null) {
                    if (!mIsUsbDeviceInitialized) {
                        mUsbConnection = mUsbManager.openDevice(mUsbDevice);
                        mIsUsbDeviceInitialized = mUsbConnection != null;
                    }
                    if (mIsUsbDeviceInitialized) {
                        // Log.d(TAG, "USB Device Initialized");
                        if (!mIsUsbInterfaceClaimed) {
                            mIsUsbInterfaceClaimed = mUsbConnection.claimInterface(mUsbIntf, true);
                            // Log.d(TAG, "USB Interface claimed: " + isInterfaceClaimed);
                        }
                        sendPtpServiceEvent(PtpServiceEvent.UsbDeviceInitialized);
                        // create the USB communicator
                        PtpUsbCommunicator communicator = new PtpUsbCommunicator(new PtpSession());
                        // initialize the USB communicator
                        communicator.initCommunicator(mUsbConnection, mUsbWriteEp, mUsbReadEp, mUsbInterruptEp);
                        // initialize the PTP device
                        mPtpDevice.initialize(mUsbDevice.getVendorId(), mUsbDevice.getProductId(), communicator);
                    }
                }

            } else
                Log.d(TAG, "No USB device present");

        } catch (Exception e) {
            Log.d(TAG, "InitUsb exception: " + e.getMessage());
        }
    }

    // preferences properties
    public SharedPreferences getPreferences() {
        return mPrefs;
    }

}