3737import android .content .Intent ;
3838import android .content .IntentFilter ;
3939import android .graphics .Bitmap ;
40+ import android .os .Handler ;
4041
4142import androidx .annotation .RestrictTo ;
4243
6970public 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