Merge "Remove all GHBM logic" into tm-dev am: 3c984e8bf5
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17491204 Change-Id: I93ced6f6e35b36a5c066ba346ac5b4f85533ab55 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -24,31 +24,20 @@ package android.hardware.fingerprint;
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IUdfpsHbmListener {
|
||||
|
||||
/** HBM that applies to the whole screen. */
|
||||
const int GLOBAL_HBM = 0;
|
||||
|
||||
/** HBM that only applies to a portion of the screen. */
|
||||
const int LOCAL_HBM = 1;
|
||||
|
||||
/**
|
||||
* UdfpsController will call this method when the HBM is enabled.
|
||||
*
|
||||
* @param hbmType The type of HBM that was enabled. See
|
||||
* {@link com.android.systemui.biometrics.UdfpsHbmTypes}.
|
||||
* @param displayId The displayId for which the HBM is enabled. See
|
||||
* {@link android.view.Display#getDisplayId()}.
|
||||
*/
|
||||
void onHbmEnabled(int hbmType, int displayId);
|
||||
void onHbmEnabled(int displayId);
|
||||
|
||||
/**
|
||||
* UdfpsController will call this method when the HBM is disabled.
|
||||
*
|
||||
* @param hbmType The type of HBM that was disabled. See
|
||||
* {@link com.android.systemui.biometrics.UdfpsHbmTypes}.
|
||||
* @param displayId The displayId for which the HBM is disabled. See
|
||||
* {@link android.view.Display#getDisplayId()}.
|
||||
*/
|
||||
void onHbmDisabled(int hbmType, int displayId);
|
||||
void onHbmDisabled(int displayId);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,4 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<com.android.systemui.biometrics.UdfpsSurfaceView
|
||||
android:id="@+id/hbm_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
</com.android.systemui.biometrics.UdfpsView>
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType;
|
||||
|
||||
/**
|
||||
* Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
|
||||
@@ -36,24 +33,21 @@ public interface UdfpsHbmProvider {
|
||||
* This method must be called from the UI thread. The callback, if provided, will also be
|
||||
* invoked from the UI thread.
|
||||
*
|
||||
* @param hbmType The type of HBM that should be enabled. See {@link UdfpsHbmTypes}.
|
||||
* @param surface The surface for which the HBM is requested, in case the HBM implementation
|
||||
* needs to set special surface flags to enable the HBM. Can be null.
|
||||
* @param onHbmEnabled A runnable that will be executed once HBM is enabled.
|
||||
*/
|
||||
void enableHbm(@HbmType int hbmType, @Nullable Surface surface,
|
||||
@Nullable Runnable onHbmEnabled);
|
||||
void enableHbm(@Nullable Runnable onHbmEnabled);
|
||||
|
||||
/**
|
||||
* UdfpsView will call this to disable the HBM when the illumination is not longer needed.
|
||||
* UdfpsView will call this to disable HBM when illumination is no longer needed.
|
||||
*
|
||||
* This method is a no-op when HBM is already disabled. If HBM is enabled, this method will
|
||||
* disable HBM for the {@code hbmType} and {@code surface} that were provided to the
|
||||
* corresponding {@link #enableHbm(int, Surface, Runnable)}.
|
||||
* This method will disable HBM if HBM is enabled. Otherwise, if HBM is already disabled,
|
||||
* this method is a no-op.
|
||||
*
|
||||
* The call must be made from the UI thread. The callback, if provided, will also be invoked
|
||||
* from the UI thread.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param onHbmDisabled A runnable that will be executed once HBM is disabled.
|
||||
*/
|
||||
void disableHbm(@Nullable Runnable onHbmDisabled);
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Different high-brightness mode (HBM) types that are relevant to this package.
|
||||
*/
|
||||
public final class UdfpsHbmTypes {
|
||||
/** HBM that applies to the whole screen. */
|
||||
public static final int GLOBAL_HBM = IUdfpsHbmListener.GLOBAL_HBM;
|
||||
|
||||
/** HBM that only applies to a portion of the screen. */
|
||||
public static final int LOCAL_HBM = IUdfpsHbmListener.LOCAL_HBM;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({GLOBAL_HBM, LOCAL_HBM})
|
||||
public @interface HbmType {
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
/**
|
||||
* Surface View for providing the Global High-Brightness Mode (GHBM) illumination for UDFPS.
|
||||
*/
|
||||
public class UdfpsSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
private static final String TAG = "UdfpsSurfaceView";
|
||||
|
||||
/**
|
||||
* Notifies {@link UdfpsView} when to enable GHBM illumination.
|
||||
*/
|
||||
interface GhbmIlluminationListener {
|
||||
/**
|
||||
* @param surface the surface for which GHBM should be enabled.
|
||||
* @param onIlluminatedRunnable a runnable that should be run after GHBM is enabled.
|
||||
*/
|
||||
void enableGhbm(@NonNull Surface surface, @Nullable Runnable onIlluminatedRunnable);
|
||||
}
|
||||
|
||||
@NonNull private final SurfaceHolder mHolder;
|
||||
@NonNull private final Paint mSensorPaint;
|
||||
|
||||
@Nullable private GhbmIlluminationListener mGhbmIlluminationListener;
|
||||
@Nullable private Runnable mOnIlluminatedRunnable;
|
||||
boolean mAwaitingSurfaceToStartIllumination;
|
||||
boolean mHasValidSurface;
|
||||
|
||||
public UdfpsSurfaceView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
// Make this SurfaceView draw on top of everything else in this window. This allows us to
|
||||
// 1) Always show the HBM circle on top of everything else, and
|
||||
// 2) Properly composite this view with any other animations in the same window no matter
|
||||
// what contents are added in which order to this view hierarchy.
|
||||
setZOrderOnTop(true);
|
||||
|
||||
mHolder = getHolder();
|
||||
mHolder.addCallback(this);
|
||||
mHolder.setFormat(PixelFormat.RGBA_8888);
|
||||
|
||||
mSensorPaint = new Paint(0 /* flags */);
|
||||
mSensorPaint.setAntiAlias(true);
|
||||
mSensorPaint.setARGB(255, 255, 255, 255);
|
||||
mSensorPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
@Override public void surfaceCreated(SurfaceHolder holder) {
|
||||
mHasValidSurface = true;
|
||||
if (mAwaitingSurfaceToStartIllumination) {
|
||||
doIlluminate(mOnIlluminatedRunnable);
|
||||
mOnIlluminatedRunnable = null;
|
||||
mAwaitingSurfaceToStartIllumination = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
// Unused.
|
||||
}
|
||||
|
||||
@Override public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
mHasValidSurface = false;
|
||||
}
|
||||
|
||||
void setGhbmIlluminationListener(@Nullable GhbmIlluminationListener listener) {
|
||||
mGhbmIlluminationListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: there is no corresponding method to stop GHBM illumination. It is expected that
|
||||
* {@link UdfpsView} will hide this view, which would destroy the surface and remove the
|
||||
* illumination dot.
|
||||
*/
|
||||
void startGhbmIllumination(@Nullable Runnable onIlluminatedRunnable) {
|
||||
if (mGhbmIlluminationListener == null) {
|
||||
Log.e(TAG, "startIllumination | mGhbmIlluminationListener is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mHasValidSurface) {
|
||||
doIlluminate(onIlluminatedRunnable);
|
||||
} else {
|
||||
mAwaitingSurfaceToStartIllumination = true;
|
||||
mOnIlluminatedRunnable = onIlluminatedRunnable;
|
||||
}
|
||||
}
|
||||
|
||||
private void doIlluminate(@Nullable Runnable onIlluminatedRunnable) {
|
||||
if (mGhbmIlluminationListener == null) {
|
||||
Log.e(TAG, "doIlluminate | mGhbmIlluminationListener is null");
|
||||
return;
|
||||
}
|
||||
|
||||
mGhbmIlluminationListener.enableGhbm(mHolder.getSurface(), onIlluminatedRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately draws the illumination dot on this SurfaceView's surface.
|
||||
*/
|
||||
void drawIlluminationDot(@NonNull RectF sensorRect) {
|
||||
if (!mHasValidSurface) {
|
||||
Log.e(TAG, "drawIlluminationDot | the surface is destroyed or was never created.");
|
||||
return;
|
||||
}
|
||||
Canvas canvas = null;
|
||||
try {
|
||||
canvas = mHolder.lockCanvas();
|
||||
canvas.drawOval(sensorRect, mSensorPaint);
|
||||
} finally {
|
||||
// Make sure the surface is never left in a bad state.
|
||||
if (canvas != null) {
|
||||
mHolder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,17 @@ import android.graphics.Paint
|
||||
import android.graphics.PointF
|
||||
import android.graphics.RectF
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import android.os.Build
|
||||
import android.os.UserHandle
|
||||
import android.provider.Settings
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.MotionEvent
|
||||
import android.view.Surface
|
||||
import android.widget.FrameLayout
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.doze.DozeReceiver
|
||||
import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType
|
||||
|
||||
private const val TAG = "UdfpsView"
|
||||
private const val SETTING_HBM_TYPE = "com.android.systemui.biometrics.UdfpsSurfaceView.hbmType"
|
||||
@HbmType
|
||||
private const val DEFAULT_HBM_TYPE = UdfpsHbmTypes.LOCAL_HBM
|
||||
|
||||
/**
|
||||
* A view containing 1) A SurfaceView for HBM, and 2) A normal drawable view for all other
|
||||
* animations.
|
||||
* The main view group containing all UDFPS animations.
|
||||
*/
|
||||
class UdfpsView(
|
||||
context: Context,
|
||||
@@ -68,21 +59,6 @@ class UdfpsView(
|
||||
com.android.internal.R.integer.config_udfps_illumination_transition_ms
|
||||
).toLong()
|
||||
|
||||
@HbmType
|
||||
private val hbmType = if (Build.IS_ENG || Build.IS_USERDEBUG) {
|
||||
Settings.Secure.getIntForUser(
|
||||
context.contentResolver,
|
||||
SETTING_HBM_TYPE,
|
||||
DEFAULT_HBM_TYPE,
|
||||
UserHandle.USER_CURRENT
|
||||
)
|
||||
} else {
|
||||
DEFAULT_HBM_TYPE
|
||||
}
|
||||
|
||||
// Only used for UdfpsHbmTypes.GLOBAL_HBM.
|
||||
private var ghbmView: UdfpsSurfaceView? = null
|
||||
|
||||
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
|
||||
var animationViewController: UdfpsAnimationViewController<*>? = null
|
||||
|
||||
@@ -109,12 +85,6 @@ class UdfpsView(
|
||||
return (animationViewController == null || !animationViewController!!.shouldPauseAuth())
|
||||
}
|
||||
|
||||
override fun onFinishInflate() {
|
||||
if (hbmType == UdfpsHbmTypes.GLOBAL_HBM) {
|
||||
ghbmView = findViewById(R.id.hbm_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun dozeTimeTick() {
|
||||
animationViewController?.dozeTimeTick()
|
||||
}
|
||||
@@ -180,24 +150,11 @@ class UdfpsView(
|
||||
override fun startIllumination(onIlluminatedRunnable: Runnable?) {
|
||||
isIlluminationRequested = true
|
||||
animationViewController?.onIlluminationStarting()
|
||||
|
||||
val gView = ghbmView
|
||||
if (gView != null) {
|
||||
gView.setGhbmIlluminationListener(this::doIlluminate)
|
||||
gView.visibility = VISIBLE
|
||||
gView.startGhbmIllumination(onIlluminatedRunnable)
|
||||
} else {
|
||||
doIlluminate(null /* surface */, onIlluminatedRunnable)
|
||||
}
|
||||
doIlluminate(onIlluminatedRunnable)
|
||||
}
|
||||
|
||||
private fun doIlluminate(surface: Surface?, onIlluminatedRunnable: Runnable?) {
|
||||
if (ghbmView != null && surface == null) {
|
||||
Log.e(TAG, "doIlluminate | surface must be non-null for GHBM")
|
||||
}
|
||||
|
||||
hbmProvider?.enableHbm(hbmType, surface) {
|
||||
ghbmView?.drawIlluminationDot(sensorRect)
|
||||
private fun doIlluminate(onIlluminatedRunnable: Runnable?) {
|
||||
hbmProvider?.enableHbm() {
|
||||
if (onIlluminatedRunnable != null) {
|
||||
// No framework API can reliably tell when a frame reaches the panel. A timeout
|
||||
// is the safest solution.
|
||||
@@ -211,10 +168,6 @@ class UdfpsView(
|
||||
override fun stopIllumination() {
|
||||
isIlluminationRequested = false
|
||||
animationViewController?.onIlluminationStopped()
|
||||
ghbmView?.let { view ->
|
||||
view.setGhbmIlluminationListener(null)
|
||||
view.visibility = INVISIBLE
|
||||
}
|
||||
hbmProvider?.disableHbm(null /* onHbmDisabled */)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
import android.testing.ViewUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Surface
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
@@ -37,7 +36,6 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.nullable
|
||||
import org.mockito.Mockito.verify
|
||||
@@ -148,7 +146,7 @@ class UdfpsViewTest : SysuiTestCase() {
|
||||
view.startIllumination(onDone)
|
||||
|
||||
val illuminator = withArgCaptor<Runnable> {
|
||||
verify(hbmProvider).enableHbm(anyInt(), nullable(Surface::class.java), capture())
|
||||
verify(hbmProvider).enableHbm(capture())
|
||||
}
|
||||
|
||||
assertThat(view.isIlluminationRequested).isTrue()
|
||||
|
||||
@@ -2098,7 +2098,6 @@ public class DisplayModeDirector {
|
||||
|
||||
private class UdfpsObserver extends IUdfpsHbmListener.Stub {
|
||||
private final SparseBooleanArray mLocalHbmEnabled = new SparseBooleanArray();
|
||||
private final SparseBooleanArray mGlobalHbmEnabled = new SparseBooleanArray();
|
||||
|
||||
public void observe() {
|
||||
StatusBarManagerInternal statusBar =
|
||||
@@ -2109,39 +2108,27 @@ public class DisplayModeDirector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHbmEnabled(int hbmType, int displayId) {
|
||||
public void onHbmEnabled(int displayId) {
|
||||
synchronized (mLock) {
|
||||
updateHbmStateLocked(hbmType, displayId, true /*enabled*/);
|
||||
updateHbmStateLocked(displayId, true /*enabled*/);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHbmDisabled(int hbmType, int displayId) {
|
||||
public void onHbmDisabled(int displayId) {
|
||||
synchronized (mLock) {
|
||||
updateHbmStateLocked(hbmType, displayId, false /*enabled*/);
|
||||
updateHbmStateLocked(displayId, false /*enabled*/);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHbmStateLocked(int hbmType, int displayId, boolean enabled) {
|
||||
switch (hbmType) {
|
||||
case UdfpsObserver.LOCAL_HBM:
|
||||
mLocalHbmEnabled.put(displayId, enabled);
|
||||
break;
|
||||
case UdfpsObserver.GLOBAL_HBM:
|
||||
mGlobalHbmEnabled.put(displayId, enabled);
|
||||
break;
|
||||
default:
|
||||
Slog.w(TAG, "Unknown HBM type reported. Ignoring.");
|
||||
return;
|
||||
}
|
||||
private void updateHbmStateLocked(int displayId, boolean enabled) {
|
||||
mLocalHbmEnabled.put(displayId, enabled);
|
||||
updateVoteLocked(displayId);
|
||||
}
|
||||
|
||||
private void updateVoteLocked(int displayId) {
|
||||
final Vote vote;
|
||||
if (mGlobalHbmEnabled.get(displayId)) {
|
||||
vote = Vote.forRefreshRates(60f, 60f);
|
||||
} else if (mLocalHbmEnabled.get(displayId)) {
|
||||
if (mLocalHbmEnabled.get(displayId)) {
|
||||
Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
|
||||
float maxRefreshRate = 0f;
|
||||
for (Display.Mode mode : modes) {
|
||||
@@ -2165,13 +2152,6 @@ public class DisplayModeDirector {
|
||||
final String enabled = mLocalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
|
||||
pw.println(" Display " + displayId + ": " + enabled);
|
||||
}
|
||||
pw.println(" mGlobalHbmEnabled: ");
|
||||
for (int i = 0; i < mGlobalHbmEnabled.size(); i++) {
|
||||
final int displayId = mGlobalHbmEnabled.keyAt(i);
|
||||
final String enabled = mGlobalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
|
||||
pw.println(" Display " + displayId + ": " + enabled);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REF
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE;
|
||||
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE;
|
||||
|
||||
@@ -919,16 +919,6 @@ public class DisplayModeDirectorTest {
|
||||
// Should be no vote initially
|
||||
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
|
||||
assertNull(vote);
|
||||
|
||||
// Enabling GHBM votes for 60hz
|
||||
hbmListener.onHbmEnabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
|
||||
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
|
||||
assertVoteForRefreshRate(vote, 60.f);
|
||||
|
||||
// Disabling GHBM removes the vote
|
||||
hbmListener.onHbmDisabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
|
||||
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
|
||||
assertNull(vote);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user