Update secondary lock screen implementation to use the newly updated SurfaceControlViewHost API.
Previously we passed back a SurfaceControl to the keyguard, updated to pass a SurfacePackage instead. The updated SurfaceControlViewHost logic addresses underlying accessibility bugs. Bug: 136085151 Test: atest AdminSecondaryLockScreenControllerTest Test: atest FrameworksServicesTests:DevicePolicyManagerTest Change-Id: I4881d5766f118b99f497ee306cd71d3c5a65a2f3
This commit is contained in:
@@ -6795,7 +6795,7 @@ package android.app.admin {
|
||||
ctor public DevicePolicyKeyguardService();
|
||||
method @Nullable public void dismiss();
|
||||
method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
|
||||
method @Nullable public android.view.SurfaceControl onSurfaceReady(@Nullable android.os.IBinder);
|
||||
method @Nullable public android.view.SurfaceControlViewHost.SurfacePackage onSurfaceReady(@Nullable android.os.IBinder);
|
||||
}
|
||||
|
||||
public class DevicePolicyManager {
|
||||
|
||||
@@ -22,7 +22,7 @@ import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControlViewHost;
|
||||
|
||||
/**
|
||||
* Client interface for providing the SystemUI with secondary lockscreen information.
|
||||
@@ -43,14 +43,14 @@ public class DevicePolicyKeyguardService extends Service {
|
||||
@Override
|
||||
public void onSurfaceReady(@Nullable IBinder hostInputToken, IKeyguardCallback callback) {
|
||||
mCallback = callback;
|
||||
SurfaceControl surfaceControl =
|
||||
SurfaceControlViewHost.SurfacePackage surfacePackage =
|
||||
DevicePolicyKeyguardService.this.onSurfaceReady(hostInputToken);
|
||||
|
||||
if (mCallback != null) {
|
||||
try {
|
||||
mCallback.onSurfaceControlCreated(surfaceControl);
|
||||
mCallback.onRemoteContentReady(surfacePackage);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to return created SurfaceControl", e);
|
||||
Log.e(TAG, "Failed to return created SurfacePackage", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,11 +65,11 @@ public class DevicePolicyKeyguardService extends Service {
|
||||
/**
|
||||
* Called by keyguard once the host surface for the secondary lockscreen is ready to display
|
||||
* remote content.
|
||||
* @return the {@link SurfaceControl} for the Surface the secondary lockscreen content is
|
||||
* attached to.
|
||||
* @return the {@link SurfaceControlViewHost.SurfacePackage} for the Surface the
|
||||
* secondary lockscreen content is attached to.
|
||||
*/
|
||||
@Nullable
|
||||
public SurfaceControl onSurfaceReady(@Nullable IBinder hostInputToken) {
|
||||
public SurfaceControlViewHost.SurfacePackage onSurfaceReady(@Nullable IBinder hostInputToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package android.app.admin;
|
||||
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControlViewHost;
|
||||
|
||||
/**
|
||||
* Internal IPC interface for informing the keyguard of events on the secondary lockscreen.
|
||||
* @hide
|
||||
*/
|
||||
interface IKeyguardCallback {
|
||||
oneway void onSurfaceControlCreated(in SurfaceControl remoteSurfaceControl);
|
||||
oneway void onRemoteContentReady(in SurfaceControlViewHost.SurfacePackage surfacePackage);
|
||||
oneway void onDismiss();
|
||||
}
|
||||
|
||||
19
core/java/android/view/SurfaceControlViewHost.aidl
Normal file
19
core/java/android/view/SurfaceControlViewHost.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2020, 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 android.view;
|
||||
|
||||
parcelable SurfaceControlViewHost.SurfacePackage;
|
||||
@@ -27,7 +27,7 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControlViewHost;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.ViewGroup;
|
||||
@@ -47,7 +47,6 @@ public class AdminSecondaryLockScreenController {
|
||||
private Handler mHandler;
|
||||
private IKeyguardClient mClient;
|
||||
private KeyguardSecurityCallback mKeyguardCallback;
|
||||
private SurfaceControl.Transaction mTransaction;
|
||||
|
||||
private final ServiceConnection mConnection = new ServiceConnection() {
|
||||
@Override
|
||||
@@ -84,13 +83,13 @@ public class AdminSecondaryLockScreenController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceControlCreated(@Nullable SurfaceControl remoteSurfaceControl) {
|
||||
public void onRemoteContentReady(
|
||||
@Nullable SurfaceControlViewHost.SurfacePackage surfacePackage) {
|
||||
if (mHandler != null) {
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
if (remoteSurfaceControl != null) {
|
||||
mTransaction.reparent(remoteSurfaceControl, mView.getSurfaceControl())
|
||||
.apply();
|
||||
if (surfacePackage != null) {
|
||||
mView.setChildSurfacePackage(surfacePackage);
|
||||
} else {
|
||||
dismiss(KeyguardUpdateMonitor.getCurrentUser());
|
||||
}
|
||||
@@ -138,11 +137,10 @@ public class AdminSecondaryLockScreenController {
|
||||
|
||||
public AdminSecondaryLockScreenController(Context context, ViewGroup parent,
|
||||
KeyguardUpdateMonitor updateMonitor, KeyguardSecurityCallback callback,
|
||||
Handler handler, SurfaceControl.Transaction transaction) {
|
||||
Handler handler) {
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
mParent = parent;
|
||||
mTransaction = transaction;
|
||||
mUpdateMonitor = updateMonitor;
|
||||
mKeyguardCallback = callback;
|
||||
mView = new AdminSecurityView(mContext, mSurfaceHolderCallback);
|
||||
|
||||
@@ -39,7 +39,6 @@ import android.util.Slog;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
@@ -149,8 +148,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
mViewConfiguration = ViewConfiguration.get(context);
|
||||
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
|
||||
mSecondaryLockScreenController = new AdminSecondaryLockScreenController(context, this,
|
||||
mUpdateMonitor, mCallback, new Handler(Looper.myLooper()),
|
||||
new SurfaceControl.Transaction());
|
||||
mUpdateMonitor, mCallback, new Handler(Looper.myLooper()));
|
||||
}
|
||||
|
||||
public void setSecurityCallback(SecurityCallback callback) {
|
||||
|
||||
@@ -39,7 +39,7 @@ import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.testing.ViewUtils;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControlViewHost;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -54,7 +54,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
|
||||
@RunWithLooper
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@@ -77,8 +76,8 @@ public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
|
||||
private KeyguardSecurityCallback mKeyguardCallback;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mUpdateMonitor;
|
||||
@Spy
|
||||
private StubTransaction mTransaction;
|
||||
@Mock
|
||||
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -97,21 +96,20 @@ public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
|
||||
when(mKeyguardClient.asBinder()).thenReturn(mKeyguardClient);
|
||||
|
||||
mTestController = new AdminSecondaryLockScreenController(
|
||||
mContext, mParent, mUpdateMonitor, mKeyguardCallback, mHandler, mTransaction);
|
||||
mContext, mParent, mUpdateMonitor, mKeyguardCallback, mHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShow() throws Exception {
|
||||
doAnswer(invocation -> {
|
||||
IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
|
||||
callback.onSurfaceControlCreated(new SurfaceControl());
|
||||
callback.onRemoteContentReady(mSurfacePackage);
|
||||
return null;
|
||||
}).when(mKeyguardClient).onSurfaceReady(any(), any(IKeyguardCallback.class));
|
||||
|
||||
mTestController.show(mServiceIntent);
|
||||
|
||||
verifySurfaceReady();
|
||||
verify(mTransaction).reparent(any(), any());
|
||||
assertThat(mContext.isBound(mComponentName)).isTrue();
|
||||
}
|
||||
|
||||
@@ -133,7 +131,7 @@ public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
|
||||
// Show the view first, then hide.
|
||||
doAnswer(invocation -> {
|
||||
IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
|
||||
callback.onSurfaceControlCreated(new SurfaceControl());
|
||||
callback.onRemoteContentReady(mSurfacePackage);
|
||||
return null;
|
||||
}).when(mKeyguardClient).onSurfaceReady(any(), any(IKeyguardCallback.class));
|
||||
|
||||
@@ -189,19 +187,4 @@ public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
|
||||
verify(mKeyguardCallback).dismiss(true, TARGET_USER_ID);
|
||||
assertThat(mContext.isBound(mComponentName)).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stubbed {@link SurfaceControl.Transaction} class that can be used when unit testing to
|
||||
* avoid calls to native code.
|
||||
*/
|
||||
private class StubTransaction extends SurfaceControl.Transaction {
|
||||
@Override
|
||||
public void apply() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceControl.Transaction reparent(SurfaceControl sc, SurfaceControl newParent) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user