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:
Yvonne Jiang
2020-02-03 17:55:19 -08:00
parent fb961bf0bd
commit 7f97f732d7
7 changed files with 42 additions and 44 deletions

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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();
}

View 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;

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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;
}
}
}