Skip to content

Commit

Permalink
android camera app - fw update enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
matkatz committed Jun 26, 2019
1 parent d456ac0 commit 97eda7d
Show file tree
Hide file tree
Showing 13 changed files with 527 additions and 113 deletions.
30 changes: 30 additions & 0 deletions wrappers/android/tools/camera/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,36 @@ android {
}
}

def getFwVersion(String productLine) {
try {
String versionsFile = new File("$projectDir/../../../../common/fw/firmware-version.h").text
def regex = productLine + " \"(.*)\""
def matcher = ( versionsFile =~ regex )
return matcher[0][1]
}catch(e){
println(e)
return "Unknown FW version"
}
}

task downloadFirmware() {
mkdir "$projectDir/src/main/res/raw"

def d4xxFwVersion = getFwVersion('D4XX_RECOMMENDED_FIRMWARE_VERSION')
def d4xxFile = new File("$projectDir/src/main/res/raw/fw_d4xx.bin")
if (!d4xxFile.exists()) {
println("downloading D4xx fw: " + d4xxFwVersion)
new URL('http://realsense-hw-public.s3-eu-west-1.amazonaws.com/Releases/RS4xx/FW/D4XX_FW_Image-' + d4xxFwVersion + '.bin').withInputStream{ i -> d4xxFile.withOutputStream{ it << i }}
}

def sr3xxFwVersion = getFwVersion('SR3XX_RECOMMENDED_FIRMWARE_VERSION')
def sr3xxFile = new File("$projectDir/src/main/res/raw/fw_sr3xx.bin")
if (!sr3xxFile.exists()) {
println("downloading SR3xx fw: " + sr3xxFwVersion)
new URL('http://realsense-hw-public.s3-eu-west-1.amazonaws.com/Releases/SR300/FW/SR3XX_FW_Image-' + sr3xxFwVersion + '.bin').withInputStream{ i -> sr3xxFile.withOutputStream{ it << i }}
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.0.0'
Expand Down
1 change: 1 addition & 0 deletions wrappers/android/tools/camera/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
android:theme="@style/AppTheme">
<activity
android:name=".DetachedActivity"
android:noHistory="true"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,44 @@
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.intel.realsense.librealsense.CameraInfo;
import com.intel.realsense.librealsense.Device;
import com.intel.realsense.librealsense.DeviceList;
import com.intel.realsense.librealsense.DeviceListener;
import com.intel.realsense.librealsense.Extension;
import com.intel.realsense.librealsense.ProductLine;
import com.intel.realsense.librealsense.RsContext;

import java.util.HashMap;
import java.util.Map;

public class DetachedActivity extends AppCompatActivity {
private static final String TAG = "librs camera detached";
private static final int PERMISSIONS_REQUEST_CAMERA = 0;
private static final int PLAYBACK_REQUEST_CODE = 1;
private static final String MINIMAL_D400_FW_VERSION = "5.10.0.0";

private boolean mPermissionsGrunted = false;
private Button mPlaybackButton;

private Context mAppContext;
private RsContext mRsContext = new RsContext();
;

private Map<ProductLine,String> mMinimalFirmwares = new HashMap<>();
private boolean mUpdating = false;
private Context mAppContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -40,7 +53,7 @@ protected void onCreate(Bundle savedInstanceState) {
mPlaybackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mAppContext, PlaybackActivity.class);
Intent intent = new Intent(DetachedActivity.this, PlaybackActivity.class);
startActivityForResult(intent, PLAYBACK_REQUEST_CODE);
}
});
Expand All @@ -51,15 +64,12 @@ public void onClick(View view) {
return;
}

runOnUiThread(new Runnable() {
@Override
public void run() {
String appVersion = BuildConfig.VERSION_NAME;
String lrsVersion = RsContext.getVersion();
TextView versions = findViewById(R.id.versionsText);
versions.setText("librealsense version: " + lrsVersion + "\ncamera app version: " + appVersion);
}
});
String appVersion = BuildConfig.VERSION_NAME;
String lrsVersion = RsContext.getVersion();
TextView versions = findViewById(R.id.versionsText);
versions.setText("librealsense version: " + lrsVersion + "\ncamera app version: " + appVersion);

mMinimalFirmwares.put(ProductLine.D400, MINIMAL_D400_FW_VERSION);

mPermissionsGrunted = true;
}
Expand All @@ -79,62 +89,96 @@ protected void onResume() {
super.onResume();

if(mPermissionsGrunted)
init();
{
RsContext.init(getApplicationContext());
mRsContext.setDevicesChangedCallback(mListener);
validatedDevice();
}
}

private void init() {
RsContext.init(getApplicationContext());
mRsContext.setDevicesChangedCallback(mListener);

if(mRsContext.queryDevices().getDeviceCount() > 0){
if(!validated_device())
private synchronized void validatedDevice(){
if(mUpdating)
return;
try(DeviceList dl = mRsContext.queryDevices()){
if(dl.getDeviceCount() == 0)
return;
Intent intent = new Intent(mAppContext, PreviewActivity.class);
startActivity(intent);
finish();
try(Device d = dl.createDevice(0)){
if(d.is(Extension.UPDATE_DEVICE)){
FirmwareUpdateProgressDialog fupd = new FirmwareUpdateProgressDialog();
fupd.show(getFragmentManager(), null);
mUpdating = true;
}
else {
if (!validateFwVersion(d))
return;
Intent intent = new Intent(this, PreviewActivity.class);
startActivity(intent);
finish();
}
}
} catch (Exception e){
Log.e(TAG, "error while validateding device, error: " + e.getMessage());
}
}

private boolean validateFwVersion(Device device){
final String currFw = device.getInfo(CameraInfo.FIRMWARE_VERSION);
final ProductLine pl = ProductLine.valueOf(device.getInfo(CameraInfo.PRODUCT_LINE));
if(mMinimalFirmwares.containsKey(pl)){
final String minimalFw = mMinimalFirmwares.get(pl);
if(!compareFwVersion(device, currFw, minimalFw)){
FirmwareUpdateDialog fud = new FirmwareUpdateDialog();
Bundle bundle = new Bundle();
bundle.putBoolean(getString(R.string.firmware_update_required), true);
fud.setArguments(bundle);
fud.show(getFragmentManager(), null);
return false;
}
}

SharedPreferences sharedPref = getSharedPreferences(getString(R.string.app_settings), Context.MODE_PRIVATE);
boolean showUpdateMessage = sharedPref.getBoolean(getString(R.string.show_update_firmware), true);
if (!showUpdateMessage || !device.supportsInfo(CameraInfo.RECOMMENDED_FIRMWARE_VERSION))
return true;

final String recommendedFw = device.getInfo(CameraInfo.RECOMMENDED_FIRMWARE_VERSION);
if(!compareFwVersion(device, currFw, recommendedFw)){
FirmwareUpdateDialog fud = new FirmwareUpdateDialog();
fud.show(getFragmentManager(), null);
return false;
}
return true;
}

private boolean compareFwVersion(Device device, String currFw, String otherFw){
String[] sFw = currFw.split("\\.");
String[] sRecFw = otherFw.split("\\.");
for (int i = 0; i < sRecFw.length; i++) {
if (Integer.parseInt(sFw[i]) > Integer.parseInt(sRecFw[i]))
break;
if (Integer.parseInt(sFw[i]) < Integer.parseInt(sRecFw[i])) {
return false;
}
}
return true;
}

private boolean validated_device(){
try(DeviceList devices = mRsContext.queryDevices()){
if(devices.getDeviceCount() == 0)
return false;
try(Device device = devices.createDevice(0)) {
if (!device.supportsInfo(CameraInfo.RECOMMENDED_FIRMWARE_VERSION))
return true;
final String recFw = device.getInfo(CameraInfo.RECOMMENDED_FIRMWARE_VERSION);
final String fw = device.getInfo(CameraInfo.FIRMWARE_VERSION);
String[] sFw = fw.split("\\.");
String[] sRecFw = recFw.split("\\.");
for(int i = 0; i < sRecFw.length; i++){
if(Integer.parseInt(sFw[i]) > Integer.parseInt(sRecFw[i]))
break;
if(Integer.parseInt(sFw[i]) < Integer.parseInt(sRecFw[i])){
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView textView = findViewById(R.id.connectCameraText);
textView.setText("The FW of the connected device is:\n " + fw +
"\n\nThe recommended FW for this device is:\n " + recFw +
"\n\nPlease update your device to the recommended FW or higher");
}
});
return false;
}
}
return true;
}
}
public void onFwUpdateStatus(final boolean status){
mUpdating = false;

runOnUiThread(new Runnable() {
@Override
public void run() {
String msg = status ? "firmware update done" : "firmware update failed";
Toast.makeText(DetachedActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
}

private DeviceListener mListener = new DeviceListener() {
@Override
public void onDeviceAttach() {
if(!validated_device())
return;
Intent intent = new Intent(mAppContext, PreviewActivity.class);
startActivity(intent);
finish();
validatedDevice();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.intel.realsense.camera;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import com.intel.realsense.librealsense.CameraInfo;
import com.intel.realsense.librealsense.Device;
import com.intel.realsense.librealsense.DeviceList;
import com.intel.realsense.librealsense.Extension;
import com.intel.realsense.librealsense.ProductLine;
import com.intel.realsense.librealsense.RsContext;
import com.intel.realsense.librealsense.Updatable;

public class FirmwareUpdateDialog extends DialogFragment {

private Button mFwUpdateButton;
private Button mSkipFwUpdateButton;
private CheckBox mDontAskAgainCheckBox;
private TextView mMessage;
private TextView mTitle;

private boolean mDontShowAgain = false;

static private String getFirmwareUpdateMessage(Device device){
final String recFw = device.supportsInfo(CameraInfo.RECOMMENDED_FIRMWARE_VERSION) ?
device.getInfo(CameraInfo.RECOMMENDED_FIRMWARE_VERSION) : "unknown";
final String fw = device.getInfo(CameraInfo.FIRMWARE_VERSION);
return "The firmware of the connected device is: " + fw +
"\n\nThe recommended firmware for this device is: " + recFw;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Activity activity = getActivity();
Bundle bundle = getArguments();

final boolean fwUpdateRequest = bundle == null ? false : bundle.getBoolean(getString(R.string.firmware_update_request), false);
final boolean fwUpdateRequired = bundle == null ? false : bundle.getBoolean(getString(R.string.firmware_update_required), false);

LayoutInflater inflater = activity.getLayoutInflater();
View fragmentView = inflater.inflate(R.layout.firmware_update_notification, null);

mDontAskAgainCheckBox = fragmentView.findViewById(R.id.dontAskFwUpdateCheckBox);
mFwUpdateButton = fragmentView.findViewById(R.id.startFwUpdateButton);
mSkipFwUpdateButton = fragmentView.findViewById(R.id.skipFwUpdateButton);
mMessage = fragmentView.findViewById(R.id.firmwareUpdateMessage);
mTitle = fragmentView.findViewById(R.id.firmwareUpdateTitle);

if(fwUpdateRequest){
mTitle.setText("Firmware update");
mSkipFwUpdateButton.setText("Cancel");
}

final RsContext rsContext = new RsContext();
try(DeviceList dl = rsContext.queryDevices()){
if(dl.getDeviceCount() > 0){
try(Device device = dl.createDevice(0)){
if(fwUpdateRequired)
mMessage.setText("The current firmware version of the connected device is not supported by this librealsense version, update is required");
else
mMessage.setText(getFirmwareUpdateMessage(device));
}
}
}

mFwUpdateButton = fragmentView.findViewById(R.id.startFwUpdateButton);
mFwUpdateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
try(DeviceList dl = rsContext.queryDevices(ProductLine.DEPTH)){
try(Device d = dl.createDevice(0)){
if(d.is(Extension.UPDATABLE))
d.<Updatable>as(Extension.UPDATABLE).enterUpdateState();
else
throw new RuntimeException("request to update a non updatable device");
}
}
}
});

mSkipFwUpdateButton = fragmentView.findViewById(R.id.skipFwUpdateButton);
mSkipFwUpdateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
if(!fwUpdateRequest){
Intent intent = new Intent(activity, PreviewActivity.class);
startActivity(intent);
}
}
});

if(fwUpdateRequired)
mSkipFwUpdateButton.setVisibility(View.GONE);

mDontAskAgainCheckBox = fragmentView.findViewById(R.id.dontAskFwUpdateCheckBox);
mDontAskAgainCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
SharedPreferences sharedPref = activity.getSharedPreferences(getString(R.string.app_settings), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
mDontShowAgain = !mDontShowAgain;
editor.putBoolean(getString(R.string.show_update_firmware), !mDontShowAgain);
editor.commit();
}
});
if(fwUpdateRequest || fwUpdateRequired)
mDontAskAgainCheckBox.setVisibility(View.GONE);

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(fragmentView);
AlertDialog rv = builder.create();
rv.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
return rv;
}
}
Loading

0 comments on commit 97eda7d

Please sign in to comment.