diff options
14 files changed, 140 insertions, 18 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ff072c268449..65793bee353f 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -19,6 +19,7 @@ package android.app.admin; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.Manifest.permission; +import android.accounts.Account; import android.annotation.CallbackExecutor; import android.annotation.ColorInt; import android.annotation.IntDef; @@ -165,6 +166,27 @@ public class DevicePolicyManager { this(context, service, false); } + /** + * Called when a managed profile has been provisioned. + * + * @throws SecurityException if the caller does not hold + * {@link android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS}. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) + public void finalizeWorkProfileProvisioning( + @NonNull UserHandle managedProfileUser, @Nullable Account migratedAccount) { + Objects.requireNonNull(managedProfileUser, "managedProfileUser can't be null"); + if (mService == null) { + throw new IllegalStateException("Could not find DevicePolicyManagerService"); + } + try { + mService.finalizeWorkProfileProvisioning(managedProfileUser, migratedAccount); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ @VisibleForTesting protected DevicePolicyManager(Context context, IDevicePolicyManager service, diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 701a362b9c31..e2e2a353e0c6 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -17,6 +17,7 @@ package android.app.admin; +import android.accounts.Account; import android.app.admin.NetworkEvent; import android.app.IApplicationThread; import android.app.IServiceConnection; @@ -97,6 +98,8 @@ interface IDevicePolicyManager { int getCurrentFailedPasswordAttempts(int userHandle, boolean parent); int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent); + void finalizeWorkProfileProvisioning(in UserHandle managedProfileUser, in Account migratedAccount); + void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, boolean parent); int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle, boolean parent); diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index e06e7b6be90a..d0a77a031c99 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -474,6 +474,7 @@ public final class Parcel { */ public final void recycle() { if (DEBUG_RECYCLE) mStack = null; + mClassCookies = null; freeBuffer(); if (mOwnsNativeParcelObject) { diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 9da50889e43f..46ee0f839fa9 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -306,7 +306,7 @@ interface IWindowSession { */ void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window, in IBinder hostInputToken, int flags, int privateFlags, int type, - out InputChannel outInputChannel); + in IBinder focusGrantToken, out InputChannel outInputChannel); /** * Update the flags on an input channel associated with a particular surface. diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index a6c5042db275..a312939e6522 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -231,7 +231,7 @@ public class SurfaceControlViewHost { public @Nullable SurfacePackage getSurfacePackage() { if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) { return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection, - mViewRoot.getInputToken()); + mWm.getFocusGrantToken()); } else { return null; } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index ffb7efa67243..d5cf1a360b0f 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -22,6 +22,7 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; +import android.os.Binder; import android.os.IBinder; import android.os.RemoteCallback; import android.os.RemoteException; @@ -75,6 +76,7 @@ public class WindowlessWindowManager implements IWindowSession { private final Configuration mConfiguration; private final IWindowSession mRealWm; private final IBinder mHostInputToken; + private final IBinder mFocusGrantToken = new Binder(); private int mForceHeight = -1; private int mForceWidth = -1; @@ -91,6 +93,10 @@ public class WindowlessWindowManager implements IWindowSession { mConfiguration.setTo(configuration); } + IBinder getFocusGrantToken() { + return mFocusGrantToken; + } + /** * Utility API. */ @@ -153,10 +159,10 @@ public class WindowlessWindowManager implements IWindowSession { mRealWm.grantInputChannel(displayId, new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"), window, mHostInputToken, attrs.flags, attrs.privateFlags, attrs.type, - outInputChannel); + mFocusGrantToken, outInputChannel); } else { mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags, - attrs.privateFlags, attrs.type, outInputChannel); + attrs.privateFlags, attrs.type, mFocusGrantToken, outInputChannel); } } catch (RemoteException e) { Log.e(TAG, "Failed to grant input to surface: ", e); @@ -464,7 +470,7 @@ public class WindowlessWindowManager implements IWindowSession { @Override public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window, - IBinder hostInputToken, int flags, int privateFlags, int type, + IBinder hostInputToken, int flags, int privateFlags, int type, IBinder focusGrantToken, InputChannel outInputChannel) { } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2ad836e54b3f..dd541f2cb3e0 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -100,6 +100,7 @@ <protected-broadcast android:name="android.intent.action.OVERLAY_PRIORITY_CHANGED" /> <protected-broadcast android:name="android.intent.action.MY_PACKAGE_SUSPENDED" /> <protected-broadcast android:name="android.intent.action.MY_PACKAGE_UNSUSPENDED" /> + <protected-broadcast android:name="android.app.action.MANAGED_PROFILE_PROVISIONED" /> <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" /> <protected-broadcast android:name="android.os.action.DEVICE_IDLE_MODE_CHANGED" /> diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index eddb5e977fa2..15a41f6b3d2c 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -2267,6 +2267,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub throw new IllegalArgumentException("padding must be positive: " + padding); } + int maxSize = getMaximumSizeDimension(displayId); + + final int paddingWidth = padding.left + padding.right; + final int paddingHeight = padding.top + padding.bottom; + if (paddingWidth > maxSize) { + throw new IllegalArgumentException("padding width " + paddingWidth + + " exceeds max width " + maxSize); + } + if (paddingHeight > maxSize) { + throw new IllegalArgumentException("padding height " + paddingHeight + + " exceeds max height " + maxSize); + } + final DisplayData wpdData = getDisplayDataOrCreate(displayId); if (!padding.equals(wpdData.mPadding)) { wpdData.mPadding.set(padding); diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index fc317a1212d5..a05769c0a48b 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -41,6 +41,8 @@ class EmbeddedWindowController { private static final String TAG = TAG_WITH_CLASS_NAME ? "EmbeddedWindowController" : TAG_WM; /* maps input token to an embedded window */ private ArrayMap<IBinder /*input token */, EmbeddedWindow> mWindows = new ArrayMap<>(); + private ArrayMap<IBinder /*focus grant token */, EmbeddedWindow> mWindowsByFocusToken = + new ArrayMap<>(); private final Object mGlobalLock; private final ActivityTaskManagerService mAtmService; @@ -59,10 +61,13 @@ class EmbeddedWindowController { void add(IBinder inputToken, EmbeddedWindow window) { try { mWindows.put(inputToken, window); + final IBinder focusToken = window.getFocusGrantToken(); + mWindowsByFocusToken.put(focusToken, window); updateProcessController(window); window.mClient.asBinder().linkToDeath(()-> { synchronized (mGlobalLock) { mWindows.remove(inputToken); + mWindowsByFocusToken.remove(focusToken); } }, 0); } catch (RemoteException e) { @@ -95,8 +100,10 @@ class EmbeddedWindowController { void remove(IWindow client) { for (int i = mWindows.size() - 1; i >= 0; i--) { - if (mWindows.valueAt(i).mClient.asBinder() == client.asBinder()) { + EmbeddedWindow ew = mWindows.valueAt(i); + if (ew.mClient.asBinder() == client.asBinder()) { mWindows.removeAt(i).onRemoved(); + mWindowsByFocusToken.remove(ew.getFocusGrantToken()); return; } } @@ -104,8 +111,10 @@ class EmbeddedWindowController { void onWindowRemoved(WindowState host) { for (int i = mWindows.size() - 1; i >= 0; i--) { - if (mWindows.valueAt(i).mHostWindowState == host) { + EmbeddedWindow ew = mWindows.valueAt(i); + if (ew.mHostWindowState == host) { mWindows.removeAt(i).onRemoved(); + mWindowsByFocusToken.remove(ew.getFocusGrantToken()); } } } @@ -114,6 +123,10 @@ class EmbeddedWindowController { return mWindows.get(inputToken); } + EmbeddedWindow getByFocusToken(IBinder focusGrantToken) { + return mWindowsByFocusToken.get(focusGrantToken); + } + void onActivityRemoved(ActivityRecord activityRecord) { for (int i = mWindows.size() - 1; i >= 0; i--) { final EmbeddedWindow window = mWindows.valueAt(i); @@ -139,6 +152,8 @@ class EmbeddedWindowController { InputChannel mInputChannel; final int mWindowType; + private IBinder mFocusGrantToken; + /** * @param session calling session to check ownership of the window * @param clientToken client token used to clean up the map if the embedding process dies @@ -153,7 +168,7 @@ class EmbeddedWindowController { */ EmbeddedWindow(Session session, WindowManagerService service, IWindow clientToken, WindowState hostWindowState, int ownerUid, int ownerPid, int windowType, - int displayId) { + int displayId, IBinder focusGrantToken) { mSession = session; mWmService = service; mClient = clientToken; @@ -164,6 +179,7 @@ class EmbeddedWindowController { mOwnerPid = ownerPid; mWindowType = windowType; mDisplayId = displayId; + mFocusGrantToken = focusGrantToken; } @Override @@ -216,5 +232,16 @@ class EmbeddedWindowController { public int getPid() { return mOwnerPid; } + + IBinder getFocusGrantToken() { + return mFocusGrantToken; + } + + IBinder getInputChannelToken() { + if (mInputChannel != null) { + return mInputChannel.getToken(); + } + return null; + } } } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index d8adc512b65a..deed514464da 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -807,7 +807,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { @Override public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window, IBinder hostInputToken, int flags, int privateFlags, int type, - InputChannel outInputChannel) { + IBinder focusGrantToken, InputChannel outInputChannel) { if (hostInputToken == null && !mCanAddInternalSystemWindow) { // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to // embedded windows without providing a host window input token @@ -823,7 +823,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { try { mService.grantInputChannel(this, mUid, mPid, displayId, surface, window, hostInputToken, flags, mCanAddInternalSystemWindow ? privateFlags : 0, - mCanAddInternalSystemWindow ? type : 0, outInputChannel); + mCanAddInternalSystemWindow ? type : 0, focusGrantToken, outInputChannel); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ec3d96150257..1820159d6458 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8378,7 +8378,8 @@ public class WindowManagerService extends IWindowManager.Stub */ void grantInputChannel(Session session, int callingUid, int callingPid, int displayId, SurfaceControl surface, IWindow window, IBinder hostInputToken, - int flags, int privateFlags, int type, InputChannel outInputChannel) { + int flags, int privateFlags, int type, IBinder focusGrantToken, + InputChannel outInputChannel) { final InputApplicationHandle applicationHandle; final String name; final InputChannel clientChannel; @@ -8386,7 +8387,7 @@ public class WindowManagerService extends IWindowManager.Stub EmbeddedWindowController.EmbeddedWindow win = new EmbeddedWindowController.EmbeddedWindow(session, this, window, mInputToWindowMap.get(hostInputToken), callingUid, callingPid, type, - displayId); + displayId, focusGrantToken); clientChannel = win.openInputChannel(); mEmbeddedWindowController.add(clientChannel.getToken(), win); applicationHandle = win.getApplicationHandle(); @@ -8606,10 +8607,10 @@ public class WindowManagerService extends IWindowManager.Stub } } - void grantEmbeddedWindowFocus(Session session, IBinder inputToken, boolean grantFocus) { + void grantEmbeddedWindowFocus(Session session, IBinder focusToken, boolean grantFocus) { synchronized (mGlobalLock) { final EmbeddedWindowController.EmbeddedWindow embeddedWindow = - mEmbeddedWindowController.get(inputToken); + mEmbeddedWindowController.getByFocusToken(focusToken); if (embeddedWindow == null) { Slog.e(TAG, "Embedded window not found"); return; @@ -8618,6 +8619,11 @@ public class WindowManagerService extends IWindowManager.Stub Slog.e(TAG, "Window not in session:" + session); return; } + IBinder inputToken = embeddedWindow.getInputChannelToken(); + if (inputToken == null) { + Slog.e(TAG, "Focus token found but input channel token not found"); + return; + } SurfaceControl.Transaction t = mTransactionFactory.get(); final int displayId = embeddedWindow.mDisplayId; if (grantFocus) { @@ -8647,7 +8653,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - void grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetInputToken, + void grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetFocusToken, boolean grantFocus) { synchronized (mGlobalLock) { final WindowState hostWindow = @@ -8661,7 +8667,7 @@ public class WindowManagerService extends IWindowManager.Stub return; } final EmbeddedWindowController.EmbeddedWindow embeddedWindow = - mEmbeddedWindowController.get(targetInputToken); + mEmbeddedWindowController.getByFocusToken(targetFocusToken); if (embeddedWindow == null) { Slog.e(TAG, "Embedded window not found"); return; @@ -8672,7 +8678,7 @@ public class WindowManagerService extends IWindowManager.Stub } SurfaceControl.Transaction t = mTransactionFactory.get(); if (grantFocus) { - t.requestFocusTransfer(targetInputToken, embeddedWindow.toString(), + t.requestFocusTransfer(embeddedWindow.getInputChannelToken(), embeddedWindow.toString(), hostWindow.mInputChannel.getToken(), hostWindow.getName(), hostWindow.getDisplayId()).apply(); @@ -8681,7 +8687,7 @@ public class WindowManagerService extends IWindowManager.Stub "reason=grantEmbeddedWindowFocus(true)"); } else { t.requestFocusTransfer(hostWindow.mInputChannel.getToken(), hostWindow.getName(), - targetInputToken, + embeddedWindow.getInputChannelToken(), embeddedWindow.toString(), hostWindow.getDisplayId()).apply(); EventLog.writeEvent(LOGTAG_INPUT_FOCUS, diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java index 55ab8c3b1af6..10ff2447948b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java @@ -15,6 +15,7 @@ */ package com.android.server.devicepolicy; +import android.accounts.Account; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.admin.DevicePolicySafetyChecker; @@ -58,6 +59,7 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { * @see {@link SystemService#onUserUnlocking} */ abstract void handleUnlockUser(int userId); + /** * To be called by {@link DevicePolicyManagerService#Lifecycle} after a user is being unlocked. * @@ -133,6 +135,11 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { return null; } + public void finalizeWorkProfileProvisioning( + UserHandle managedProfileUser, Account migratedAccount) { + + } + public void provisionFullyManagedDevice( FullyManagedDeviceProvisioningParams provisioningParams, String callerPackage) { } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 0fbcfd3a3ba1..5c2827ff831c 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -26,6 +26,7 @@ import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED; import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE; import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE; +import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER; @@ -56,6 +57,7 @@ import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS; import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT; import static android.app.admin.DevicePolicyManager.DELEGATION_SECURITY_LOGGING; import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER; +import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE; import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO; import static android.app.admin.DevicePolicyManager.ID_TYPE_IMEI; import static android.app.admin.DevicePolicyManager.ID_TYPE_INDIVIDUAL_ATTESTATION; @@ -10569,6 +10571,35 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override + public void finalizeWorkProfileProvisioning(UserHandle managedProfileUser, + Account migratedAccount) { + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + + if (!isManagedProfile(managedProfileUser.getIdentifier())) { + throw new IllegalStateException("Given user is not a managed profile"); + } + ComponentName profileOwnerComponent = + mOwners.getProfileOwnerComponent(managedProfileUser.getIdentifier()); + if (profileOwnerComponent == null) { + throw new IllegalStateException("There is no profile owner on the given profile"); + } + Intent primaryProfileSuccessIntent = new Intent(ACTION_MANAGED_PROFILE_PROVISIONED); + primaryProfileSuccessIntent.setPackage(profileOwnerComponent.getPackageName()); + primaryProfileSuccessIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES + | Intent.FLAG_RECEIVER_FOREGROUND); + primaryProfileSuccessIntent.putExtra(Intent.EXTRA_USER, managedProfileUser); + + if (migratedAccount != null) { + primaryProfileSuccessIntent.putExtra(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, + migratedAccount); + } + + mContext.sendBroadcastAsUser(primaryProfileSuccessIntent, + UserHandle.of(getProfileParentId(managedProfileUser.getIdentifier()))); + } + + @Override public UserHandle createAndManageUser(ComponentName admin, String name, ComponentName profileOwner, PersistableBundle adminExtras, int flags) { Objects.requireNonNull(admin, "admin is null"); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index e000265f0a2c..4cdeb0b07187 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1444,9 +1444,14 @@ public class TelecomManager { * when placing calls. The user may still need to enable the {@link PhoneAccount} within * the phone app settings before the account is usable. * <p> + * Note: Each package is limited to 10 {@link PhoneAccount} registrations. + * <p> * A {@link SecurityException} will be thrown if an app tries to register a * {@link PhoneAccountHandle} where the package name specified within * {@link PhoneAccountHandle#getComponentName()} does not match the package name of the app. + * <p> + * A {@link IllegalArgumentException} will be thrown if an app tries to register a + * {@link PhoneAccount} when the upper bound limit, 10, has already been reached. * * @param account The complete {@link PhoneAccount}. */ |