diff options
author | Robert Henigan <robert.henigan@livio.io> | 2020-10-05 13:31:51 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-05 13:31:51 -0400 |
commit | 1cd37116aa21df73a70a6fe48b956f9bec144b8c (patch) | |
tree | bd12fc1bcd1b94d65d94aee3889e8a90ee6639c1 | |
parent | fb5bc6eb580902a3c13f7d079d71599f4b3bf6f4 (diff) | |
parent | a6b38b3060eecff77a28c7785ec0816ed4539ec9 (diff) | |
download | sdl_android-1cd37116aa21df73a70a6fe48b956f9bec144b8c.tar.gz |
Merge pull request #1517 from smartdevicelink/bugfix/issue_1515
Correct Lockscreen start behavior
3 files changed, 165 insertions, 121 deletions
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java index d18908dbe..924ad6680 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java @@ -134,18 +134,18 @@ public class LockScreenManagerTests { onDriverDistraction.setState(DriverDistractionState.DD_ON); onDDListener.onNotified(onDriverDistraction); assertTrue(lockScreenManager.enableDismissGesture); - assertTrue(lockScreenManager.mIsLockscreenDismissible); + assertTrue(lockScreenManager.isLockscreenDismissible); } @Test public void testLockScreenDismissibleWithEnableFalseAndDismissibilityFalse() { lockScreenManager.enableDismissGesture = false; OnDriverDistraction onDriverDistraction = new OnDriverDistraction(); - onDriverDistraction.setLockscreenDismissibility(true); + onDriverDistraction.setLockscreenDismissibility(false); onDriverDistraction.setState(DriverDistractionState.DD_ON); onDDListener.onNotified(onDriverDistraction); assertFalse(lockScreenManager.enableDismissGesture); - assertFalse(lockScreenManager.mIsLockscreenDismissible); + assertFalse(lockScreenManager.isLockscreenDismissible); } @Test @@ -156,7 +156,7 @@ public class LockScreenManagerTests { onDriverDistraction.setState(DriverDistractionState.DD_ON); onDDListener.onNotified(onDriverDistraction); assertTrue(lockScreenManager.enableDismissGesture); - assertFalse(lockScreenManager.mIsLockscreenDismissible); + assertFalse(lockScreenManager.isLockscreenDismissible); } @Test @@ -167,7 +167,7 @@ public class LockScreenManagerTests { onDriverDistraction.setState(DriverDistractionState.DD_ON); onDDListener.onNotified(onDriverDistraction); assertFalse(lockScreenManager.enableDismissGesture); - assertFalse(lockScreenManager.mIsLockscreenDismissible); + assertTrue(lockScreenManager.isLockscreenDismissible); } }
\ No newline at end of file diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java index 105396fa2..66894df8b 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java @@ -37,6 +37,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; +import android.os.Handler; import androidx.annotation.RestrictTo; @@ -69,12 +70,13 @@ import java.lang.ref.WeakReference; public class LockScreenManager extends BaseSubManager { private static final String TAG = "LockScreenManager"; + private final Object LOCKSCREEN_LAUNCH_LOCK = new Object(); private final WeakReference<Context> context; HMILevel hmiLevel; private OnRPCNotificationListener systemRequestListener, ddListener, hmiListener; private String deviceIconUrl; boolean driverDistStatus; - boolean mIsLockscreenDismissible; + boolean isLockscreenDismissible = false; boolean enableDismissGesture; final boolean lockScreenEnabled; final boolean deviceLogoEnabled; @@ -89,6 +91,7 @@ public class LockScreenManager extends BaseSubManager { private String mLockscreenWarningMsg; private BroadcastReceiver mLockscreenDismissedReceiver; private final LockScreenDeviceIconManager mLockScreenDeviceIconManager; + private String lastIntentUsed; public LockScreenManager(LockScreenConfig lockScreenConfig, Context context, ISdl internalInterface) { @@ -195,34 +198,54 @@ public class LockScreenManager extends BaseSubManager { public void onNotified(RPCNotification notification) { // do something with the status if (notification != null) { - OnDriverDistraction ddState = (OnDriverDistraction) notification; - Boolean isDismissible = ddState.getLockscreenDismissibility(); - DebugTool.logInfo(TAG, "Lock screen dismissible: " + isDismissible); - if (isDismissible != null) { - // both of these conditions must be met to be able to dismiss lockscreen - if (isDismissible && enableDismissGesture) { - mIsLockscreenDismissible = true; - - // if DisplayMode is set to ALWAYS, it will be shown before the first DD notification. - // If this is our first DD notification and we are in ALWAYS mode, send another intent to - // enable the dismissal - if (!receivedFirstDDNotification && displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS) { - launchLockScreenActivity(); + synchronized (this) { + OnDriverDistraction ddState = (OnDriverDistraction) notification; + driverDistStatus = DriverDistractionState.DD_ON.equals(ddState.getState()); + mLockscreenWarningMsg = ddState.getLockscreenWarningMessage(); + boolean previousDismissibleState = isLockscreenDismissible; + if(ddState.getLockscreenDismissibility() != null ) { + isLockscreenDismissible = ddState.getLockscreenDismissibility(); + } //If the param is null, we assume it stays as the previous value + + DebugTool.logInfo(TAG, "Lock screen dismissible: " + isLockscreenDismissible); + + if (displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS) { + //If the lockscreen is DISPLAY_MODE_ALWAYS, the only thing that matters + // is the dismissible state + if (enableDismissGesture) { + //Check if there was a change to the dismissible state + if (isLockscreenDismissible != previousDismissibleState) { + // if DisplayMode is set to ALWAYS, it will be shown before the first DD notification. + // If this is our first DD notification and we are in ALWAYS mode, send another intent to + // enable the dismissal. There is a delay added to allow time for the activity + // time to completely start and handle the new intent. There seems to be odd behavior + // in Android when startActivity is called multiple times too quickly. + if (!receivedFirstDDNotification) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + launchLockScreenActivity(); + } + }, 1000); + } else { + launchLockScreenActivity(); + } + } } + receivedFirstDDNotification = true; + return; } - } - mLockscreenWarningMsg = ddState.getLockscreenWarningMessage(); - if (ddState.getState() == DriverDistractionState.DD_ON) { - // launch lock screen - driverDistStatus = true; - launchLockScreenActivity(); - } else { - // close lock screen - driverDistStatus = false; - closeLockScreenActivity(); + //For all other states the logic will be handled in the launchLockScreenActivity method call + if (driverDistStatus) { + // launch lock screen + launchLockScreenActivity(); + } else { + // close lock screen + closeLockScreenActivity(); + } + receivedFirstDDNotification = true; } - receivedFirstDDNotification = true; } } }; @@ -258,6 +281,7 @@ public class LockScreenManager extends BaseSubManager { @androidx.lifecycle.OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_STOP) public void onMoveToBackground() { isApplicationForegrounded = false; + lastIntentUsed = null; } }; @@ -273,11 +297,13 @@ public class LockScreenManager extends BaseSubManager { public void onReceive(Context context, Intent intent) { if (SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED.equals(intent.getAction())) { mLockScreenHasBeenDismissed = true; + lastIntentUsed = null; } } }; } + //// // LAUNCH LOCK SCREEN LOGIC //// @@ -290,34 +316,43 @@ public class LockScreenManager extends BaseSubManager { * X. If the status is set to OFF, Send broadcast to close lock screen if it is open */ private void launchLockScreenActivity() { - // If the user has dismissed the lockscreen for this run or has disabled it, do not show it - if (mLockScreenHasBeenDismissed || displayMode == LockScreenConfig.DISPLAY_MODE_NEVER) { - return; - } - // intent to open SDLLockScreenActivity - // pass in icon, background color, and custom view - if (lockScreenEnabled && isApplicationForegrounded && context.get() != null) { - if (mIsLockscreenDismissible && !lockscreenDismissReceiverRegistered) { - context.get().registerReceiver(mLockscreenDismissedReceiver, new IntentFilter(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED)); - lockscreenDismissReceiverRegistered = true; - + synchronized (LOCKSCREEN_LAUNCH_LOCK) { + // If the user has dismissed the lockscreen for this run or has disabled it, do not show it + if (mLockScreenHasBeenDismissed || displayMode == LockScreenConfig.DISPLAY_MODE_NEVER) { + return; } - LockScreenStatus status = getLockScreenStatus(); - if (status == LockScreenStatus.REQUIRED || displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS || (status == LockScreenStatus.OPTIONAL && displayMode == LockScreenConfig.DISPLAY_MODE_OPTIONAL_OR_REQUIRED)) { - Intent showLockScreenIntent = new Intent(context.get(), SDLLockScreenActivity.class); - showLockScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - // Extra parameters for customization of the lock screen view - showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_ICON_EXTRA, lockScreenIcon); - showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_COLOR_EXTRA, lockScreenColor); - showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_CUSTOM_VIEW_EXTRA, customView); - showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled); - showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo); - showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSIBLE, mIsLockscreenDismissible); - showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_WARNING_MSG, mLockscreenWarningMsg); - context.get().startActivity(showLockScreenIntent); - } else if (status == LockScreenStatus.OFF) { - closeLockScreenActivity(); + // intent to open SDLLockScreenActivity + // pass in icon, background color, and custom view + if (lockScreenEnabled && isApplicationForegrounded && context.get() != null) { + if (isLockscreenDismissible && !lockscreenDismissReceiverRegistered) { + context.get().registerReceiver(mLockscreenDismissedReceiver, new IntentFilter(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED)); + lockscreenDismissReceiverRegistered = true; + + } + LockScreenStatus status = getLockScreenStatus(); + if (status == LockScreenStatus.REQUIRED || displayMode == LockScreenConfig.DISPLAY_MODE_ALWAYS || (status == LockScreenStatus.OPTIONAL && displayMode == LockScreenConfig.DISPLAY_MODE_OPTIONAL_OR_REQUIRED)) { + Intent showLockScreenIntent = new Intent(context.get(), SDLLockScreenActivity.class); + showLockScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // Extra parameters for customization of the lock screen view + showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_ICON_EXTRA, lockScreenIcon); + showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_COLOR_EXTRA, lockScreenColor); + showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_CUSTOM_VIEW_EXTRA, customView); + showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled); + showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo); + showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSIBLE, isLockscreenDismissible && enableDismissGesture); + showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_WARNING_MSG, mLockscreenWarningMsg); + + if (lastIntentUsed != null && lastIntentUsed.equals(showLockScreenIntent.toUri(0))) { + DebugTool.logInfo(TAG, "Not restarting lockscreen with same intent"); + return; + } else { + context.get().startActivity(showLockScreenIntent); + lastIntentUsed = showLockScreenIntent.toUri(0); + } + } else if (status == LockScreenStatus.OFF) { + closeLockScreenActivity(); + } } } } @@ -334,6 +369,7 @@ public class LockScreenManager extends BaseSubManager { context.get().sendBroadcast(new Intent(SDLLockScreenActivity.CLOSE_LOCK_SCREEN_ACTION)); } } + lastIntentUsed = null; } //// diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java index e74e9db6e..01de088c1 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java @@ -66,12 +66,11 @@ public class SDLLockScreenActivity extends Activity { public static final String KEY_LOCKSCREEN_DISMISSIBLE = "KEY_LOCKSCREEN_DISMISSIBLE"; public static final String KEY_LOCKSCREEN_WARNING_MSG = "KEY_LOCKSCREEN_WARNING_MSG"; private static final int MIN_SWIPE_DISTANCE = 200; - private boolean mIsDismissible; - private GestureDetector mGestureDetector; + private boolean isDismissible; + private GestureDetector dismissibleGestureDetector; private int backgroundColor = Color.parseColor("#394e60"); private boolean useWhiteIconAndTextColor; - private final BroadcastReceiver lockScreenBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -97,9 +96,9 @@ public class SDLLockScreenActivity extends Activity { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); - mGestureDetector = new GestureDetector(this, new SwipeUpGestureListener()); + dismissibleGestureDetector = new GestureDetector(this, new SwipeUpGestureListener()); // set any parameters that came from the lock screen manager - initializeActivity(getIntent()); + initializeActivity(getIntent(), true); // create intent filter IntentFilter lockscreenFilter = new IntentFilter(); @@ -112,8 +111,8 @@ public class SDLLockScreenActivity extends Activity { @Override public boolean onTouchEvent(MotionEvent event) { - if (mIsDismissible) { - return mGestureDetector.onTouchEvent(event); + if (isDismissible) { + return dismissibleGestureDetector.onTouchEvent(event); } return super.onTouchEvent(event); } @@ -132,26 +131,32 @@ public class SDLLockScreenActivity extends Activity { protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); - if (intent != null && intent.getBooleanExtra(KEY_LOCKSCREEN_DISMISSIBLE, false)) { - initializeActivity(intent); - } + initializeActivity(intent, false); } - public void initializeActivity(Intent intent) { + public void initializeActivity(Intent intent, boolean inflateLayout) { if (intent != null) { - boolean deviceLogoEnabled = intent.getBooleanExtra(LOCKSCREEN_DEVICE_LOGO_EXTRA, true); - int customColor = intent.getIntExtra(LOCKSCREEN_COLOR_EXTRA, 0); - int customIcon = intent.getIntExtra(LOCKSCREEN_ICON_EXTRA, 0); + isDismissible = intent.getBooleanExtra(KEY_LOCKSCREEN_DISMISSIBLE, false); int customView = intent.getIntExtra(LOCKSCREEN_CUSTOM_VIEW_EXTRA, 0); - Bitmap deviceIcon = intent.getParcelableExtra(LOCKSCREEN_DEVICE_LOGO_BITMAP); - backgroundColor = (customColor != 0) ? customColor : backgroundColor; - if (customView != 0) { - setCustomView(customView); + if (inflateLayout) { + setContentView(customView); + } //Currently the only thing done with a custom view is to inflate it } else { - setContentView(R.layout.activity_sdllock_screen); + boolean deviceLogoEnabled = intent.getBooleanExtra(LOCKSCREEN_DEVICE_LOGO_EXTRA, true); + int customColor = intent.getIntExtra(LOCKSCREEN_COLOR_EXTRA, 0); + int customIcon = intent.getIntExtra(LOCKSCREEN_ICON_EXTRA, 0); + Bitmap deviceIcon = intent.getParcelableExtra(LOCKSCREEN_DEVICE_LOGO_BITMAP); + + if (inflateLayout) { + setContentView(R.layout.activity_sdllock_screen); + } + + backgroundColor = (customColor != 0) ? customColor : backgroundColor; setBackgroundColor(); + useWhiteIconAndTextColor = shouldUseWhiteForegroundForBackgroundColor(); + setTextColor(useWhiteIconAndTextColor ? Color.WHITE : Color.BLACK); // set Lock Screen Icon if (customIcon != 0) { @@ -163,13 +168,11 @@ public class SDLLockScreenActivity extends Activity { if (deviceLogoEnabled && deviceIcon != null) { setDeviceLogo(deviceIcon); } - mIsDismissible = intent.getBooleanExtra(KEY_LOCKSCREEN_DISMISSIBLE, false); + String warningMsg = intent.getStringExtra(KEY_LOCKSCREEN_WARNING_MSG); - if (mIsDismissible) { - setLockscreenWarningMessage(warningMsg); - } else if (!useWhiteIconAndTextColor) { - setTextColorBlack(); - } + setLockscreenText(warningMsg); + + } } } @@ -178,33 +181,37 @@ public class SDLLockScreenActivity extends Activity { * Sets the lockScreen logo */ private void setSdlLogo() { - ImageView lockScreen_iv = findViewById(R.id.lockscreen_image); - Drawable sdlIcon = getResources().getDrawable(R.drawable.sdl_lockscreen_icon); - // Checks color contrast and determines if the logo should be black or white - if (useWhiteIconAndTextColor) { - int color = Color.parseColor("#ffffff"); - - int red = (color & 0xFF0000) / 0xFFFF; - int green = (color & 0xFF00) / 0xFF; - int blue = color & 0xFF; - - float[] matrix = {0, 0, 0, 0, red, - 0, 0, 0, 0, green, - 0, 0, 0, 0, blue, - 0, 0, 0, 1, 0}; - - ColorFilter colorFilter = new ColorMatrixColorFilter(matrix); - sdlIcon.setColorFilter(colorFilter); + ImageView lockScreenImageView = findViewById(R.id.lockscreen_image); + if (lockScreenImageView != null) { + Drawable sdlIcon = getResources().getDrawable(R.drawable.sdl_lockscreen_icon); + // Checks color contrast and determines if the logo should be black or white + if (sdlIcon != null && useWhiteIconAndTextColor) { + int color = Color.parseColor("#ffffff"); + + int red = (color & 0xFF0000) / 0xFFFF; + int green = (color & 0xFF00) / 0xFF; + int blue = color & 0xFF; + + float[] matrix = {0, 0, 0, 0, red, + 0, 0, 0, 0, green, + 0, 0, 0, 0, blue, + 0, 0, 0, 1, 0}; + + ColorFilter colorFilter = new ColorMatrixColorFilter(matrix); + sdlIcon.setColorFilter(colorFilter); + } + lockScreenImageView.setImageDrawable(sdlIcon); } - lockScreen_iv.setImageDrawable(sdlIcon); } /** * Changes the text color to white on the lockScreen */ - private void setTextColorBlack() { - TextView tv = findViewById(R.id.lockscreen_text); - tv.setTextColor(Color.parseColor("#000000")); + private void setTextColor(int color) { + TextView lockscreenTextView = findViewById(R.id.lockscreen_text); + if (lockscreenTextView != null) { + lockscreenTextView.setTextColor(color); + } } /** @@ -242,35 +249,36 @@ public class SDLLockScreenActivity extends Activity { * @param customIcon */ private void changeIcon(int customIcon) { - ImageView lockScreen_iv = findViewById(R.id.lockscreen_image); - lockScreen_iv.setVisibility(View.GONE); + ImageView lockScreenImageView = findViewById(R.id.lockscreen_image); + if (lockScreenImageView != null) { + lockScreenImageView.setVisibility(View.GONE); + } - ImageView lockScreenCustom_iv = findViewById(R.id.appIcon); - lockScreenCustom_iv.setVisibility(View.VISIBLE); - lockScreenCustom_iv.setBackgroundResource(customIcon); + ImageView appIconImageView = findViewById(R.id.appIcon); + if (appIconImageView != null) { + appIconImageView.setVisibility(View.VISIBLE); + appIconImageView.setBackgroundResource(customIcon); + } } private void setDeviceLogo(Bitmap deviceLogo) { - ImageView device_iv = findViewById(R.id.device_image); - if (deviceLogo != null) { - device_iv.setImageBitmap(deviceLogo); + ImageView connectedDeviceImageView = findViewById(R.id.device_image); + if (deviceLogo != null && connectedDeviceImageView != null) { + connectedDeviceImageView.setImageBitmap(deviceLogo); } } - private void setLockscreenWarningMessage(String msg) { - TextView tv = findViewById(R.id.lockscreen_text); - if (tv != null) { - if (!useWhiteIconAndTextColor) { - tv.setTextColor(Color.parseColor("#000000")); + private void setLockscreenText(String msg) { + TextView lockscreenTextView = findViewById(R.id.lockscreen_text); + if (lockscreenTextView != null) { + if (isDismissible) { + lockscreenTextView.setText(msg != null ? msg : getString(R.string.default_lockscreen_warning_message)); + } else { + lockscreenTextView.setText(getString(R.string.lockscreen_text)); } - tv.setText(msg != null ? msg : getString(R.string.default_lockscreen_warning_message)); } } - private void setCustomView(int customView) { - setContentView(customView); - } - private class SwipeUpGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onFling(MotionEvent event1, MotionEvent event2, |