Skip to content

Commit 1cd3711

Browse files
author
Robert Henigan
authored
Merge pull request #1517 from smartdevicelink/bugfix/issue_1515
Correct Lockscreen start behavior
2 parents fb5bc6e + a6b38b3 commit 1cd3711

3 files changed

Lines changed: 165 additions & 121 deletions

File tree

android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,18 @@ public void testLockScreenDismissibleWithEnableTrueAndDismissibilityTrue() {
134134
onDriverDistraction.setState(DriverDistractionState.DD_ON);
135135
onDDListener.onNotified(onDriverDistraction);
136136
assertTrue(lockScreenManager.enableDismissGesture);
137-
assertTrue(lockScreenManager.mIsLockscreenDismissible);
137+
assertTrue(lockScreenManager.isLockscreenDismissible);
138138
}
139139

140140
@Test
141141
public void testLockScreenDismissibleWithEnableFalseAndDismissibilityFalse() {
142142
lockScreenManager.enableDismissGesture = false;
143143
OnDriverDistraction onDriverDistraction = new OnDriverDistraction();
144-
onDriverDistraction.setLockscreenDismissibility(true);
144+
onDriverDistraction.setLockscreenDismissibility(false);
145145
onDriverDistraction.setState(DriverDistractionState.DD_ON);
146146
onDDListener.onNotified(onDriverDistraction);
147147
assertFalse(lockScreenManager.enableDismissGesture);
148-
assertFalse(lockScreenManager.mIsLockscreenDismissible);
148+
assertFalse(lockScreenManager.isLockscreenDismissible);
149149
}
150150

151151
@Test
@@ -156,7 +156,7 @@ public void testLockScreenDismissibleWithEnableTrueAndDismissibilityFalse() {
156156
onDriverDistraction.setState(DriverDistractionState.DD_ON);
157157
onDDListener.onNotified(onDriverDistraction);
158158
assertTrue(lockScreenManager.enableDismissGesture);
159-
assertFalse(lockScreenManager.mIsLockscreenDismissible);
159+
assertFalse(lockScreenManager.isLockscreenDismissible);
160160
}
161161

162162
@Test
@@ -167,7 +167,7 @@ public void testLockScreenDismissibleWithEnableFalseAndDismissibilityTrue() {
167167
onDriverDistraction.setState(DriverDistractionState.DD_ON);
168168
onDDListener.onNotified(onDriverDistraction);
169169
assertFalse(lockScreenManager.enableDismissGesture);
170-
assertFalse(lockScreenManager.mIsLockscreenDismissible);
170+
assertTrue(lockScreenManager.isLockscreenDismissible);
171171
}
172172

173173
}

android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java

Lines changed: 88 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import android.content.Intent;
3838
import android.content.IntentFilter;
3939
import android.graphics.Bitmap;
40+
import android.os.Handler;
4041

4142
import androidx.annotation.RestrictTo;
4243

@@ -69,12 +70,13 @@
6970
public class LockScreenManager extends BaseSubManager {
7071

7172
private static final String TAG = "LockScreenManager";
73+
private final Object LOCKSCREEN_LAUNCH_LOCK = new Object();
7274
private final WeakReference<Context> context;
7375
HMILevel hmiLevel;
7476
private OnRPCNotificationListener systemRequestListener, ddListener, hmiListener;
7577
private String deviceIconUrl;
7678
boolean driverDistStatus;
77-
boolean mIsLockscreenDismissible;
79+
boolean isLockscreenDismissible = false;
7880
boolean enableDismissGesture;
7981
final boolean lockScreenEnabled;
8082
final boolean deviceLogoEnabled;
@@ -89,6 +91,7 @@ public class LockScreenManager extends BaseSubManager {
8991
private String mLockscreenWarningMsg;
9092
private BroadcastReceiver mLockscreenDismissedReceiver;
9193
private final LockScreenDeviceIconManager mLockScreenDeviceIconManager;
94+
private String lastIntentUsed;
9295

9396
public LockScreenManager(LockScreenConfig lockScreenConfig, Context context, ISdl internalInterface) {
9497

@@ -195,34 +198,54 @@ public void onNotified(RPCNotification notification) {
195198
public void onNotified(RPCNotification notification) {
196199
// do something with the status
197200
if (notification != null) {
198-
OnDriverDistraction ddState = (OnDriverDistraction) notification;
199-
Boolean isDismissible = ddState.getLockscreenDismissibility();
200-
DebugTool.logInfo(TAG, "Lock screen dismissible: " + isDismissible);
201-
if (isDismissible != null) {
202-
// both of these conditions must be met to be able to dismiss lockscreen
203-
if (isDismissible && enableDismissGesture) {
204-
mIsLockscreenDismissible = true;
205-
206-
// if DisplayMode is set to ALWAYS, it will be shown before the first DD notification.
207-
// If this is our first DD notification and we are in ALWAYS mode, send another intent to
208-
// enable the dismissal
209-
if (!receivedFirstDDNotification && displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS) {
210-
launchLockScreenActivity();
201+
synchronized (this) {
202+
OnDriverDistraction ddState = (OnDriverDistraction) notification;
203+
driverDistStatus = DriverDistractionState.DD_ON.equals(ddState.getState());
204+
mLockscreenWarningMsg = ddState.getLockscreenWarningMessage();
205+
boolean previousDismissibleState = isLockscreenDismissible;
206+
if(ddState.getLockscreenDismissibility() != null ) {
207+
isLockscreenDismissible = ddState.getLockscreenDismissibility();
208+
} //If the param is null, we assume it stays as the previous value
209+
210+
DebugTool.logInfo(TAG, "Lock screen dismissible: " + isLockscreenDismissible);
211+
212+
if (displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS) {
213+
//If the lockscreen is DISPLAY_MODE_ALWAYS, the only thing that matters
214+
// is the dismissible state
215+
if (enableDismissGesture) {
216+
//Check if there was a change to the dismissible state
217+
if (isLockscreenDismissible != previousDismissibleState) {
218+
// if DisplayMode is set to ALWAYS, it will be shown before the first DD notification.
219+
// If this is our first DD notification and we are in ALWAYS mode, send another intent to
220+
// enable the dismissal. There is a delay added to allow time for the activity
221+
// time to completely start and handle the new intent. There seems to be odd behavior
222+
// in Android when startActivity is called multiple times too quickly.
223+
if (!receivedFirstDDNotification) {
224+
new Handler().postDelayed(new Runnable() {
225+
@Override
226+
public void run() {
227+
launchLockScreenActivity();
228+
}
229+
}, 1000);
230+
} else {
231+
launchLockScreenActivity();
232+
}
233+
}
211234
}
235+
receivedFirstDDNotification = true;
236+
return;
212237
}
213-
}
214-
mLockscreenWarningMsg = ddState.getLockscreenWarningMessage();
215238

216-
if (ddState.getState() == DriverDistractionState.DD_ON) {
217-
// launch lock screen
218-
driverDistStatus = true;
219-
launchLockScreenActivity();
220-
} else {
221-
// close lock screen
222-
driverDistStatus = false;
223-
closeLockScreenActivity();
239+
//For all other states the logic will be handled in the launchLockScreenActivity method call
240+
if (driverDistStatus) {
241+
// launch lock screen
242+
launchLockScreenActivity();
243+
} else {
244+
// close lock screen
245+
closeLockScreenActivity();
246+
}
247+
receivedFirstDDNotification = true;
224248
}
225-
receivedFirstDDNotification = true;
226249
}
227250
}
228251
};
@@ -258,6 +281,7 @@ public void onMoveToForeground() {
258281
@androidx.lifecycle.OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_STOP)
259282
public void onMoveToBackground() {
260283
isApplicationForegrounded = false;
284+
lastIntentUsed = null;
261285
}
262286
};
263287

@@ -273,11 +297,13 @@ public void onMoveToBackground() {
273297
public void onReceive(Context context, Intent intent) {
274298
if (SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED.equals(intent.getAction())) {
275299
mLockScreenHasBeenDismissed = true;
300+
lastIntentUsed = null;
276301
}
277302
}
278303
};
279304
}
280305

306+
281307
////
282308
// LAUNCH LOCK SCREEN LOGIC
283309
////
@@ -290,34 +316,43 @@ public void onReceive(Context context, Intent intent) {
290316
* X. If the status is set to OFF, Send broadcast to close lock screen if it is open
291317
*/
292318
private void launchLockScreenActivity() {
293-
// If the user has dismissed the lockscreen for this run or has disabled it, do not show it
294-
if (mLockScreenHasBeenDismissed || displayMode == LockScreenConfig.DISPLAY_MODE_NEVER) {
295-
return;
296-
}
297-
// intent to open SDLLockScreenActivity
298-
// pass in icon, background color, and custom view
299-
if (lockScreenEnabled && isApplicationForegrounded && context.get() != null) {
300-
if (mIsLockscreenDismissible && !lockscreenDismissReceiverRegistered) {
301-
context.get().registerReceiver(mLockscreenDismissedReceiver, new IntentFilter(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED));
302-
lockscreenDismissReceiverRegistered = true;
303-
319+
synchronized (LOCKSCREEN_LAUNCH_LOCK) {
320+
// If the user has dismissed the lockscreen for this run or has disabled it, do not show it
321+
if (mLockScreenHasBeenDismissed || displayMode == LockScreenConfig.DISPLAY_MODE_NEVER) {
322+
return;
304323
}
305-
LockScreenStatus status = getLockScreenStatus();
306-
if (status == LockScreenStatus.REQUIRED || displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS || (status == LockScreenStatus.OPTIONAL && displayMode == LockScreenConfig.DISPLAY_MODE_OPTIONAL_OR_REQUIRED)) {
307-
Intent showLockScreenIntent = new Intent(context.get(), SDLLockScreenActivity.class);
308-
showLockScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
309-
310-
// Extra parameters for customization of the lock screen view
311-
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_ICON_EXTRA, lockScreenIcon);
312-
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_COLOR_EXTRA, lockScreenColor);
313-
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_CUSTOM_VIEW_EXTRA, customView);
314-
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled);
315-
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo);
316-
showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSIBLE, mIsLockscreenDismissible);
317-
showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_WARNING_MSG, mLockscreenWarningMsg);
318-
context.get().startActivity(showLockScreenIntent);
319-
} else if (status == LockScreenStatus.OFF) {
320-
closeLockScreenActivity();
324+
// intent to open SDLLockScreenActivity
325+
// pass in icon, background color, and custom view
326+
if (lockScreenEnabled && isApplicationForegrounded && context.get() != null) {
327+
if (isLockscreenDismissible && !lockscreenDismissReceiverRegistered) {
328+
context.get().registerReceiver(mLockscreenDismissedReceiver, new IntentFilter(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED));
329+
lockscreenDismissReceiverRegistered = true;
330+
331+
}
332+
LockScreenStatus status = getLockScreenStatus();
333+
if (status == LockScreenStatus.REQUIRED || displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS || (status == LockScreenStatus.OPTIONAL && displayMode == LockScreenConfig.DISPLAY_MODE_OPTIONAL_OR_REQUIRED)) {
334+
Intent showLockScreenIntent = new Intent(context.get(), SDLLockScreenActivity.class);
335+
showLockScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
336+
337+
// Extra parameters for customization of the lock screen view
338+
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_ICON_EXTRA, lockScreenIcon);
339+
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_COLOR_EXTRA, lockScreenColor);
340+
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_CUSTOM_VIEW_EXTRA, customView);
341+
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled);
342+
showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo);
343+
showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSIBLE, isLockscreenDismissible && enableDismissGesture);
344+
showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_WARNING_MSG, mLockscreenWarningMsg);
345+
346+
if (lastIntentUsed != null && lastIntentUsed.equals(showLockScreenIntent.toUri(0))) {
347+
DebugTool.logInfo(TAG, "Not restarting lockscreen with same intent");
348+
return;
349+
} else {
350+
context.get().startActivity(showLockScreenIntent);
351+
lastIntentUsed = showLockScreenIntent.toUri(0);
352+
}
353+
} else if (status == LockScreenStatus.OFF) {
354+
closeLockScreenActivity();
355+
}
321356
}
322357
}
323358
}
@@ -334,6 +369,7 @@ private void closeLockScreenActivity() {
334369
context.get().sendBroadcast(new Intent(SDLLockScreenActivity.CLOSE_LOCK_SCREEN_ACTION));
335370
}
336371
}
372+
lastIntentUsed = null;
337373
}
338374

339375
////

0 commit comments

Comments
 (0)