Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android stability fixes #6945

Merged
merged 4 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/android/jni/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ Java_com_intel_realsense_librealsense_Device_nQuerySensors(JNIEnv *env, jclass t
sensors.push_back(s);
}
jlongArray rv = env->NewLongArray(sensors.size());
env->SetLongArrayRegion(rv, 0, sensors.size(), reinterpret_cast<const jlong *>(sensors.data()));

for (auto i = 0; i < sensors.size(); i++)
{
env->SetLongArrayRegion(rv, i, 1, reinterpret_cast<const jlong *>(&sensors[i]));
}

return rv;
}

Expand Down
8 changes: 6 additions & 2 deletions src/android/jni/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ Java_com_intel_realsense_librealsense_Sensor_nGetStreamProfiles(JNIEnv *env, jcl
profiles.push_back(sp);
}

// jlong is 64-bit, but pointer in profiles could be 32-bit, copy element by element
jlongArray rv = env->NewLongArray(profiles.size());
env->SetLongArrayRegion(rv, 0, profiles.size(), reinterpret_cast<const jlong *>(profiles.data()));
for (auto i = 0; i < size; i++)
{
env->SetLongArrayRegion(rv, i, 1, reinterpret_cast<const jlong *>(&profiles[i]));
}
return rv;
}

Expand Down Expand Up @@ -97,4 +101,4 @@ Java_com_intel_realsense_librealsense_DepthSensor_nGetDepthScale(JNIEnv *env, jc
float depthScale = rs2_get_depth_scale(reinterpret_cast<rs2_sensor *>(handle), &e);
handle_error(env, e);
return depthScale;
}
}
15 changes: 12 additions & 3 deletions src/concurrency.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,16 @@ class dispatcher
auto func = std::move(item);
invoke([&, func](dispatcher::cancellable_timer c)
{
std::lock_guard<std::mutex> lk(_blocking_invoke_mutex);
func(c);

done = true;
_blocking_invoke_cv.notify_one();
}, is_blocking);

//wait
std::unique_lock<std::mutex> lk(_blocking_invoke_mutex);
while(_blocking_invoke_cv.wait_for(lk, std::chrono::milliseconds(10), [&](){ return !done && !exit_condition(); }));
_blocking_invoke_cv.wait(lk, [&](){ return done || exit_condition(); });
}

void start()
Expand All @@ -288,6 +290,9 @@ class dispatcher
{
{
std::unique_lock<std::mutex> lock(_was_stopped_mutex);

if (_was_stopped.load()) return;

_was_stopped = true;
_was_stopped_cv.notify_all();
}
Expand All @@ -310,6 +315,8 @@ class dispatcher
stop();
_queue.clear();
_is_alive = false;

if (_thread.joinable())
_thread.join();
}

Expand Down Expand Up @@ -379,8 +386,10 @@ class active_object

void stop()
{
_stopped = true;
_dispatcher.stop();
if (!_stopped.load()) {
_stopped = true;
_dispatcher.stop();
}
}

~active_object()
Expand Down
18 changes: 11 additions & 7 deletions src/pipeline/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ namespace librealsense

pipeline::~pipeline()
{
try
{
unsafe_stop();
if (_active_profile) {
try {
unsafe_stop();
}
catch (...) {}
}
catch (...) {}
}

std::shared_ptr<profile> pipeline::start(std::shared_ptr<config> conf, frame_callback_ptr callback)
Expand Down Expand Up @@ -144,10 +145,13 @@ namespace librealsense
catch (...)
{
} // Stop will throw if device was disconnected. TODO - refactoring anticipated

// shared pointers initialized when pipeline running with _active_profile
// should be reset with _active_profile too
_active_profile.reset();
_prev_conf.reset();
_streams_callback.reset();
}
_active_profile.reset();
_prev_conf.reset();
_streams_callback.reset();
}

std::shared_ptr<device_interface> pipeline::wait_for_device(const std::chrono::milliseconds& timeout, const std::string& serial)
Expand Down
2 changes: 1 addition & 1 deletion src/uvc/uvc-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ namespace librealsense

stop_stream_cleanup(profile, elem);

if (_profiles.empty())
if (!_profiles.empty())
_streamers.clear();
}

Expand Down
20 changes: 17 additions & 3 deletions src/uvc/uvc-streamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ namespace librealsense

_context.messenger->reset_endpoint(_read_endpoint, RS2_USB_ENDPOINT_DIRECTION_READ);

_running = true;
{
std::lock_guard<std::mutex> lock(_running_mutex);
_running = true;
}

for(auto&& r : _requests)
{
Expand Down Expand Up @@ -197,14 +200,25 @@ namespace librealsense

_publish_frame_thread->stop();

_running = false;
{
std::lock_guard<std::mutex> lock(_running_mutex);
_running = false;
_stopped_cv.notify_one();
}

}, [this](){ return !_running; });
}

void uvc_streamer::flush()
{
stop();
if(_running)
stop();

// synchronized so do not destroy shared pointers while it's still being running
{
std::unique_lock<std::mutex> lock(_running_mutex);
_stopped_cv.wait_for(lock, std::chrono::seconds(1), [&]() { return !_running; });
}

_read_endpoint.reset();

Expand Down
2 changes: 2 additions & 0 deletions src/uvc/uvc-streamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ namespace librealsense
bool wait_for_first_frame(uint32_t timeout_ms);

private:
std::mutex _running_mutex;
std::condition_variable _stopped_cv;
bool _running = false;
bool _frame_arrived = false;
bool _publish_frames = true;
Expand Down
3 changes: 2 additions & 1 deletion wrappers/android/tools/camera/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
</activity>
<activity
android:name=".PreviewActivity"
android:launchMode="singleTop"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".SettingsActivity"
Expand All @@ -49,4 +50,4 @@
android:theme="@style/AppTheme.NoActionBar" />
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,7 @@ protected void onCreate(Bundle savedInstanceState) {

requestPermissionsIfNeeded();

mPlaybackButton = findViewById(R.id.playbackButton);
mPlaybackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDetached = false;
finish();
Intent intent = new Intent(DetachedActivity.this, PlaybackActivity.class);
startActivityForResult(intent, PLAYBACK_REQUEST_CODE);
}
});

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);
}
});

mMinimalFirmwares.put(ProductLine.D400, MINIMAL_D400_FW_VERSION);
init();
}

private void requestPermissionsIfNeeded() {
Expand All @@ -93,7 +72,7 @@ private void requestPermissionsIfNeeded() {
@Override
protected void onResume() {
super.onResume();
mDetached = true;

if (isCameraPermissionGranted()) {
RsContext.init(getApplicationContext());
mRsContext.setDevicesChangedCallback(mListener);
Expand All @@ -109,12 +88,53 @@ private boolean isWritePermissionGranted() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}

private synchronized void init()
{
mPlaybackButton = findViewById(R.id.playbackButton);
mPlaybackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDetached = false;
finish();
Intent intent = new Intent(DetachedActivity.this, PlaybackActivity.class);
startActivityForResult(intent, PLAYBACK_REQUEST_CODE);
}
});

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);
}
});

mMinimalFirmwares.put(ProductLine.D400, MINIMAL_D400_FW_VERSION);
}

private synchronized void validatedDevice(){
if(mUpdating)
return;
try(DeviceList dl = mRsContext.queryDevices()){
if(dl.getDeviceCount() == 0)
if(dl.getDeviceCount() == 0) {
init();

// kill preview activity if device disconnected
if (mDetached) {
mDetached = false;

Intent intent = new Intent(this, PreviewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("keepalive", false);
startActivity(intent);
}

return;
}

try(Device d = dl.createDevice(0)){
if(d == null)
return;
Expand All @@ -127,10 +147,17 @@ private synchronized void validatedDevice(){
else {
if (!validateFwVersion(d))
return;

mDetached = false;

finish();

// launch preview activity and keep it alive
// the activity is single top instance, can be killed later the same instance
// to prevent issues with multiple instances
Intent intent = new Intent(this, PreviewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("keepalive", true);
startActivity(intent);
}
}
Expand Down Expand Up @@ -201,11 +228,8 @@ public void onDeviceAttach() {

@Override
public void onDeviceDetach() {
if(mDetached)
return;
finish();
Intent intent = new Intent(mAppContext, DetachedActivity.class);
startActivity(intent);
mDetached = true;
validatedDevice();
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public class PreviewActivity extends AppCompatActivity {
private boolean statsToggle = false;
private boolean mShow3D = false;

boolean keepalive = true;

public synchronized void toggleStats(){
statsToggle = !statsToggle;
if(statsToggle){
Expand All @@ -72,6 +74,15 @@ public synchronized void toggleStats(){
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);

keepalive = true;

Intent intent = this.getIntent();

if (intent != null && intent.getExtras() != null ) {
keepalive = intent.getExtras().getBoolean("keepalive");
}

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

mGLSurfaceView = findViewById(R.id.glSurfaceView);
Expand Down Expand Up @@ -204,6 +215,11 @@ private void clearLables(){
protected void onResume() {
super.onResume();

if(keepalive == false)
{
return;
}

mStreamingStats = new StreamingStats();
mStreamer = new Streamer(this, true, new Streamer.Listener() {
@Override
Expand Down Expand Up @@ -298,4 +314,21 @@ private synchronized void pauseFwLogger(){
}
mFwLogsRunning = false;
}

@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);

if (intent != null && intent.getExtras() != null ) {
keepalive = intent.getExtras().getBoolean("keepalive");
}

// destroy activity if requested
if(keepalive == false)
{
PreviewActivity.this.finish();
}
}

}